Files
LWLT-AIBOT/archive/project-history/2026-08-12/findings.full.md
T

300 KiB
Raw Blame History

LTJT Business Module API Findings

2026-08-10 — LianSyn-platform 正式化与持久登录 findings

  • 当前正式操作台和外部解析器源码已迁移到 LianSyn-platform/,控制平面静态目录与 parser import 均使用正式路径。
  • 生产入口曾包含旧平台启动脚本、根 README、控制平面 server、前端存储键和来源常量;这些已统一为平台正式命名。
  • 当前数据库会话已有 expires_at、idle_expires_at、撤销时间和哈希 Token;登录 Cookie 也已有持久化属性,但仍受 12 小时绝对 TTL / 120 分钟空闲 TTL 限制。
  • 持久登录需让服务端查询不再因 expires_at 或 idle_expires_at 自动失效,并让 Cookie 跨浏览器重启保留;退出、改密、停用账号和管理员撤销仍必须撤销会话。

Implementation result

  • 运行目录已迁移为 LianSyn-platform/;控制平面静态 root、解析器 import、Docker、npm scripts、测试路径、插件桥接来源和操作台缓存键均已同步。
  • 008_persistent_sessions.sql 会先撤销迁移前已经过期的活动会话,再将剩余活动会话的两个过期字段清空;AuthService 不再生成、检查或滑动更新自动过期时间。
  • 登录 Cookie 使用 HttpOnly、生产环境 Secure、SameSite=Lax 和长生命周期;退出登录、改密、账号停用与管理员强制改密仍由服务端撤销。
  • 最终验证通过:类型检查、构建、控制平面 27/27、解析/业务回归 58/58、脚本语法、旧引用扫描和 git diff --check。

Initial Authenticated State

  • Site: https://ltjt.yunzhi.run/
  • Logged-in page: https://ltjt.yunzhi.run/System/Mainlt.asp
  • Title: 老挝联泰_LW5.1.3
  • Main iframe: https://ltjt.yunzhi.run/System/homelt.asp, iframe name MainIframe, id Iframe_Home
  • Visible account label observed: 测试ai员工账号
  • Authorized target scope stated by user: "业务操作" module only.

Business Module Menu Items Observed

  • 产品管理
  • 独立团计划表
  • 散拼团计划表
  • 团队安排
  • 酒店用房表
  • 航班控位表
  • 团队备案表
  • 退货管理
  • 我的付款单
  • 我的收款单
  • 我的费用报销单
  • 我的发票申请
  • 我发放的签单
  • 我的客户欠款
  • 客服回访

Endpoint Inventory

Business Page URLs From Main Menu

  • GET /System/Business/Product.asp - 产品管理
  • GET /System/Business/orders.asp - 独立团计划表
  • GET /System/Business/plan.asp - 散拼团计划表
  • GET /System/Business/teams.asp - 团队安排
  • GET /System/Business/Hotels.asp - 酒店用房表
  • GET /System/Business/tickets.asp - 航班控位表
  • GET /System/Business/teams_beians.asp - 团队备案表
  • GET /System/Business/teams_return.asp - 退货管理
  • GET /System/Business/Cash_fu.asp - 我的付款单
  • GET /System/Business/Cash_shou.asp - 我的收款单
  • GET /System/Business/Cash_zhi.asp - 我的费用报销单
  • GET /System/Business/Invoice.asp - 我的发票申请
  • GET /System/Business/Bill_out.asp - 我发放的签单
  • GET /System/Business/Arrears.asp - 我的客户欠款
  • GET /System/Business/kefu.asp - 客服回访

Product Management Page

  • Menu click creates/uses iframe id jidiao40, iframe name MainIframe, title 产品管理, src /System/Business/Product.asp.
  • Initial page request: GET /System/Business/Product.asp.
  • List XHR: POST /System/dat/product.asp.
  • Observed list request body:
    • Act=PrintGridList
    • Tpage=1
    • P_Size=50
    • S_fabudanwei=老挝联泰
    • S_chanpinming=
    • S_tianshu=
    • S_kehu=
    • S_caozuoren=
    • S_zhuanxianming=
    • S_zhuangtai=
  • Autocomplete/field metadata XHR: POST /System/dat/AjaxPublicFun.asp?Act=ProGetTableZD&tb=Product&zd=chanpinming&s_fabudanwei=老挝联泰.
  • Product page loads JS: /JavaScript/PubFun.js, /JavaScript/onmouseover.js, /JavaScript/SelectBox/SelectBox.min.js.
  • Product iframe visible text confirms list columns include: 行程编码, 业务名称, 产品名称/行程天数, 所属客户, 接待说明, 航班信息, 用房数, 结算价格, 更新人, 操作.

Business Page URLs With Observed Query Parameters

  • /System/Business/orders.asp?S_zhuangtai=预订&wode=0 - 待确认订单数
  • /System/Business/teams.asp?S_chufariqi=2026-7-7&S_chufarizhi=2026-7-7&wode=0 - 今日出发团队
  • /System/Business/orders.asp?S_chufariqi=2026-7-8&S_chufarizhi=2026-7-8&wode=0 - 明日出发团队
  • /System/Business/orders.asp?riqi=xiadanri&S_chufariqi=2026-7-7&S_chufarizhi=2026-7-7&wode=0 - 今日新增团队
  • /System/Business/cash_shou.asp?zt=待认领 - 收款单提交
  • /System/Business/teams.asp?S_zhuangtai=今日回程团 - 今日回程团
  • /System/Business/teams_return.asp - 退货管理

Independent Group Down-Order Flow

  • On /System/Business/orders.asp, the 下单 button calls OPEN_update(0,0,0).
  • The button opens GET /system/Business/orders_add.asp?fabudanwei=<分公司>&copy=0&ddid=0&_=<timestamp> in a dialog iframe.
  • The add/edit page title is 计划下单/修改.
  • The save action is POST /System/DAT/orders.asp with payload Act=DoInfoJH& plus ListForm.serialize().
  • The save response is JavaScript (dataType: "script"), not JSON.
  • SubmitInfoForm() checks that passenger count is not zero, then calls Vidy.CheckMastInput("ListForm"), then sends the Ajax POST.
  • The add form is large: about 825 input/select/textarea controls were present, due to repeated itinerary, fee, flight, hotel/restaurant/attraction, upload, and hidden metadata rows.
  • Required primary fields observed include chufa_ri, zhuanxianming, TianShu, zutuanshe, chanpinming, gendanren, tuanxuhao1, tuanxuhao2, passenger-count fields, and xiaoshouren.
  • The add page loads several lookup endpoints under /system/dat/AjaxPublicFun.asp, including product, travel/customer, staff, flight/control, fee item, and partner-resource lookups.

Static Assets Seen On Main Pages

  • /JavaScript/jquery-1.4.2.min.js and /JavaScript/jquery-1.8.3.min.js
  • /JavaScript/VidySail.js
  • /JavaScript/lhgdialog/lhgdialog.min.js?skin=blue&self=true
  • /JavaScript/highcharts/js/highcharts.js

See archived api_inventory.md for the structured endpoint inventory.

Auth and Session Notes

  • App is classic ASP on Microsoft IIS.
  • Login uses an ASPSESSIONID... cookie plus multiple custom session cookies.
  • Cookie values were intentionally not recorded; cookie names/attributes only.
  • ASPSESSIONIDAUTTQAQD was observed as secure=true, httpOnly=false, session cookie.
  • Multiple custom cookies are not HttpOnly and appear to be session-scoped.
  • A main-page reload during capture redirected back to /system/loginlt.html; avoid destructive reloads during capture and prefer in-frame navigation after re-login.
  • Real menu clicks do not replace the home iframe. They create additional module iframes such as jidiao40 for 产品管理 and add a tab in #Main_TopMenu.
  • Direct unauthenticated requests to /System/Mainlt.asp, /System/homelt.asp, and representative /System/Business/*.asp pages all returned a 129-byte HTML/script response that alerts "未登录或登录超时" and redirects to /system/loginlt.html.
  • Login page posts Action=CheckSystemLogin, UserName, UserPwd, Code, set_lang, and a client-generated session_id to POST /system/dat/AjaxCommand.asp; response is executed as JavaScript (dataType: "script").
  • CAPTCHA image endpoint: GET /Inc/GetCode.asp?<random>.
  • Direct GET/HEAD /system/dat/AjaxCommand.asp without login/action returns an empty 200 response and sets a fresh ASP session cookie.
  • Page-context sensitivity: direct fetch probes to /System/dat/*.asp from the top page and from an existing module iframe returned the 86-byte JavaScript response alert('登陆失效,请重新登陆!') after the session became unstable, while natural menu-triggered page loads had successfully called the same dat endpoints. Treat these endpoints as requiring a fresh valid browser session and possibly the same referer/frame/window state as the originating ASP page.

Integration Risks

  • There may not be a formal JSON API; the integration may require browser-equivalent ASP form/query calls and HTML parsing unless hidden AJAX endpoints are found.
  • Session cookies are browser/session based. A stable server-to-server integration would need either an official API, a dedicated integration account, or a controlled login/session renewal strategy approved by the system owner.
  • We need to inspect individual business pages before concluding whether list/detail operations return HTML, script, JSON, or downloadable files.
  • The public VidySail.js asset appears to be general validation/utility code rather than an API client; it does not expose a centralized business API wrapper.
  • Simulated login is likely undesirable for production unless the system owner provides an integration account and an approved CAPTCHA/session process.
  • Successful page loads prove the browser can call the list endpoints, but direct fetch probes after session expiry returned a JavaScript login-timeout response. The adapter must detect this response and renew the session.
  • The adapter design needs a page-context strategy: either replay requests with exact cookies/referer/origin from a freshly opened module page, or run the request inside a controlled browser context that first opens the relevant ASP page.
  • For write operations such as independent-group down-order, the adapter should initially run in dry-run/read-only discovery mode. Actual Act=DoInfoJH submission requires explicit approval and either a sandbox/test order or a rollback policy.
  • Down-order integration should likely start with a browser-context serializer: open orders_add.asp, fill/select required fields, run the page's own lookup/calculation code, inspect ListForm.serialize(), and only later enable actual submission.

Adapter Mapping Findings

  • First local mapping artifact: mappings/orders_add.mapping.json.
  • First local dry-run serializer: tools/dry_run_order_create.mjs.
  • Browser-context comparison helper: tools/browser_order_add_dry_run.mjs. It is designed to fill and serialize the live form only; it does not click submit or call DoInfoJH.
  • The standard operation contract now requires route, trip, and order_number for team_order_create, because LTJT requires zhuanxianming, TianShu, tuanxuhao1, and tuanxuhao2.
  • Local dry-run can build a full Act=DoInfoJH&... payload shape from captured form fields, but it is still a draft until compared against a live browser ListForm.serialize() after LTJT lookup selections.
  • Lookup-sensitive fields remain the main submit blocker for production: customer (zutuansheid, currency/contact metadata), route/order prefix, product pricing metadata (baojia and product-loaded fields), OP, and salesperson.
  • Passenger-list operations remain out of scope for the first mapping. The current mapping only supports passenger_list.operation = none.
  • Previous live browser comparison blocker was resolved by reopening the collaboration Chrome on 127.0.0.1:9223 and logging in again.
  • After fresh login, browser-context dry-run passed against live orders_add.asp: local and browser serialized field sets both contained 822 fields, with zero mapped-field mismatches.
  • Live form discovery found yaobeian=要备案 is serialized by default. The standard operation now has data.system_defaults.filing_required, mapped to LTJT yaobeian.
  • The browser dry-run is still not a production submit path: it verifies form field compatibility and serialization only. The next production-grade step is deterministic lookup resolution for customer, route, product, OP, and salesperson hidden metadata.

SelectBox / Lookup Findings

  • The user's warning is correct: many visible text fields are LTJT SelectBox widgets, not free text fields.
  • The SelectBox data protocol is ◇ for rows and ◆ for columns, confirmed from the live /JavaScript/SelectBox/SelectBox.min.js.
  • Critical create-order fields must be selected from existing LTJT choices:
    • TianShu: static options, 10 rows, maps to itself.
    • zhuanxianming: lookup endpoint returned 16 rows x 11 columns; selection sets zhuanxianming and tuanxuhao1.
    • chanpinming: lookup endpoint returned 160 rows x 2 columns; selection sets chanpinming and should then trigger GetProduct(cpm) side effects.
    • zutuanshe: lookup endpoint returned 93 rows x 6 columns; selection sets bizhong, zutuansheid, zutuanshe, lianxiren, and zutuanshegzr.
    • staff lookup returned 33 rows x 2 columns; used by gendanren and xiaoshouren.
  • Resource fields are also SelectBox-backed: hotels, restaurants, attractions, flights, receivable items, and reserved resource/detail fields each have their own lookup-backed ranges and linked fields.
  • A serializer-only dry run can prove field names and payload shape, but it must not be treated as production-ready. Production readiness requires lookup validation: every SelectBox-bound standard value must match exactly one LTJT row, and the adapter must apply the page's linked SetVal fields.
  • Fake sample data is now correctly blocked by tools/validate_order_add_lookups.mjs: only the static 4D3N option matched; fake route/product/customer/OP/sales values had zero exact matches.
  • tools/resolve_order_add_lookups.mjs now turns exact-matched SelectBox rows into linked field patches using SetVal. It redacts resolved values in its normal report and refuses to write --resolved-out when any critical lookup is blocked.
  • tools/dry_run_order_create.mjs --lookup-resolution now blocks payload generation unless lookup resolution has passed, so serializer-only success cannot accidentally be treated as submit readiness.

Product Side-Effect / Browser Preflight Findings

  • Product selection has a second required layer beyond the chanpinming SelectBox match. The page function Find_product() calls ../dat/AjaxPublicFun.asp?Act=GetProduct&cpm=<product> with dataType:"script", and the returned script mutates the current ListForm.
  • tools/inspect_order_add_product_effect.mjs was added to run this behavior without submitting. It can exact-match a product from a standard operation, or use --sample-first-existing-product for a redacted non-submit inspection. It stores only field names, counts, byte lengths, and redacted metadata.
  • Redacted sample inspection of the first existing product observed one successful GetProduct script response and 135 changed form fields: 9 itinerary text fields, 7 core fields, 21 pricing/receivable fields, 96 resource fields, and 2 other fields. No DoInfoJH submit was attempted.
  • Product side effects can overwrite fields that were previously treated as direct or lookup fields, including TianShu, zhuanxianming, tuanxuhao1, tuanxuhao2, zutuanshe, zutuansheid, xiaoshouren, ys_* receivable rows, itinerary text, meals/hotels/attractions, and related resource metadata.
  • Production filling order should therefore be product-template first, then consistency validation, then controlled overwrite of fields owned by the upstream business system. If the product template's trip, route, customer id, or route prefix does not match the standard operation and lookup resolution, the adapter should block instead of masking the mismatch by overwriting visible text fields.
  • tools/browser_order_add_preflight.mjs now combines lookup exact-match checks, product Find_product() execution, product-template consistency checks, controlled post-product field setting, receivable-row clearing/rewrite from standard prices, and final live ListForm.serialize() without submitting.
  • The fake sample is correctly blocked by browser preflight before product side effects: static trip matched once, while fake route/product/customer/OP/sales values matched zero LTJT options. The report is redacted by default and does not write serialized values.
  • tools/browser_order_add_submit_intercept.mjs now tests the page's own SubmitInfoForm() branch by monkey-patching jQuery.ajax before the function runs. When the fake-filled form is used, the page attempts one Act=DoInfoJH request, but the request is intercepted and never reaches the network. The report stores field names, field count, byte length, and a payload hash only.
  • tools/browser_order_add_template_selftest.mjs now proves the non-writing pipeline can pass using a real existing LTJT product template while keeping all option values in browser memory only. The redacted self-test selected an existing product, exact-matched product/trip/route/customer/staff once each, observed 135 product-side-effect field changes, filled obvious test markers (AI-DRYRUN-NO-SUBMIT) into the current draft, serialized 822 fields, and captured one prevented DoInfoJH submit branch.
  • tools/browser_order_add_submit_approved.mjs is the guarded live-submit tool. It refuses before connecting to the browser unless it has: a browser_preflight_passed report, a separate submit_intercept_captured report, matching payload SHA-256 values, --execute-live-submit, and the exact approval token APPROVE-LTJT-DOINFOJH-SUBMIT.
  • The live-submit refusal path was verified using the template self-test report as an invalid stand-in. It refused before browser access and reported blockers for missing execute flag, wrong report statuses, and missing intercepted payload hash.
  • SubmitInfoForm() can mutate the payload between a plain ListForm.serialize() snapshot and the actual DoInfoJH request. The approved submit path now treats the submit-intercept payload hash as authoritative and re-checks the actual AJAX request hash immediately before network send.
  • A controlled live test submit was completed with obvious test markers (AI-DRYRUN-NO-SUBMIT) and a hash-matched approved payload. The submit response was classified as successful: one POST /System/DAT/orders.asp, dataType:"script", HTTP/AJAX success, no login-timeout text, no permission text, and a success hint in the redacted response.
  • tools/verify_order_marker.mjs verifies the submitted test order through the independent-order list endpoint without storing business row values. Searching JH_OrderList for departure date 2026-8-1 and marker AI-DRYRUN-NO-SUBMIT found the marker in the response, proving the submitted test order is visible in LTJT.

Raw Instruction Simulation Findings

  • samples/raw_instruction_team_order_20260811.json records the user's raw-order instruction as a structured test operation with the explicit ERP test marker RAWTEST-ERP-20260811.
  • tools/browser_order_add_raw_instruction_test.mjs was added for the test-stage workflow where upstream business-system fields are not yet pre-split. It accepts the parsed raw instruction, opens a fresh orders_add.asp form, selects the product from existing LTJT options, runs Find_product(), and derives linked route, trip, customer, customer id, currency, and route-prefix fields from the product template in browser memory.
  • The raw-instruction test validates choice-backed fields before submit. For the 遇见老挝 order dated 2026-08-11, product, post-template product, trip, route, customer, and salesperson each resolved to exactly one LTJT option. The OP value 测试 was not an exact staff option, but it resolved by deterministic unique_contains to exactly one existing staff option; ambiguous or zero-match cases block submit.
  • The same test generated three receivable rows from the raw counts/prices: adult, child-with-bed, and child-no-bed. Passenger total was 4, room total was 2, and computed receivable total was 1380.
  • Product template side effects changed 126 form fields for this product: 10 itinerary text fields, 7 core fields, 21 pricing/receivable fields, 86 resource fields, and 2 other fields. The adapter then cleared/rebuilt receivable rows while preserving product-template itinerary/resource fields.
  • The submit branch was first intercepted with no network write. The intercepted DoInfoJH payload had 822 serialized fields and hash 5c56f91d7552797c4cddc8c99d1a206a6c3a83125c5c19dea817c15b8358c2f3.
  • The approved live submit succeeded for the same hash: one POST /System/DAT/orders.asp, dataType:"script", no login-timeout text, no permission text, success hint present, and no error hint. A dialog alert was emitted by the ERP response and was redacted in the report.
  • tools/verify_order_marker.mjs confirmed the saved raw-instruction ERP test order by searching JH_OrderList for departure date 2026-8-11 and marker RAWTEST-ERP-20260811; the response contained the marker and did not look empty or unauthorized.

Chrome Extension Prototype Findings

  • A local MV3 Chrome extension prototype now lives at chrome-extension/ltjt-order-assistant. It can be installed with Chrome's Load unpacked flow.
  • The extension popup parses raw Chinese order instructions or accepts the structured JSON operation format, then locks the newest orders_add.asp iframe opened from the logged-in LTJT ERP page.
  • inpage.js runs in Chrome's MAIN world so it can call the ERP page's own Find_product(), intercept jQuery.ajax, and invoke SubmitInfoForm() without coordinate-based RPA.
  • Version 0.1.0 preserves the current safety boundary: live submit is blocked unless the operation is a test order with a non-empty data.test_marker, a passed preflight, a captured submit payload hash, and explicit checkbox confirmation.
  • The packaged local zip is chrome-extension/ltjt-order-assistant.zip; for local use, the unpacked folder remains the preferred install target.
  • The LianSyn-platform page now lives at LianSyn-platform. It has a single raw-instruction text box, creates one structured ERP order task, and sends it to the extension through window.postMessage plus the extension content script business-bridge.js.
  • The parsing-agent prompt is stored with the platform adapter under LianSyn-platform/. It defines the LTJT field meanings, required output schema, passenger/room/price mappings, and explicitly tells the agent not to guess ERP linked IDs or product-template side-effect fields.
  • LianSyn-platform/server.mjs serves the platform adapter and exposes the parser transport; the formal control plane owns login, task persistence, and operator confirmation.
  • The extension now writes task feedback back into chrome.storage.local under the business task id after preflight, live submit, verification, or extension errors. The LianSyn-platform page polls the bridge for those results and displays the latest status.

LianSyn-platform / Agent Findings

  • The LianSyn-platform page represents the upstream business system with one large raw-instruction text area. The configured parser decomposes that text into the standard team_order_create operation.
  • The model-agent path is intentionally OpenAI-compatible rather than provider-specific. The browser page stores endpoint/model locally and keeps the API key in session storage; server.mjs proxies the request to avoid browser CORS issues.
  • MiniMax testing showed that endpoint selection matters: the global-looking api.minimax.io endpoint returned HTTP 401 for the supplied key, while the China endpoint api.minimaxi.com returned HTTP 200 with the same OpenAI-compatible request shape.
  • The production parsing prompt lives with LianSyn-platform/. Its job is business-text decomposition and LTJT field understanding only. It must not invent linked ERP IDs, hidden fields, product template effects, or SelectBox choices; those remain deterministic browser/ERP validations.
  • Task cards are now the operator-facing surface. The task card is created before plugin/ERP execution, so business users can track waiting, paused, running, blocked, and completed states without opening the extension popup.

Extension / Bridge Findings

  • The extension is no longer treated as a standalone data-entry app for normal users. It is a browser-session adapter controlled by the business system and only exposes a small popup for connection state plus the ERP-operation enable switch.
  • The content-script bridge uses window.postMessage between the local business page and business-bridge.js, then chrome.runtime.sendMessage / chrome.storage.local inside the extension. This is page automation, not coordinate-based RPA.
  • The bridge can report two separate concepts that should not be collapsed:
    • Business-system/plugin bridge connected.
    • ERP automation enabled.
  • When ERP automation is disabled, the business system should show the plugin as connected but mark new executable tasks as paused rather than trying to run ERP and then showing a confusing failure.
  • The extension reload lifecycle is a real operational risk. After reloading an unpacked extension, old content scripts in already-open pages can throw Extension context invalidated. Version 0.2.12 adds reinjection tolerance, but the safest manual test procedure remains: reload extension, refresh business-system page, then open the popup.
  • Current direct page bridge scope is one browser profile. It can work across multiple windows/tabs in the same Chrome profile, but it cannot see pages in another Chrome profile, Edge, Safari, Firefox, or another machine.
  • Multi-browser production support should use a local bridge hub or backend task queue: business system submits tasks to the hub/queue, browser plugins register as workers, and task status returns through the same channel.

Task Deletion and Cancellation Findings (2026-07-12)

  • The business page currently exposes top-level 查询反馈 and 清空任务 controls; their listeners call pollResult() and clearTasks() and must be removed together with the controls.
  • The right task panel currently has only #taskState and #taskDetail; deletion should target currentTaskId and remove that one task from local storage.
  • The bridge has CLEAR_TASKS but no single-task delete/cancel message. A new bridge message must call the background service worker before removing the corresponding local task data.
  • background.js stores active IDs in an in-memory runningTasks set. Execution awaits tab loads, frame discovery, preflight, submit, verification, and batch children without cancellation checks. Cancellation can safely stop future phases at boundaries; a network/browser action already in flight cannot be rolled back by a UI delete.
  • The implemented cancellation flag is checked before/after browser script actions and in tab/frame wait loops. setResult() suppresses late writes for cancelled task IDs so bridge cleanup is not undone by a finishing promise.
  • A delete request is fail-closed for confirmed tasks when the bridge cannot acknowledge cancellation: the local card remains so the operator does not mistake an un-cancelled ERP task for a deleted one. Unconfirmed tasks have no plugin task and can be deleted locally.
  • A live ERP network submit that was already in flight when cancellation arrived cannot be rolled back by the browser extension; the UI removes the task only after the cancellation request is acknowledged.

AI Workbench Header Findings (2026-07-12)

  • The supplied logo is a 1254×1254 square PNG with large white margins around a horizontal wordmark. The header uses object-fit: cover in a horizontal frame so the wordmark remains legible without rewriting the source asset.
  • The local server did not previously map .png; it now serves the logo as image/png.
  • AI connection state had no safe probe endpoint. The business server now exposes GET /api/status, returning whether DEERFLOW_OPEN_API_KEY is configured without exposing the key. Plugin state continues to use the existing bridge PING.
  • The final header uses a stretched horizontal menu with AI操作台 as the active item; AI/plugin status tags sit at the far right and intentionally collapse their display to green 已开启 or red 未连接. Clicking either tag refreshes only its corresponding probe.
  • The first AI status implementation only checked Boolean(DEERFLOW_OPEN_API_KEY), so it was not a connectivity check. /api/status now calls ExternalAgentParser.checkConnection(), which sends an authenticated empty validation request to the external session endpoint without creating a session. The browser uses ai_connected and refreshes it on load, every five seconds, and on click.
  • Runtime diagnosis after the status remained red: the process listening on 127.0.0.1:8765 was an older node server.mjs instance. Its static page reflected the latest frontend, but its in-memory HTTP routes did not include GET /api/status and returned 404; the frontend correctly treated that as disconnected. The service must be restarted after server-side route changes.
  • The stale process was gone when the requested restart was performed, so the service was started fresh on port 8765. The route is now live, but no server-side Key is available in the current environment; restart with a private .env/environment variable to make the AI probe turn green.

Three-stage Project Status UI Findings (2026-07-12)

  • The task store already contains the required signals: parser states such as running with stage=parse, agent_parse_passed, and parse_failed; handoff/executor states such as accepted, queued, running, blocked, and completed; and receipt data from result.erp_receipt, result.report.erp_receipt, alerts, or parsed ERP messages.
  • The new stage surface can remain presentation-only: it derives state from the selected task and does not alter task lifecycle or plugin messages.
  • The desktop browser check shows three compact cards fit above the terminal log in the right panel. Empty tasks render neutral pending cards; a parser failure turns the Agent card red while later stages remain pending; completed tasks with erp_receipt can turn the business and receipt cards green.

Confirmation Action Relocation Findings (2026-07-12)

  • The existing manual confirmation action was generated inside each task card and delegated through data-task-action="confirm".
  • It is now a single selected-task action in the right detail header. The action is hidden unless requiresManualConfirmation(selectedTask()) is true, preventing duplicate confirmation controls and keeping the left card focused on type, ID, and status.

Input Area Copy Findings (2026-07-12)

  • The left panel's functionality is already wired to #rawInstruction and #createTaskButton, so the requested label changes are presentation-only and do not alter parsing or task creation behavior.

Current MVP Definition

  • MVP success is no longer "the assistant can fill one ERP form once." That has been proven with guarded live test orders.
  • The current MVP is: a business-system task is created from raw or structured input; the plugin automatically performs the LTJT ERP operation in the logged-in browser session; the business system shows task progress and final result; the operator can disable ERP actions from the plugin.
  • The main remaining MVP risk is connection/session reliability around extension reloads, browser/profile boundaries, and ERP login/session expiry. These should be tested deliberately before adding more business scenarios.

External Agent Parsing Refactor — Confirmed 2026-07-12

  • The requested change is limited to raw business-input parsing and returning the existing standard operation JSON to the business system. ERP/plugin execution is unchanged and out of scope.
  • Each input task gets an independent Open Agent Session. A retry of the same task should reuse its session and idempotency keys; separate tasks must not share context.
  • The business-system server will call POST /api/open/agent-sessions, then POST /api/open/agent-sessions/{session_id}/messages/stream, collect SSE events, and return the existing normalized parse result to the browser UI.
  • The external Agent Profile's published prompt is the sole prompt source. The local prompt file/editor and browser model configuration are removed.
  • DEERFLOW_BASE_URL and DEERFLOW_OPEN_API_KEY are server environment variables. The supplied secret is not written to source, examples, reports, browser storage, or logs.
  • The local adapter endpoint is renamed to /api/parse; all /api/agent/* routes and local Agent terminology are removed.
  • The external API does not receive profile_id; the supplied Open API token's external-app policy resolves the published Profile.
  • Real smoke verification with the private key confirmed Bearer authentication, CSRF double-submit compatibility, session creation, and SSE delivery. No ERP endpoint was called.
  • The real stream emits metadata, values, repeated messages, and end; assistant content is delivered as AIMessageChunk objects in messages arrays, not as message.delta events.
  • The currently resolved published Profile returned a generic JSON shape (reply, intent, missingFields, nextStep, profileSuggestion, keyInfoSuggestions, citations, riskFlags) during synthetic parser calls. The local adapter intentionally blocks this as external_result_contract_mismatch; the external Profile must be configured/published to return the agreed standard operation contract.

2026-07-12 — Authorized full ERP/plugin live test

  • The user explicitly authorized creating temporary ERP orders and manually deleting them afterward. The external Agent was not changed; this pass covers only the root business system, the Chrome plugin, and the logged-in ERP browser session.
  • Existing create routes were revalidated: team-single task CDP-PLUGIN-TEST-20260712 completed with group LLW-260811CDP-PLUGIN-TEST-20260712-1783842347475-A; the sequential team-batch fallback completed for 2026-09-01 and 2026-09-08 with groups LLW-260901BATCHT0712-D20260901-1783843465676-A and LLW-260908BATCHT0712-D20260908-1783843475645-A.
  • The new guarded live split-parent adapter completed task CDP-PLUGIN-SPLIT-PARENT-LIVE-20260712-R2, creating LW-260916PLUGSP0712R2-A with planned capacity 4. The split-child adapter completed task CDP-PLUGIN-SPLIT-CHILD-LIVE-20260712-R3, adding child order D14271 with pax 2+1+1; the parent row requery confirmed the child and received count.
  • Direct and plugin export checks confirmed all three source responses: Xingyou customer confirmation, Liantai customer confirmation, and JOB order. The final plugin task CDP-PLUGIN-EXPORT-LIVE-20260712-R3 used the correct independent-order ddid/tid pair (14266/14170), received HTTP 200 Word-like responses, and reported no_erp_write=true, never_resave=true; no local download or delivery was claimed.
  • Order-update and traveler-import routes are intentionally still dry-run/read-only. The ERP update POST returned HTTP 200 with an empty response and no persistence in both independent and split-child checks. The native traveler import dialog filled synthetic rows but exposed a phone-field mapping offset; no save was clicked. These routes remain fail-closed until the ERP contract is corrected and reverified.
  • Final local gate: extension version 0.2.14 is loaded and PING reports ERP automation enabled; JavaScript syntax checks pass; tools/operation-plans.test.mjs passes 12/12; the standard schema validates; and the packaged ZIP passes unzip -t.

Manual cleanup candidates

  • Confirmed current-pass test groups/orders: LLW-260811CDP-PLUGIN-TEST-20260712-1783842347475-A; LLW-260901BATCHT0712-D20260901-1783843465676-A; LLW-260908BATCHT0712-D20260908-1783843475645-A; LW-260915SPT0712-A with parent record D14268 and child D14269; LW-260916PLUGSP0712R2-A with parent record D14270 and child D14271.
  • Earlier controlled live-submit markers also created test records: AI-DRYRUN-NO-SUBMIT (departure 2026-08-01) and RAWTEST-ERP-20260811 (departure 2026-08-11).
  • The earlier CDP-BATCH-TEST-20260712 attempt produced an ownership-uncertain record around LLW-260812A-A; verify it manually before deleting. No automatic deletion or retry was performed.
  • 2026-07-12 UI review: the external parser request was already wired through /api/parse, but the browser setOutput() function intentionally discarded technical responses and the detail pane rendered only the task ID. The pane now exposes safe request-stage diagnostics and formatted response JSON, so users can distinguish request initiation, session creation, SSE completion, contract blocking, and local failures.

Project Development Standard Findings — 2026-07-12

  • The project has two distinct ownership layers: Skill/operation design expresses business meaning, while ERP control scripts perform deterministic product-template effects, SelectBox lookup, form mapping, preflight, and post-operation verification.
  • The actual team-order raw-instruction test accepts product/date/passenger/room/price/OP/sales facts and derives route, trip, customer, currency, and route prefix from Find_product/GetProduct; this must be reflected in maintenance documentation and task-ready contract rules.
  • The next input protocol should require an exact first non-empty line such as 新增订单 or 修改订单, map it directly to one standard action, and block unknown/missing first-line commands before Skill invocation.
  • The handoff package remains a comparison and compatibility source. Current root schemas, mappings, scripts, Skill references, and tests are the maintenance authority for the active external-Agent architecture.

2026-07-12 — Productionization discovery

  • The platform adapter exposes /api/status and /api/parse; durable task state is owned by the control plane, while extension task state and results use chrome.storage.local as an execution cache.
  • No formal application database, identity/tenant model, durable task queue, outbox/idempotency layer, plugin registry/version policy, or server-side audit/event store was found in the current project manifests and source.
  • The existing system_operation_scope.md and handoff package already define a useful boundary: the upstream business system/database owns business meaning and standard operation data, while the LTJT adapter deterministically validates and executes against the legacy ERP.
  • The highest-order architecture decision is therefore the system-of-record boundary: retain LTJT as the initial external operational source of truth and build a production control plane around it, or make the new platform the primary ERP and migrate/replace LTJT capabilities. This must be confirmed before designing the durable schema and plugin runtime.

2026-07-12 — Repository cleanup audit findings

Current structure

  • The active root implementation is small and coherent enough to preserve in place: agent设计规范/, schemas/, mappings/, tools/, chrome-extension/, LianSyn-platform/, and samples/ form the current Agent-to-operation-to-ERP-adapter chain.
  • 开发维护规范.md is the current maintenance rule, but there is no root README that explains the entrypoint, source-of-truth order, test gates, or archive policy.
  • task_plan.md, progress.md, and findings.md are valuable chronological logs, not runtime documentation. They contain superseded statements from earlier architecture stages and should not remain the only project orientation material.

Legacy handoff boundary

  • 交接包/ is not imported or executed by current root code. It is a legacy handoff snapshot with useful business rules, route discoveries, fixtures, and safety ideas.
  • The handoff's executable contract (erp-task-v1), eight separate Skills, runner scripts, and deployment instructions are not the current cloud Agent output contract. They should be retained as read-only compatibility reference, not edited as if they were active source.
  • The handoff contains missing-path references and generated runtime/output folders. A future archive must separate reusable documentation/code from runtime residue instead of moving the entire directory as one undifferentiated source package.

Risky or disposable material

  • 交接包/runtime/, 交接包/diagnostics/, 交接包/tools/runtime/, and root reports/ contain temporary health files, browser/runtime state, audit records, test markers, and exported document artifacts. They should be quarantined and redacted/retained only according to evidence policy.
  • Root .DS_Store files are disposable. The root has no .gitignore, so future browser/runtime artifacts can reappear in the project unless ignore rules are added.
  • The packaged extension ZIP is a release artifact, not source. Skill packages should likewise be rebuilt into a clearly named distribution directory when needed; the current root does not contain a committed portable .skill artifact.

Every retained file should have exactly one status: active-source, active-contract, active-doc, fixture, historical-reference, validation-evidence, release-artifact, runtime-residue, or secret-sensitive/quarantine. No file in the last four categories should be used as a maintenance source of truth.

2026-07-12 — Cleanup dependency decision

  • Current root source does not import the legacy handoff directory. References to the handoff occur in documentation, compatibility wording, and historical logs only.
  • Current root source does not read any existing report file at startup or during the normal task loop. Report paths are CLI output destinations, so removing existing report files does not break the active flow.
  • The legacy handoff's runtime/, diagnostics/, and tools/runtime/ areas contain generated state and output rather than reusable source. They are deletion candidates under the user's confirmed cleanup rule.
  • The extension ZIP is retained by relocation to dist/, because it is a deliverable artifact rather than historical evidence.
  • Planning files remain in place as active session memory. Their old entries are history and are not allowed to override the current root README, maintenance standard, Agent/Skill contract, schema, mapping, or ERP control code.

2026-07-12 — Cleanup completed findings

  • The project now has a clear active root and a dated legacy archive. Current maintainers should not search the archive for the latest business rule.
  • The old handoff package retained 153 source/document/fixture files after deleting runtime and generated output areas; its package remains useful for comparison but is not part of the active execution path.
  • The current root has 22 fewer validation artifacts and no .DS_Store residue. The report directory is intentionally empty except for its output-policy README.
  • The extension release ZIP is now separated from extension source under dist/.
  • Remaining governance work is non-blocking: introduce a periodic stale-artifact check and decide later whether the long planning logs should move into docs/history/ after planning-file tooling no longer depends on root paths.
  • User confirmed the first phase will retain LTJT as the external operational source of truth and focus only on architecture-level hardening. New business functions, new ERP routes, and workflow changes are explicitly out of scope for this pass.
  • User confirmed the first deployment is single-company, single-tenant, and private. Organization isolation fields may be reserved for future expansion, but full multi-tenant SaaS behavior is not part of this hardening pass.
  • User confirmed a centralized server plus browser-plugin Worker topology: the backend persists and dispatches tasks, while Chrome performs the existing LTJT session-bound operation and reports state. Browser/local extension storage is not authoritative.
  • User confirmed PostgreSQL as the authoritative application database. Redis may be used only for ephemeral concerns such as cache, locks, or transport acceleration; it must not replace durable task or audit state.
  • User chose not to integrate enterprise SSO in phase one and explicitly added native platform account login to the hardening scope. Account provisioning, recovery, and role policy remain open decisions.
  • User confirmed administrator-created/invited accounts with public registration disabled; the first administrator is bootstrapped during deployment.
  • User confirmed that only administrators will use the platform initially; one administrator role with full permissions is sufficient for phase one. Granular human RBAC is out of scope, while plugin Worker identity remains a separate runtime concern.
  • User confirmed server-side administrator sessions with secure HttpOnly/SameSite cookies rather than long-lived browser-stored JWTs. Session rotation, expiry, revocation, CSRF protection, and auditability are part of the hardening scope.
  • User explicitly declined MFA for phase one. The design must compensate with password, rate-limit/lockout, session, audit, and controlled recovery protections without adding an MFA flow.
  • User confirmed password recovery should use a controlled server-side reset path only; email self-service recovery is out of scope for the private first phase.
  • User confirmed the extension does not need independent registration, pairing, or Worker credentials in phase one. It runs only within the administrator's already-authenticated browser/ERP session.
  • User confirmed the existing execution safety chain must remain: preflight/dry-run, explicit administrator confirmation, single submit, and ERP re-query; uncertain outcomes must block automatic retry or duplicate creation.
  • User confirmed production PostgreSQL starts clean; prototype local storage, extension cache, reports, and test orders are not migrated. Only schema, configuration structure, and standard-operation contracts carry forward.
  • User explicitly chose direct production deployment without a separate development/staging environment. Release safety must therefore rely on offline/static gates, no-write defaults, explicit confirmation, migration prechecks, and recoverable database backups.
  • User confirmed automated PostgreSQL backups, a pre-migration backup, independent backup storage, and restore verification as mandatory production safeguards.
  • User confirmed a minimal private-deployment observability baseline: structured redacted logs, health checks, and alerts for service/database/backup/task/plugin/ERP reconciliation failures, without adding a third-party monitoring platform.
  • User confirmed production secrets use protected deployment-host injection only and must not appear in source control, images, logs, database records, frontend code, or extension storage; rotation is server-side controlled.

2026-07-12 — Consolidated implementation recommendation

  • The recommended implementation keeps the active Agent/Skill/schema/mapping/ERP chain intact and adds a TypeScript Node/Fastify control plane with PostgreSQL, explicit SQL migrations, Zod validation, Pino logs, server-side sessions, and a DB-backed task queue/lease model.
  • REST commands plus SSE/polling replace browser-local task authority; the current business-system page remains the operator surface with only the required login/persistence wiring added.
  • Redis, SSO, MFA, public registration, separate staging deployment, independent plugin credentials, new business routes, and new business screens are intentionally excluded.
  • Production data protection defaults to encrypted/field-redacted sensitive snapshots, redacted audit logs, configurable retention, independent backups, and restore verification.

2026-07-12 — Architecture hardening implementation findings

  • Added control-plane/ with a Fastify/TypeScript server, PostgreSQL migration runner, native administrator authentication, encrypted task snapshots, durable task state, idempotency, leases, events, audit, outbox, SSE, and health endpoints.
  • The existing business page now hides the workbench until administrator authentication succeeds, reads task cards from /api/tasks, creates tasks through the durable API, confirms/cancels through server transitions, and persists plugin results back to PostgreSQL. Its task array is an in-memory render cache; raw draft input is session-only.
  • The root package uses a nested CommonJS package marker inside the extension so the existing UMD operation-plan tests remain compatible with the new root ESM/TypeScript package.
  • No local PostgreSQL or Docker runtime is available in this workspace. Migration execution, administrator bootstrap against a real database, backup creation, restore verification, and Compose startup remain target-environment gates rather than silently simulated results.
  • The local npm run db:migrate smoke correctly fails closed with a redacted connection error (ECONNREFUSED 127.0.0.1:5432) when PostgreSQL is absent; it does not mark the database as migrated.

2026-07-13 — Login gate visual fix

  • The login panel was rendered together with the workbench because .workbench-grid { display: grid; } overrode the browser's default [hidden] rule.
  • Added an explicit global [hidden] { display: none !important; } rule and bumped the stylesheet cache version. The login state now hides the workbench instead of layering it behind the login card.

2026-07-13 — Automatic environment loading findings

  • The UI uses relative fetches for /api/auth/login, /api/auth/me, and /api/status; it must be opened from the 8786 control-plane origin, not the legacy 8765 parser-only server.
  • control-plane/src/config.ts reads process.env but did not load a project .env itself. The 8786 process inherited no external Agent variables, so its status correctly reported external_service_not_configured even though the 8765 service had the private key.
  • The local private env file contains parser-oriented variables including a PORT value for 8765; it cannot be reused as the root control-plane env without overriding the control-plane port and origin.
  • The safe project boundary is a root ignored .env with local control-plane defaults and the private external Agent values, plus --env-file=.env on all root control-plane scripts. .env.example and .env.production.example remain placeholder templates.

2026-07-13 — Automatic environment loading result

  • The project now has one local control-plane startup command: npm run dev; it loads the root .env automatically and listens on 8786 with the correct APP_ORIGIN.
  • The parser-only service remains separate at 8765 and uses LianSyn-platform/.env; it is not a login endpoint.
  • After restart, the control-plane external Agent probe authenticated successfully and the database readiness probe remained healthy.
  • Root .env is local-only and ignored. The production replacement point is .env.production/Docker Compose secret injection, not source code or frontend storage.

2026-07-13 — Parse stall diagnosis and local hardening

  • The stuck task TASK-20260713032610-K5AWZxc remained parse_running with no persisted parse_response or operation; the control-plane process had an established HTTPS connection to the Agent while the task stream did not complete.
  • The local Agent client could wait through three separate 120-second phases, exceeding the five-minute task lease. It also waited for the HTTP body to close even after terminal SSE events and did not explicitly handle data: [DONE].
  • The parse worker could reclaim the same expired task while its original in-process worker was still active; late results were not tied to the lease owner and could overwrite a newer attempt.
  • /api/status previously used a state-changing session-creation POST as a health probe. It now uses the provider's read-only GET /health endpoint, caches the result for 30 seconds, and the browser refreshes status every 30 seconds.
  • Local fixes now enforce a 180-second total parse budget, honor terminal SSE events, exclude active task IDs from local claims, persist the running message, and reject stale parse results by lease owner. The cancelled diagnostic task was not automatically retried.

2026-07-13 — Delete task visibility diagnosis

  • The delete button's request path was wired: deleteSelectedTask() appends a cancellation log, calls POST /api/tasks/:taskId/cancel, and removes the task from the in-memory card list.
  • The control-plane cancellation endpoint intentionally keeps the durable row and marks it cancelled for audit; however, listTasks() returned cancelled rows in its default response.
  • The cancellation event triggers the page's SSE syncRemoteTasks() refresh. That refresh repopulated the just-removed cancelled task, making a successful delete look like a no-op.
  • The fix preserves cancelled rows in the database and only hides them from the default active-task list; explicit status queries can still request cancelled history.

2026-07-13 — Parse Worker root cause and end-to-end resolution

  • The repeated five-minute reclaims were not a database lock or a missing Agent response. A real Agent request completed in about 50 seconds, but the control plane attempted to insert an empty string into task_events.actor_user_id, a PostgreSQL UUID column. SQLSTATE 22P02 rolled the entire result transaction back, leaving the task in parse_running until its lease expired.
  • System-generated task events now persist a null actor. A regression test directly verifies this UUID boundary.
  • Parse claims now create durable task_attempts; the Worker has an independent watchdog and propagated abort signal; hanging SSE cancellation is bounded; expired leases are converted to a durable parse_failed terminal state and are never automatically resubmitted to Agent.
  • Parser outcomes are retried only for database persistence, not by calling Agent again. Lease-owner checks reject late results and the queue is single-flight within the process.
  • Initial SSE history replay no longer causes a /api/tasks request storm: the browser starts from the highest known event ID, the server honors Last-Event-ID, and concurrent refreshes are coalesced.
  • Terminal tasks clear leases, cancelled tasks close any running attempts, and migrations 002_parse_reliability and 003_terminal_lease_cleanup reconcile existing rows.
  • /api/status now distinguishes reachability from authentication and uses a successful real parse as non-mutating authentication evidence.

2026-07-13 — Real Agent and backend completion evidence

  • Real task TASK-20260713043752-_GgRRXg created one external Agent session, consumed a terminal SSE stream with 2695 events, returned agent_parse_passed, and produced the expected test operation for product 遇见老挝, departure 2026-08-11, passenger/room/price counts, OP, and sales fields.
  • The successful task used exactly one parse attempt. Its attempt changed from running to completed, response and request hashes were stored, the lease was cleared, and task state changed to awaiting_confirmation.
  • An isolated no-ERP-write verification then exercised the authenticated backend transitions confirmed -> queued -> completed; the encrypted result records no_erp_write=true, with complete task-event and audit chains.
  • Final runtime status reports database_ready=true, ai_reachable=true, ai_authenticated=true, and ai_connected=true. PostgreSQL has no active or expired parse tasks, no running attempts, no terminal leases, no duplicate attempt keys, and no waiting locks.

2026-07-13 — ERP duplicate execution incident findings

  • The incident was local, not an Agent-return failure. Audit and task events showed the same task was browser-claimed four times at approximately 10:38, 10:40, 10:40, and 10:42 UTC while ERP execution was already active.
  • Three defects combined: the server allowed claim from confirmed, queued, and running; the page sent CREATE_TASK to the extension before recording the server claim; and bridge-ready/heartbeat/page-refresh logic automatically resubmitted every confirmed task whose handoff status was no longer exactly accepted.
  • Result collection stopped after the first running update because polling selected only handoff_status === 'accepted', while the backend changed the handoff status to running. This explains why ERP could finish while PostgreSQL and the UI remained at an earlier stage.
  • The old extension used only an in-memory runningTasks set. A content-script replay or extension service-worker restart could lose that guard and execute the same task again.
  • The corrected invariant is at-most-once dispatch: server transaction creates one ERP attempt and execution ID before delivery; the page sends only when claimed=true; the extension persists that execution ID atomically with the accepted task; and the database has a partial unique index allowing one phase='erp' attempt per task.
  • Exactly-once ERP side effects cannot be inferred after a transport crash. The plugin therefore persists write_started before a real write; any failure, cancellation, restart, or unknown response after that point becomes reconciliation_pending and cannot be retried automatically.
  • Terminal results are monotonic and immutable. Replayed identical updates create no event, completed/reconciliation/blocked tasks reject later running updates, and execution-result ownership is checked against both browser connection and execution ID.
  • Task TASK-20260713103736-9tLJa4w has no trustworthy captured ERP receipt because the old page stopped polling. It is intentionally marked duplicate_execution_detected and must be reconciled in ERP by group/order number or test marker rather than guessed as completed.
  • The native ERP deferred dialog callback had an old opener runtime error. The callback is now suppressed because explicit verification and return-to-list own that lifecycle; extension 0.3.1 currently reports zero manifest/runtime errors.
  • A shell-expanded SQL $1 placeholder caused the first incident-isolation command to fail before any mutation; the corrected command succeeded. A later syntax-check command used a duplicated relative path, but the proper node --check and the full regression gate passed.

2026-08-05 — Task-scoped session continuation baseline

  • LianSyn-platform/external-agent-client.mjs creates /api/open/agent-sessions, reads session_id, and sends one SSE message, while the control plane owns task-scoped session persistence.
  • control-plane persists task snapshots and parse responses but has no first-class external-session table, message-turn table, conversation_id, or user-input continuation route.
  • Existing Skill output has only agent_parse_passed and terminal agent_parse_blocked; missing fields are currently represented as blockers. The complete operation schema is action-specific and must remain strict.
  • The implementation must add a separate parse-result wrapper contract rather than weakening schemas/standard_system_operation.schema.json.

2026-08-05 — Task-scoped session continuation implementation findings

  • The control plane can claim a queued user turn from agent_session_messages; the worker receives the decrypted current turn, prior sent/replayed turns, the encrypted external session ID, and the persisted recovery count.
  • Public task responses expose only session_id_present, turn, recovery count, conversation ID, and the sanitized input request. Raw external session IDs are removed recursively from transport metadata before UI/API output.
  • A task with agent_parse_needs_input becomes awaiting_user_input and never enters confirmation, ERP claim, or plugin execution. A follow-up message changes only that same task back to parse_queued.
  • Message matching is intentionally conservative: explicit task_id is authoritative; a conversation can auto-match only one waiting task; multiple matches return task_selection_required; no conversation never auto-matches.
  • Lease expiry now fails the in-flight user turn and its Agent session together, while retaining only a boolean session-presence marker in the terminal parse response.

2026-08-05 — Manual Agent-to-ERP handoff boundary

  • The current backend already separates awaiting_confirmation from ERP execution: parsing ends at awaiting_confirmation; /api/tasks/:taskId/confirm changes the task to confirmed; /api/tasks/:taskId/claim creates the single ERP execution record; the extension then runs its internal automation.
  • The current operator button calls confirmation and handoff in one user action. The requested behavior is therefore one explicit 确认并提交到 ERP 插件 action after Agent output, not two separate confirmation buttons.
  • The plugin's existing automation switch remains an internal execution control. It must not be replaced by a second Agent-result confirmation gate.

2026-08-05 — Login session persistence diagnosis and fix

  • PostgreSQL contained active sessions with future absolute and idle expiry timestamps, so the server-side session rows were durable.
  • The login route already used an HttpOnly cookie with Max-Age; the fix now also sends Expires derived from the same absolute TTL for broader browser/webview compatibility.
  • /api/auth/me, /api/auth/csrf, login, and logout now send Cache-Control: no-store so a cached 401 cannot make a valid session look logged out after refresh.
  • The page previously called showLoginPanel() immediately on DOM load before the asynchronous session probe. It now shows a temporary disabled recovery state and only displays the login form after /api/auth/me or CSRF restoration fails.
  • The static operator page is served by the 8786 control plane. The 8765 server.mjs process is parser-only; using it as the page origin cannot preserve or validate control-plane login sessions.
  • Runtime verification after restart: /health/live 200, database ready, AI connected, auth/me no-store headers present, and the served HTML uses the auth-persistence cache-buster.

2026-08-05 — Login refresh false-logout root cause

  • The initial Cookie-only diagnosis was incomplete. Live request logs showed the browser did send a valid session: /api/auth/me and /api/auth/csrf both returned HTTP 200 during refresh.
  • The next /api/tasks request returned HTTP 500 with PostgreSQL SQLSTATE 42P01: relation agent_sessions did not exist. initializeSession() wrapped task sync in the same catch as authentication and converted that 500 into showLoginPanel('请登录后继续。').
  • The configured database had migrations 001–004 but not 005_agent_task_sessions. The migration runner applied 005_agent_task_sessions; direct task listing now succeeds.
  • initializeSession() now authenticates first, then synchronizes tasks in a separate guarded block. A task/database error no longer clears authUser or displays the login form.
  • A temporary session smoke test was revoked after verification; it proved /api/auth/me 200, no-store auth headers, and /api/tasks 200 after the migration.

2026-08-05 — Status diagnostics baseline

  • /api/status already separates ai_reachable and ai_authenticated, but computes ai_connected as database ready plus reachability plus historical authentication success. A rotated key therefore remains visually disconnected until a later successful parse supersedes the old 401 record.
  • The external read-only /health probe can establish service reachability but cannot validate the API key. Authentication evidence must remain visible as a separate diagnostic field rather than silently treated as transport connectivity.
  • AI and plugin indicators are already buttons, but their click handlers only rerun probes. No details surface exists.
  • Plugin bridge responses already provide connection, extension version, compatibility, and ERP automation state; these can support green, yellow-warning, and red states without changing the extension protocol.
  • The live operator page now reports AI 已连接 before login because /api/status is public and read-only; authentication history remains visible inside the details dialog.
  • In the in-app browser without the LTJT extension, the plugin dialog correctly reports a bridge timeout, unknown version, disabled automation, the minimum compatible version, and the latest check time.

2026-08-05 — Reply panel and blank-operation root cause

  • The large yellow block is entirely frontend markup/state around the existing /api/messages endpoint; removing it does not require deleting backend continuation support.
  • requiresManualConfirmation() currently treats any truthy task.operation as confirmable unless failed/completed. It does not explicitly reject awaiting_user_input.
  • applyParseResult() correctly derives operation = null for agent_parse_needs_input, but then persists operationSummary(operation), and operationSummary(null) returns a truthy object with empty fields.
  • Existing waiting rows need a public-response compatibility guard because changing future persistence does not rewrite historical blank summary objects.
  • Keeping input_request in the public task JSON satisfies observability without keeping an operator interaction surface; future channel integrations can still call /api/messages.
  • After restart, the current waiting task is safely non-executable even though its historical database JSON summary remains blank: public wrapping returns operation: null, and the UI confirmation guard only accepts successful parse states.

2026-08-05 — Confirmed production team-order input rules

  • All order requests are production/formal orders. The Agent/Skill must set order_nature to formal and must not ask whether an order is a test or formal order or generate a test marker.
  • A date range and an explicit departure-date list are different facts and must not overwrite each other. When only month/day is supplied, use the current date as the anchor and choose the nearest corresponding date; do not ask the user for a year.
  • Team-order pricing is not user-owned input. Product or business selection synchronizes price and other linked fields; omit prices from the user-required set and do not ask for adult/child/infant/leader unit prices or leader fare treatment.
  • OP and salesperson come from the logged-in account defaults; do not ask the user for either field.
  • Passenger counts are a required object, but individual child/infant/leader keys are optional. Preserve the notation semantics: bare 15+1 follows the existing adult-plus-leader convention; 15+1占+1 means 15 adults + 1 child with bed + 1 leader; 15+1不占+1 means 15 adults + 1 child without bed + 1 leader.
  • Room counts are a required object, but only the first four room types are in scope: SGL, TWN, TRP, and DBL. Missing individual types are valid. Aliases include 标 → TWN, 一单 → SGL, 三人间 → TRP, and 双卧大床房 → DBL; 8标 parses as TWN: 8, and 8标一单 parses as TWN: 8, SGL: 1.
  • The active implementation is agent设计规范/agent-prompt.md plus agent设计规范/skills/lwlt-newbooking/; the old ltjt-business-operation path is already staged for removal and must not be restored.

2026-08-05 — Four-domain Skill routing redesign baseline

  • The active Agent Prompt currently says users do not need a fixed first line, which conflicts with the new requirement and must be replaced by a strict first-line router protocol.
  • The maintenance standard already reserves an action-to-Skill registry and a planned first-line command protocol, but the current registry still assigns all seven actions to lwlt-newbooking.
  • Confirmed domain ownership: newbooking owns team_order_create, team_order_batch_create, and shared_plan_create; updating will own independent-team and shared-plan modifications; arrangement will own guide, vehicle, hotel, and major-transport arrangements; confirmation will own customer confirmation exports and related export behaviors.
  • The first line is a human-facing business behavior name, not an internal Skill token. Internal Skill names (newbooking, updating, arrangement, confirmation) must stay inside the Agent/Skill routing layer.
  • The canonical behavior names supplied by the user are: 独立团批量下单, 独立团单个下单, 散拼团新增计划, 独立团信息修改, 散拼团信息修改, 安排导游, 安排用车, 安排酒店, 安排大交通, and 导出客户确认单.
  • The router should normalize only harmless surrounding whitespace/BOM, then match the first non-empty line against the registered behavior names. Unknown or missing behavior names block before any business Skill is invoked.

2026-08-05 — Business-behavior hint protocol relaxed

  • User clarified that the first line is a collaboration convention for faster routing, not a rigid command grammar.
  • The Agent should prefer the first line but inspect the full input and task context, tolerate spacing mistakes, minor typos, common abbreviations, and ordinary wording, and route when the overall intent is clear.
  • Missing or non-standard first-line wording is not itself a blocker. Ask or block only when the business type cannot be determined or multiple business goals conflict.

2026-08-05 — Cloud prompt boundary clarified

  • User clarified that the cloud Agent should not be told about internal Skill names or the maintainer registry; it only needs the operational business-processing guidance.
  • Removed internal routing details from agent设计规范/agent-prompt.md. The prompt now refers only to the appropriate business capability and leaves internal mapping to the platform configuration.

2026-08-05 — Four-domain Skill routing redesign implemented

  • Added agent设计规范/business-behavior-registry.md as the authoritative business-behavior reference. It keeps concrete behavior names separate from the internal Skill names.
  • Replaced the old single-Skill Agent Prompt route with first-line-preferred routing to lwlt-newbooking, lwlt-updating, lwlt-arrangement, or lwlt-confirmation; the body and context can correct an imperfect or missing line.
  • Active Skill metadata now consists of exactly four directories: lwlt-newbooking, lwlt-updating, lwlt-arrangement, and lwlt-confirmation.
  • lwlt-newbooking owns only 独立团批量下单/team_order_batch_create, 独立团单个下单/team_order_create, and 散拼团新增计划/shared_plan_create; it carries the production-only date, sparse passenger/room, auto-synced price/staff, and room-alias rules.
  • lwlt-confirmation owns 导出客户确认单/confirmation_export and preserves export-only/no-resave boundaries. lwlt-updating and lwlt-arrangement are registered scaffolds that return stable not-implemented blockers until their contracts are added.

2026-08-05 — Internal Skill identifier prefix

  • Renamed the four active Skill directories to lwlt-newbooking, lwlt-updating, lwlt-arrangement, and lwlt-confirmation.
  • Updated frontmatter names, display names, invocation tokens, internal blocker identifiers, reference headings, registry mappings, README links, and maintenance-document paths.
  • Kept business behavior names and the cloud-facing Agent Prompt free of internal Skill identifiers.

2026-08-05 — Skill/ERP plugin alignment audit

  • The active Skill output is production-only (order_nature=formal, submit_mode=dry_run, no test_marker), while operation-plans.js, inpage.js, and the extension README still treated team and split creates as test-only. Without a runtime change, the new Skill output would be blocked or downgraded to a planned-only result before it could reach the ERP form.
  • The plugin planner still required data.op_user.name, data.sales_user.name, and manual category prices. The active Skill intentionally omits those user inputs because LTJT supplies login-default staff and product selection/GetProduct supplies linked pricing and other fields.
  • The team preflight selected OP and sales only from explicit operation values, required a test marker, and cleared/rebuilt all product-generated receivable rows from data.prices. This contradicts the production Skill and can overwrite ERP product-template pricing.
  • Formal team execution also verified only a visible test marker. The extension has a durable execution ID, write-started state, approved payload hash, ERP response receipt, and date-aware browser re-query, so production verification can use the ERP group-number receipt instead of inventing a marker.
  • The split-parent adapter currently rejects date lists/ranges and uses a test suffix fallback. The ERP page itself exposes date-range fields and date checkboxes; the adapter can preserve the Skill's departure_dates/recurrence semantics while selecting the matching generated dates.
  • Confirmation output had two contract mismatches: the Skill example used confirmation.type=default, which the planner rejected after alias normalization, and recovery flags were emitted under data.recovery while planner validation checked only a top-level camelCase object. The plugin export executor also did not read data.export_types or data.confirmation.type for non-default types.
  • lwlt-updating and lwlt-arrangement remain intentionally blocked. The plugin exposes only historical/read-only order_update/traveler probes and no published write contract for the two updating behaviors or four arrangement behaviors; routing them to those compatibility actions would create a false success path.

2026-08-06 — Strict contract audit before plugin update

  • The active lwlt-newbooking Skill already states order_nature: "formal", submit_mode: "dry_run", no test marker, required sparse passenger/room objects, and ERP-derived OP/sales/pricing. Its examples did not make the named-reference shape explicit enough for product/customer.
  • The root Schema still allowed order_nature: "test", submit_mode: "submit", and a legacy data.test_marker; its source definition also omitted host-added task_id and parser_prompt_version metadata.
  • The external parser adapter was force-defaulting a missing action and overwriting any submit mode, then passing strings such as data.product: "老挝好时光" to the business system. It also converted flat legacy parser fields into an invented operation.
  • The extension planner accepted test, accepted legacy operation envelopes, and did not validate room-count shape, canonical dates, or named-reference types. The page preflight had the same test allowance and no room-count contract check.
  • The user's blocked task had no_erp_write: true and write_attempted: false; it was stopped by validation before ERP write. The stale executor's OP/sales blockers were not present in the current source, confirming that the active failure is contract drift plus an outdated running plugin, not an ERP write attempt.

2026-08-06 — Strict contract update completed

  • The active Skill and plugin now share the same production-only contract: named product/customer/route references, strict calendar dates, required sparse passenger/room objects, formal/dry-run modes, and ERP-owned price/staff defaults.
  • The external parser validates the returned operation before host metadata/default injection and no longer adapts flat or camelCase legacy output. The exact reported payload now returns external_operation_contract_invalid with operation: null.
  • The extension planner and page preflight reject the same malformed shapes; batch expansion preserves canonical zero-padded dates and no longer creates test markers.
  • Confirmation export aliases were removed from the Schema as well as parser/planner validation so documentation, Schema, and plugin agree on the three canonical types.
  • Extension compatibility is now 0.3.2; both ZIP artifacts were rebuilt and passed unzip -t. Safe retry for no-write validation failures remains intentionally separate from this release.

2026-08-06 — 独立团批量下单原生流程启动

  • User authorized real ERP creation for the supplied independent-team batch case and changed the live ERP origin to https://lwlt.hisy.cc/System/Mainlt.asp.
  • The requested native flow is: open independent-team batch order; fill departure range; resolve abbreviated booking customer; resolve and select abbreviated product; let the selected product populate the required group-number fields; fill estimated passengers; fill room count; select cycle dates through explicit dates or weekday/single-date shortcuts; save; return the modal group number to the business system.
  • The current active plugin does not implement this native route. team_order_batch_create is currently defined as a sequential team_single fallback, and the existing form mapping targets /System/Business/orders_add.asp with DoInfoJH, so it cannot be treated as evidence for the native batch page.
  • Chrome CDP was authorized and prepared for the logged-in local browser; the old 127.0.0.1:9223 probe was offline before connecting to the new ERP origin. Live page discovery remains the first implementation gate.

Live discovery evidence

  • The authorized Chrome target is logged in at https://lwlt.hisy.cc/System/Mainlt.asp; the main page uses Iframe_Home and dynamically opens jidiao41 for /System/Business/orders.asp.
  • The independent-team list exposes a distinct 批量下单 button with onclick="OPEN_ProEdits()". That function opens a nested dialog iframe at /system/Business/orders_adds.asp?fabudanwei=老挝联泰.
  • The native batch form title is 新增散拼团队 and its visible fields match the user's requested sequence: Riqi1, Riqi2, zutuanshe, S_chanpinming, darenshu, frenshu1, zhouqi, product radio cp_id, and SubmitButton with value 提交保存.
  • The form initially shows login-default jiedairen and xiaoshouren as 测试ai员工账号, and hidden fabudanwei=老挝联泰. The initial date range and count values are blank/zero; no save action has been sent.
  • The native batch page currently renders product rows, including a visible row 老挝好时光-(广东); its radio value and related row metadata must be extracted from the row, not guessed from the text alone.

Native batch preflight evidence

  • The form is InfoForm1, method POST, logical action Act=DoInfoJHs, endpoint /System/DAT/orders.asp, and response type script.
  • Customer data is a SelectBox dataset with columns currency, customer ID, customer name, contact, manager. The ERP's built-in filter checks one column for a contiguous substring, so the shortened input 衡阳广东 is not safe to pass through unchanged; deterministic runtime matching must tokenize the user term across the candidate's searchable fields and require exactly one candidate. In this live dataset, the unique combined match is ID 661, LW衡阳国旅云南分社(广东市场).
  • Selecting customer ID 661 through the page's own SelectBox value mapping populates zutuanshe, zutuansheid, zutuanshegzr, xiaoshouren, and keyuandi); observed values are customer LW衡阳国旅云南分社(广东市场), manager/sales 衡阳罗舟, and source 广东`.
  • Calling the native customer side effect set_travel() with product search 老挝好时光 reloads the product table and returns exactly one row in this context: 老挝好时光-(广东), 6D5N, radio name cp_id, value 409.
  • Clicking the product radio invokes set_th("LW","A") and fills tuanxuhao1=LW, tuanxuhao2=A; this is the required product-to-group-number side effect.
  • Date range 2026-9-1 to 2026-9-30 generates 30 date values. The page renders two identical checkbox nodes per date, but selecting one node each for 2026-9-3, 2026-9-5, and 2026-9-30 serializes exactly those three zhidingzhouqi values. Shortcut values are All, weekday 1..6,0, odd dates d1d,d3d,d5d,d7d,d9d, and even dates d2d,d4d,d6d,d8d,d0d.
  • With the requested values, the native page's own SubmitInfoForm() passed local required-field validation and produced one intercepted POST with 43 fields, no alert, and no network write. The redacted preflight payload hash was d06cd64734bb3fdc5171a21a41a20118dd4114230d7391d3a1ad98ac10a5a573.
  • The page source checks input[name="cpid"] while the actual product control is cp_id; because the check uses loose equality, this does not block the browser, but the plugin must validate the actual cp_id control explicitly rather than copy this typo.

2026-08-06 — 原生批量真实执行与旧插件经验对照

  • The archived plugin/Skill history was inspected after the first native attempt failed. Its confirmed production experience is the guarded DoInfoJH team-single route and the per-date team-batch fallback; archived tests and handoff docs explicitly keep native DoInfoJHs deferred because of the historical backend error/HTTP-500 risk. This was comparison evidence, not a reason to silently change the user's requested native business flow.
  • The first live native execution on the repaired deployment was intentionally not retried under the same execution ID. It reached write_started, sent exactly one approved-hash DoInfoJHs request, received an error callback with no ERP group number, and remained uncertain until a read-only order-list query found no matching target order.
  • After the user confirmed that the ERP-side bug had been fixed, a fresh execution ID exec-native-batch-20260903-retry6 was accepted. It opened /System/Business/orders.asp, invoked OPEN_ProEdits(), filled the range 2026-9-1 through 2026-9-30, uniquely resolved customer keyword 衡阳广东, uniquely resolved product keyword 老挝好时光, filled 15 adults + 1 leader and TWN=8 + SGL=1, and selected 2026-9-3, 2026-9-5, and 2026-9-30.
  • The repaired ERP returned the native success receipt 操作成功,共计新增 3 个团队 with groups LW-260903A-A, LW-260905A-A, and LW-260930A-B. The plugin queried JH_OrderList for each returned identifier over the requested range; all three returned HTTP 200 responses with a positive marker count and no login-timeout or permission text.
  • The business-system task NATIVE-BATCH-20260903-RETRY6 ended completed, with route=team_batch_native, write_attempted=true, no_erp_write=false, and the three ERP group numbers returned in group_numbers and erp_receipt.

2026-08-06 — 扩展重载后的桥接误报修复

  • 复现确认:旧业务页中残留了两个扩展重载前的桥接监听器,它们返回 Extension context invalidated;同一次 PING 还会收到当前桥接的有效 PONG。旧弹窗按“第一个响应”判定,因此误报“未联通”。
  • 修复 popup.js:忽略旧上下文错误,等待当前桥接的有效 PONG;只有超时且没有有效响应时才判定未联通。
  • 修复业务系统桥接客户端:收到同类旧上下文错误时保留 pending 请求,继续等待当前桥接响应,避免任务创建被旧监听器抢先拒绝。
  • Chrome 实际加载目录为 /Users/inmanx/Desktop/ltjt-order-assistant-0.4.0;已用最新插件包恢复该目录并重新加载扩展。当前弹窗实测显示“已联通 / 插件允许操作 ERP”。

2026-08-06 — 业务系统回查轮询修复

  • 任务 TASK-20260806044018-ocRc2O0 的插件结果已经是 completed,但业务系统卡片仍显示“待回查”。原因是前端把 reconciliation_pending 错误列入终态,停止了对插件结果的轮询。
  • 从插件只读取得完成结果后,三条团号均已回查命中:HTTP 200、found=true、无登录超时/权限错误;结果已回写业务系统,卡片现显示“已完成”。
  • 修正 LianSyn-platform/app.js:reconciliation_pending 不再是终态,并允许继续轮询;不触发重复 ERP 提交。

2026-08-06 — 控制平面中间状态收敛修复

  • 进一步确认:插件在 ERP 已写入后会先发布 status=running、stage=verification 的进度回执;控制平面原先因 write_attempted=true 把该进度误分类为不可变 reconciliation_pending,从而拒绝后续同一执行编号的完成回执。
  • 修正控制平面:写入后的 running 仍属于当前租约内的活动进度,租约过期才进入待回查;对同一执行记录、同一连接、带团号/回查证据的确定性完成回执,允许从待回查收敛为 completed。
  • 重建并加载控制平面后,任务 TASK-20260806044018-ocRc2O0 已成功收敛为 completed,业务系统接口返回 stage=verification、handoff_status=completed,且无重复 ERP 提交。

2026-08-06 — 原生批量日志完整团号修复

  • 原生批量最终日志文案此前只读取 erp_receipt.group_number,因此只显示第一条团号;结构化结果中的 group_numbers 实际一直包含全部 3 条。
  • 插件现在优先用完整 group_numbers 生成中间回执和最终回查日志:LW-260903A-A、LW-260905A-A、LW-260930A-B。
  • 已重建插件 ZIP,并同步实际 Chrome 未打包加载目录;不会改变既有回执或触发重复保存。
  • 刷新业务系统后,历史完成事件已按任务结果补全为 LW-260903A-A、LW-260905A-A、LW-260930A-B,当前卡片仍为“已完成”。

2026-08-06 — 业务设计范式与历史治理专项盘点

  • 当前项目已经具备可复用的业务适配雏形:agent设计规范/business-behavior-registry.md 负责行为路由,四个前缀 Skill 负责领域边界,schemas/ 与 mappings/ 负责标准契约和 ERP 字段映射,tools/ 与 Chrome 扩展负责确定性执行,agent设计规范/test-fixtures/ 负责样例和宿主验证证据。
  • lwlt-newbooking 的独立团批量下单已经形成三类分散资产:用户输入和归一化规则在 Skill/reference 与 fixture 中;ERP 顺序、模糊关键字唯一匹配、产品联动、批量日期、提交与团号回查在 ERP handoff、mapping、扩展和 findings/progress 证据中;标准 operation 在 Schema 和 planner 测试中。
  • 现有 开发维护规范.md 已覆盖“先 Skill、再 Schema、再 ERP 脚本、再测试和发布”的维护顺序,也有旧版 Business Handoff Template 作为历史参考;但当前仓库还没有一个明确要求每个新业务同时提交“用户输入模板/示例 + ERP 操作流程/证据 + Skill 适配”的单一入口与状态清单。
  • 2026-07-12 已完成过一轮非破坏性治理:旧 交接包/ 已归档到 archive/handoff/2026-07-12/legacy-erp-handoff/,根目录忽略规则、dist/ 发布物说明、归档/隔离说明已存在;因此本次应先在现有治理之上做分类和入口收敛,不应重复搬迁或误删历史证据。
  • 当前仓库包含约 155 个归档文件、24 个发布/构建文件,runtime/ 当前为空且被忽略;根目录 .DS_Store 仍被 Git 跟踪且已修改。当前工作树还有大量未提交业务改动,包含旧 Skill 路径删除、新 Skill/fixture/Schema/映射/测试和控制平面改动;这些不能在没有逐项归属确认的情况下当作“历史垃圾”。
  • 清理范围仍需用户确认。推荐边界是:源码、当前契约、当前 Skill、测试和真实验证证据保留;历史实现和交接材料可恢复归档;生成包只保留当前交付版本及必要的可追溯说明;仅删除经过引用扫描确认的临时运行残留、重复生成物或明确废弃副本。完整历史记录保留,不做不可恢复的大范围删除。
  • 用户已确认按上述边界执行,并明确旧版 开发维护规范.md 不再作为当前规范,需要按新的三项业务适配范式重新形成。

2026-08-06 — 业务设计范式与历史治理完成

  • 当前权威规范已从旧版维护清单重建为 开发维护规范.md:先登记 business_id,再完成用户输入契约、ERP 有序流程和 Skill 适配,最后用回执/回查、测试和发布包验收。
  • agent设计规范/business-adaptation-registry.md 是跨会话业务总索引;agent设计规范/businesses/team_order_batch_create.md 是第一个完整业务的一页式入口;agent设计规范/templates/business-adaptation-template.md 是以后新增业务的固定起点。
  • 第一业务没有复制成第二套运行规则,而是通过入口链接复用现有 lwlt-newbooking Skill、fixture、Schema/mapping、原生批量插件和真实证据,避免文档与代码再次分叉。
  • 历史治理完成:旧 API 研究报告归档到 archive/research/2026-07-07/,旧 0.3.2 扩展包归档到 archive/releases/2026-08-06/,.DS_Store 运行残留删除;旧维护规范由 Git 历史保留,不再作为当前入口。
  • 完成检查通过:9 个核心 Markdown 文件本地链接、4 个 Skill quick validator、4 个 JSON 文件解析、TypeScript no-emit、控制平面 11/11、业务/插件回归 55/55、关键 JavaScript 语法、git diff --check、当前和归档 ZIP 完整性。

2026-08-06 — 独立团单个下单只读梳理

  • 用户给出的第二个业务是:独立团单个下单,发团日期 09-03,预定客户关键词 老挝联泰,产品关键词 遇见老挝,人数 15+1,房型 TWN=8、SGL=1。
  • 现有插件已经有受保护的 team_order_create → team_single → browser_team_single 路径,入口是独立团计划表的 下单 按钮 OPEN_update(0,0,0),表单为 /System/Business/orders_add.asp,提交动作是 Act=DoInfoJH。
  • 现有 team_order_create 契约把客户当作产品模板的可派生字段;这与本次用户明确要求“先模糊搜索预定客户并点选”不一致,后续必须把 data.customer 纳入该业务的用户必填事实,并让页面适配器执行唯一匹配。
  • 在当前已登录 ERP 的单团表单中,客户 SelectBox 数据共 97 行;关键词 老挝联泰 命中三个候选:LW老挝联泰(人民币)、LW老挝联泰(美金)、LW老挝联泰(老挝)。零/多候选必须阻断,不能按当前默认 CNY 或数组顺序猜选。
  • 产品 SelectBox 中同时存在 遇见老挝(常规) 和 遇见老挝;按产品名称列做“先精确、再唯一包含”的规则时,遇见老挝 有一个精确候选,但仍需在选定客户后通过产品联动检查团号设置、业务名称/行程和其他必填字段一致性。
  • 本次只读打开和检查了单团表单,没有调用 DoInfoJH,没有保存新订单,也没有改变 ERP 数据。日期 09-03 在当前 2026-08-06 上下文中暂按 2026-09-03 作为后续保存前预检假设。

2026-08-06 — 独立团单个下单补充行为与保存前预检

  • 用户明确客户输入为 老挝联泰人名币,按已登记的安全别名归一为 老挝联泰人民币;原始关键词保留在 customer.keyword,不把隐藏客户 ID 写入 Skill operation。
  • 当前 ERP 客户数据中,归一化关键字唯一命中 LW老挝联泰(人民币);美金和老挝币记录均未被候选选择。客户匹配规则为精确优先、唯一包含兜底,零/多候选阻断。
  • 实测产品 遇见老挝 的名称列有一个精确候选;产品旁边的 #gengxinxingcheng 为可见 <a> 控件,onclick="Find_product()"。插件现在点击该控件,不再直接绕过按钮调用函数。
  • 实测 GetProduct 成功回填团号设置 LLW/A、天数、专线/业务名称和大量行程/资源字段;同时把客户暂时覆盖为产品模板客户。插件记录该覆盖,重新应用客户映射后最终客户恢复校验通过。
  • 对完整单团 operation 运行了真实页面保存前预检:表单 826 控件,产品 AJAX 成功,客户/产品/行程/团号检查通过,必填字段无缺失;提交捕获为单个 DoInfoJH 分支且 DoInfoJH_network_prevented=true,没有发送 ERP 写入请求。
  • 预检使用的标准事实:日期 2026-09-03、成人 15 + 领队 1、TWN=8 + SGL=1;当前页面回填后业务人数合计 16、房间合计 9。
  • 本次没有调用真实保存、没有解析新团号、没有写入 ERP。team_order_create 业务适配包现标记为 预检通过,真实写入仍须独立授权。

2026-08-06 — 单团业务真实保存授权已收到

  • 用户明确指出保存前拦截不算完整 ERP 测试,要求对当前单团案例执行真实保存,并要求每个业务都有独立业务适配包。
  • 当前唯一允许写入的案例:日期 2026-09-03,客户关键词 老挝联泰人名币(规范客户名 老挝联泰人民币),产品 遇见老挝,成人 15 + 领队 1,TWN=8、SGL=1。
  • 本次真实执行必须继续使用预检哈希、执行编号和 ERP 回查门禁;不改用裸请求,不重复发送写入,不保存 Cookie/客户隐藏 ID。

2026-08-06 — 单团首次真实保存尝试被安全门阻断

  • 新任务 SINGLE-20260903-20260806-1785999026144 已被插件接受并完成了单团表单打开/预检阶段。
  • 真实保存阶段没有到达 ERP 网络:liveSubmitApproved 观察到 SubmitInfoForm() 生成的 DoInfoJH 请求载荷哈希与预检哈希不一致,返回 prevented_from_network=true、无 ERP 回执、无团号。
  • 记录的状态为 execution_uncertain 是插件的写入阶段安全状态,但这次具体请求被本地哈希门禁拦截;当前证据显示 live_submit_attempted=true、prevented_from_network=true、erp_receipt=null,因此不能声称订单已保存,也不能复用该执行编号重试。
  • 待修复点:ERP SubmitInfoForm() 在函数调用中对表单/序列化载荷有动态变更,预检时的静态全载荷哈希不能直接作为下一次调用的请求哈希。修复必须继续校验关键业务字段和一次性预检边界,并在新执行编号下重新预检。

2026-08-06 — 单团第二次真实提交尝试发现指纹实现错误

  • 新执行编号 exec-single-20260903-retry-1785999345070 已完成真实路径预检,核心业务字段指纹一致,但仍未发出 ERP 请求。
  • 原因是新增指纹在同步哈希函数中处理了中文解码值,触发了 sha256Sync 的 ASCII 限制;插件捕获为 SubmitInfoForm threw before ajax,因此 ERP 网络写入仍为 0。
  • 已将指纹输入改为规范化 URL 编码值,保留中文客户/产品的字段校验语义;修复后必须重新加载实际 Chrome 扩展并使用第三个新执行编号,不能复用该失败编号。

2026-08-06 — 独立团单个下单真实保存与回查完成

  • 修复后的 0.4.0 扩展重新加载,业务桥接 PING 返回有效,ERP 操作开关为 enabled。
  • 第三个新执行编号 exec-single-20260903-live-1785999502789 按当前示例完整执行:日期 2026-09-03、客户关键词 老挝联泰人名币、产品 遇见老挝、成人 15 + 领队 1、TWN=8 + SGL=1。
  • 预检证据:客户唯一包含匹配;产品 1 个精确候选(包含匹配共 2 个);实际点击“更新行程”并观察 GetProduct 成功;产品联动产生团号设置/行程字段;客户被联动覆盖后恢复复核通过;表单 826 控件、822 个序列化字段、必填字段 0 个缺失。
  • ERP 真实保存返回成功弹窗,团号 LLW-260903A-A,产品为 遇见老挝,人数回执为 15+ (0+0+0) +1。
  • JH_OrderList 回查:日期范围 2026-9-3 至 2026-9-3,HTTP 200,团号标记命中 9 次,无登录超时/权限错误;最终任务状态 completed。
  • 已修正最终验证回执的 write_attempted 保留逻辑,避免只读回查报告覆盖“已跨过 ERP 写入边界”的事实;该修复将在下一次扩展 reload 后生效,不需要重复本次已完成订单。

2026-08-06 — 散拼团新增计划只读 ERP 发现

  • 用户给出的第三个 lwlt-newbooking 业务是 散拼团新增计划:日期范围 09-01到09-30、产品 遇见老挝、计划收客数 30、8标1单、周期日期 2026-09-03/2026-09-05/2026-09-30,以及拼单客户 南宁国旅、人数 15+1。
  • 已在用户授权的登录 ERP 中打开“散拼团计划表”并点击“新增计划”进入只读表单;入口为 /System/Business/plan.asp,新增函数为 OPEN_adds(),表单弹窗页面为 /system/Business/plan_add.asp。
  • 真实表单 InfoForm1 的保存契约为 POST /System/DAT/plan.asp?Act=DoInfoSPs,按钮为 SubmitButton=提交保存;本次没有调用保存函数、没有发送 DoInfoSPs、没有产生新团号。
  • 页面字段已确认:Riqi1/Riqi2 日期范围、jihuashu 计划收客数、frenshu0..frenshu5 对应 SGL/TWN/TRP/DBL/HNM/TL、S_chanpinming 产品搜索、zhouqi 周期复选框、拼单客户 zutuanshe、拼单人数 darenshu/xiaorenshu/ertrenshu/yingrenshu/quanrenshu。
  • 页面带隐藏 fabudanwei=老挝联泰,没有第二个可见的“计划预订客户”字段;因此 南宁国旅 应进入拼单信息的 zutuanshe,而用户示例前面的 预定客户:老挝联泰 不能未经确认直接覆盖该字段。现有 shared_plan_create 适配器仍把客户、OP、销售当作旧母团流程字段,且没有映射房型/拼单人数,需按本次真实页面重构。

2026-08-06 — 散拼团新增计划输入纠正

  • 用户确认原示例中的 预定客户:老挝联泰 是误写,正式输入不包含该字段;第三个业务只保留拼单客户 南宁国旅 和人数 15+1。
  • 语义边界已确定:南宁国旅 写入散拼新增计划页面的拼单客户 zutuanshe,老挝联泰 仅是当前 ERP 登录上下文的隐藏 fabudanwei,不进入本次 operation 的用户事实。

2026-08-06 — 散拼产品查询第一次尝试

  • 在真实新增计划弹窗中按用户关键词调用页面原生 AjaxLoadData(true) 查询 遇见老挝;请求为 /system/dat/product.asp,参数包含 S_zhuanxianlei=散拼团 和 fabudanwei=老挝联泰。
  • 当前 ERP 响应没有返回产品行,并提示没有找到匹配数据;这不是保存失败,仍未调用 DoInfoSPs。需要先确认散拼产品数据是否要求使用其它名称/类别或由产品列表的模糊候选继续选择,不能把独立团产品直接强行点入散拼表单。

2026-08-06 — 散拼产品跨类别核查

  • 在同一个已登录 ERP 页面只读调用产品查询接口,分别以 S_zhuanxianlei=散拼团、独立团 和空类别查询 遇见老挝。
  • 散拼团类别返回 0 条;独立团类别返回 遇见老挝(常规)(产品 ID 403)和精确 遇见老挝(产品 ID 399,类别显示为“保险银行商会”)。
  • 当前不能把 ID 399 或 403 直接写入散拼计划表:这会绕过页面的散拼产品过滤,可能导致业务类别、团号设置和产品行程错误。需由业务确认使用正确的散拼产品名称/类别,或明确授权跨类别操作。

2026-08-06 — 散拼产品关键词修正后的只读查询

  • 用户将产品关键词修正为 老挝广东;重新打开散拼新增计划弹窗并按原生输入查询,ERP 的连续字符串查询仍返回 0 条。
  • 该页面的空关键词散拼产品列表中存在 老挝行程--广东(产品 ID 412)等广东线路;因此 老挝广东 更可能是跨字段/分词简称,而不是 ERP 的连续产品名称。下一步会在散拼候选列表内做确定性 token 匹配,并阻断多候选,不跨类别取产品。

2026-08-06 — 散拼产品唯一关键字确认与第三业务适配

  • 用户确认业务侧产品输入必须包含唯一匹配关键字;插件规则固定为:精确/连续匹配或确定性有序关键字匹配只有唯一候选才继续,0 个或多个候选直接提示用户并阻断,不选择第一条。
  • 用户将第三业务最终产品关键字修正为 老挝广东8D。在当前散拼候选列表中,老挝行程--广东 8D7N 是唯一同时满足“老挝”“广东”“8D”有序匹配的产品;老挝好时光-(广东) 为 6D,精华老挝--广东(身份证) 为 5D,均被排除。
  • 已按最终业务语义建立 operation:planned_capacity=30、顶层 room_counts={TWN:8,SGL:1}、split_order.customer=南宁国旅、split_order.passenger_counts={adult:15,leader:1};没有把隐藏 fabudanwei=老挝联泰写成用户客户。
  • 已完成三项适配:新增 shared_plan_create.md,更新 lwlt-newbooking Skill/references/fixture/output contract,新增 plan_add.mapping.json 与 plan_add_form_schema.json,并重构散拼页面适配器的产品/客户唯一匹配、房型、周期日期和拼单人数填写。
  • 本阶段本地检查通过:插件/后台/规划器/外部 operation validator 语法检查,operation planner 24/24,external-agent-client 29/29,Schema/映射 JSON 解析;仍未调用 DoInfoSPs,下一步进行新扩展加载后的真实页面预检与授权保存。

2026-08-06 — 散拼团新增计划真实保存与全量回查完成

  • 真实执行前发现 Chrome 实际加载的是 /Users/inmanx/Desktop/ltjt-order-assistant-0.4.0,不是工作区源码;已将测试通过的 background.js、inpage.js、operation-plans.js 同步到该加载目录并重载扩展。
  • 第一次新执行在产品关键字触发 ERP 原生异步搜索后看到 0 行,未形成提交请求;第二次新执行因旧桌面副本/直接列表页容器不兼容未返回浏览器动作结果。两次均没有 DoInfoSPs 成功响应或新团号,未复用执行编号。
  • 修复产品流程:先在当前已加载散拼候选集合内按产品名称/天数做唯一连续或有序关键字匹配;只有当前列表无法唯一确定时才触发原生搜索。0/多候选仍直接阻断,不选择第一条。
  • 修复容器兼容:ensureMainPage 同时支持 Mainlt.asp 的主 iframe 和直接 /System/Business/plan.asp 列表页;明确 no_erp_write 的前置阻断不再被误报为待回查。
  • 最终授权执行任务 TASK-20260806074844-1IJ7ukM 完成真实保存。产品 老挝广东8D 唯一命中 cp_id=412、标签 老挝行程--广东 8D7N,匹配规则 unique_ordered_tokens;拼单客户 南宁国旅 唯一命中 LW南宁国旅,匹配规则 unique_contains_normalized。
  • 保存前预检确认:日期范围 2026-9-1 至 2026-9-30,计划收客 30,房间 SGL=1/TWN=8、总数 9,拼单人数成人 15 + 领队 1、总数 16,周期日期 2026-9-3、2026-9-5、2026-9-30,团号设置和 ERP 默认人员均有效。
  • POST /System/DAT/plan.asp 的 Act=DoInfoSPs 返回 HTTP 200 成功脚本:操作成功,共计新增 3 个团队,完整团号为 LW-260903A-A、LW-260905A-A、LW-260930A-B。
  • 已在散拼计划表按日期范围逐一查询三个团号,均各自命中 1 个团队,产品均为 老挝行程--广东、计划收客 30、成人 15 + 领队 1;最终业务任务状态为 completed。
  • 已将适配包、registry、mapping 状态更新为 已真实验证/live_verified;插件回执现在保留首个 group_number 兼容字段,同时返回完整 group_numbers 和 group_count。

2026-08-06 — 插件版本升级与 lwlt-newbooking 三业务核对

  • 插件从 0.4.0 升级为 0.5.0;manifest、运行时桥接版本、批量兼容桥接、业务系统最低兼容版本和操作文档已统一更新。
  • lwlt-newbooking 已完整覆盖三个 action:team_order_batch_create、team_order_create、shared_plan_create;三个业务均有独立适配包,并在登记表中标记为 已真实验证。
  • 0.4.0 ZIP 已移入 archive/releases/2026-08-06/ 保留追溯;当前 dist/ 交付包为 ltjt-order-assistant-0.5.0.zip、无版本别名 ZIP 和 lwlt-newbooking.skill。

2026-08-06 — 原生批量保存后的 ERP loading 遮罩修复

  • 用户反馈业务任务已成功但批量下单页仍显示 loading...;原因是插件为了捕获 ERP 成功弹窗而替换了原生弹窗回调,却没有关闭 ERP 的 loading 遮罩。
  • inpage.js 现在暴露统一的 closeLingeringLoading 清理器;team-batch-inpage.js 在成功回执解析后立即清理并安排二次清理,返回 ui_cleanup 证据,不触发任何额外 ERP 写入。
  • 该页面收尾修复发布为插件 0.5.1;0.5.0 包已归档,59 项业务/插件回归、TypeScript、JS 语法和 ZIP 完整性检查通过。

2026-08-06 — 散拼团解析契约漂移修复

  • 用户案例 散拼团新增计划 / 老挝广东8D / 30 / 8标1单 / 2026-09-03、09-05、09-30 / 南宁国旅 / 15+1 的失败发生在外部 Profile SSE 已完成之后、本地标准 operation 校验之前;ERP 没有打开、没有写入,也没有产生新的保存尝试。
  • 外部 Profile 当前已启用 lwlt-newbooking;直接复现同一输入可返回 shared_plan_create,字段为 planned_capacity=30、三条 departure_dates 和嵌套 split_order,说明输入语义和 ERP 适配不是本次失败原因。
  • 本地解析提示已增加三类新增业务的 canonical 字段边界;对未知字段仍 fail-closed,但错误现在会列出具体字段名。若首次结果仅是契约格式漂移,适配器在同一会话内最多自动请求一次修复,修复结果仍经过完整 validator,不会静默删除字段或进入 ERP。
  • 已增加契约修复、未知字段诊断回归测试;external-agent-client 测试 32/32、TypeScript no-emit、JS 语法和 git diff --check 通过。控制平面已重启加载补丁,健康检查返回 ai_connected=true。

2026-08-06 — Unified task lifecycle observability

  • The ambiguity was at the control-plane presentation and failure-contract boundary: external_operation_contract_invalid means the external Agent returned a result, but the local standard operation validator rejected it before confirmation, plugin handoff, or ERP write.
  • PublicTaskEvent now exposes the already-persisted event payload with transport identifiers redacted, and PublicTask exposes a normalized failure object with error code, stage, source, human message, Agent-returned flag, plugin/ERP boundary flags, and validation errors.
  • The parser now records a timestamped external_request.timeline while keeping the compatible top-level request stage; it includes result receipt, contract validation, and one same-session contract repair stage.
  • The operator page now renders one chronological large black-box 任务生命周期 console. Control-plane events and external Agent trace events are merged by timestamp; raw parse/operation/executor JSON is indented under the corresponding event in the same plain-text log.
  • The schema, README guidance, static assertions, parser tests, control-plane tests, TypeScript check, JavaScript syntax check, and git diff --check were updated and pass.

2026-08-06 — Browser execution blocker diagnosis

  • Task TASK-20260806091051-e4C0sJg returned a valid shared_plan_create operation from the external Agent and passed the local contract boundary before confirmation; the failure is not an Agent response failure.
  • The persisted ERP execution result is status=blocked, stage=browser_execution, with blocker product lookup keyword expected exactly one candidate, found 0; lookup_checks contains an empty product candidate list and exact_match_count=0.
  • The execution stopped before DoInfoSPs: no_erp_write=true and write_attempted=false. The current task must not be treated as a save-with-unknown-receipt case.
  • Public lifecycle events now retain the safe execution blocker details so the operator console can distinguish parser failure, plugin preflight blocking, and ERP write/reconciliation states.

2026-08-06 — Live ERP verification of split-product lookup

  • The authorized Chrome session is using extension version 0.5.1; the failure is not explained by loading an old extension package.
  • On the live /System/Business/plan_add.asp form, the empty product query returned 20 scatter-product rows. The row cp_id=365 displayed product name 江西老挝 and duration 10D9N, so the visible combined label is 江西老挝10D9N.
  • Typing 江西老挝10D into S_chanpinming and triggering the real ERP onblur=AjaxLoadData(true) replaced the product table with zero rows. The captured request was Act=PrintGridList_list, S_zhuanxianlei=散拼团, S_chanpinming=江西老挝10D, fabudanwei=老挝联泰; the returned SQL applies the keyword only to a.chanpinming, while the duration is a separate a.tianshu field.
  • Re-running the adapter's normalized contiguous match against the same empty-query candidate set produced exactly one result: cp_id=365, 江西老挝10D9N. The mismatch is therefore in the fallback boundary: ERP native search cannot resolve a business keyword that includes duration and then destroys the locally matchable candidate set.
  • The live verification was read-only: no product was selected and no DoInfoSPs save request was sent.

2026-08-06 — Product lookup fix and 0.5.2 delivery

  • The product catalogue sample confirms that ERP displays product name and duration together in the visible second cell, while its native S_chanpinming query filters only the product-name column. Examples include 江西老挝 10D9N, 老挝行程--广东 8D7N, 尊享邂逅老挝--江西--9.10月份 8D7N, and 尊享老挝3.10 8D7N.
  • Added a shared product lookup helper used by the split-plan and native team-batch adapters. It normalizes punctuation/full-width text, parses a duration-shaped suffix, matches Chinese route fragments in order, matches duration tokens against the duration field, and refuses zero/ambiguous results.
  • Changed the native-search fallback from “send the whole business keyword” to “reload with an empty S_chanpinming, then match locally”. This directly addresses the live 江西老挝10D → 0 rows reproduction without weakening the unique-match gate.
  • Updated the lwlt-newbooking Skill and business handoff packages to preserve the raw product keyword and document the ERP boundary. The extension is now version 0.5.2; the new ZIP includes product-lookup.js, and the Skill archive was rebuilt without .DS_Store files.
  • Regression evidence: 77/77 Node tests passed, product lookup tests 5/5, Skill quick validation passed, JavaScript syntax and ZIP integrity checks passed. No ERP save request was sent during this fix verification.
  • After reloading the workspace unpacked extension in Chrome, the live read-only regression on the real plan_add.asp returned 20 candidates: 江西老挝10D uniquely matched cp_id=365 / 江西老挝 10D9N and 老挝广东8D uniquely matched cp_id=412 / 老挝行程--广东 8D7N. The dialog was closed afterward; no product was selected and no DoInfoSPs request was made.

2026-08-06 — 真实成功运行回归证据与生命周期字段缺口

  • 附件日志对应任务 TASK-20260806095904-M7VZmvA,Agent 已成功返回合法的 shared_plan_create operation;确认、插件派发、ERP 保存、回查均已发生,不是解析失败。
  • 本次实际产品关键词 江西老挝10D 由插件在空条件候选集内唯一匹配 cp_id=365 / 江西老挝 10D9N,规则为 unique_contiguous;ERP 原生复合搜索没有被用来决定产品。
  • ERP 实际保存成功,返回两条团号:LW-260907A-B、LW-260915A-A;两条均回查为 parent_group_found,执行阶段为 submitted,write_attempted=true,no_erp_write=false。
  • 外层最终 task_event 的 agent_returned、plugin_dispatch_started、erp_write_started、reconciliation_resolved 仍是 false,与嵌套 executor_response 矛盾。根因初步定位为 control-plane/src/task-service.ts 的 recordExecutionResult() 只从成功结果中生成 executionFailure=null,随后用 ?? false 填充这些字段;这是生命周期事件序列化缺口,不是 Agent、插件或 ERP 执行失败。
  • 这条成功日志应作为产品匹配算法的真实回归样本;修复不得再次提交 ERP,只修正任务结果/事件的边界事实归一化。

2026-08-06 — 新一轮散拼计划 HTTP 500 与解析事件缺口

  • 附件日志任务为 TASK-20260806101143-Zy0vgtA。外部 Agent 返回并通过标准 operation 校验,operation 为 shared_plan_create,不是 Agent 解析失败。
  • 插件预检和确定性匹配均通过:产品 广东衡阳6D → cp_id=415、规则 unique_name_duration_tokens;客户 辽宁康辉 → LW辽宁康辉、规则 unique_contains_normalized;请求日期、计划人数、房型、拼单人数均已填入并通过预检。
  • 真正的 ERP 边界错误是 POST /System/DAT/plan.asp、Act=DoInfoSPs 返回 HTTP 500,页面弹出 提交超时!;响应没有团号,回查结果为空。因此当前状态 reconciliation_pending 是正确的安全状态,不能按普通失败自动重试,因为写入是否在 ERP 内部落库仍未确定。
  • 与上一次成功案例不同,本次没有收到 ERP 成功脚本或任何团号,不能把它归因于回查算法;需要先对照 ERP 端 500 日志/请求字段排查。
  • 新日志还暴露出解析成功事件的显示缺口:awaiting_confirmation 的外层 payload 中 agent_returned=false,但 parse_response.status=agent_parse_passed;该事件应标记 Agent 已返回、尚未派发插件、尚未发起 ERP 写入。

与已成功回执的请求差异

  • 两次请求的日期范围、Act=DoInfoSPs、房型 SGL=1/TWN=8、计划收客数 40、默认人员和团号前后缀结构一致。
  • 本次不同项是产品 广东衡阳6D / cp_id=415、客户 LW辽宁康辉 / zutuansheid=8、拼单人数 成人=8/小孩占床=1/小孩不占床=0,以及多了周期日期 2026-09-26;这些差异只能作为 ERP 端 500 的排查线索,不能在本地直接断定某一字段有问题。
  • 目前最可靠的结论是:产品/客户算法和保存前预检没有阻断;500 发生在 ERP 服务端处理 DoInfoSPs 时。由于没有成功回执,任何重试都必须先完成 ERP 列表回查或获得新的执行授权,不能由插件自动重试。

2026-08-06 — 用户确认 HTTP 500 后 ERP 已落库

  • 用户提供的 ERP 列表截图确认本次请求实际生成了团号 LW-260907A-B;可见记录产品为衡阳线路,出发日期 2026-9-7,计划收客数 40,回程/已收客信息与本次请求的 8+1 房型及 8+1 拼单人数相符。
  • 因此本次真实故障不是保存失败,而是 ERP 在保存/返回阶段产生 HTTP 500,插件没有从响应正文拿到团号,随后按安全策略进入 reconciliation_pending。插件没有重复提交,这是正确的安全行为,但回查能力不足。
  • 后续实现必须把“无团号的写入异常”分成两个阶段:先只读回查可能已落库的记录;只有回查确认 0 条时才保持不确定并等待人工处理,任何情况下都不能自动重提原始写入。

Authorized read-only ERP reconciliation check

  • 在当前登录 ERP 中只读查询散拼计划表,按请求日期逐日核查:2026-9-7 命中 LW-260907A-B,产品为 广东直飞行程--衡阳(晚航班),计划收客 40,人数 8 + 小孩占床 1 + 领队 1 = 10。
  • 同样查询 2026-9-15 和 2026-9-26,均未命中本次产品/测试人员记录;当前证据是 3 个计划日期中只落库了第 1 个,不能把整个三日期任务标记为 completed。
  • 这验证了需要“异常响应后的只读回查 + 部分落库结果”模型:已确认的团号可以回传,缺失日期仍保留 reconciliation pending,禁止重提整个任务。

2026-08-06 — 全量任务彻底删除审计

  • 当前前端 LianSyn-platform/app.js 的 canDeleteTask() 会因 completed、reconciliation_pending、blocked、failed、cancelled、dry_run 或执行已领取而置灰删除按钮;这正是用户反馈“还是无法删除”的直接原因。
  • 当前业务系统调用 POST /api/tasks/:taskId/cancel,控制平面 cancelTask() 会把任务标记为 cancelled 而不是删除;完成/待回查任务和已有 ERP attempt 会被拒绝。
  • Chrome bridge 已有 DELETE_TASK 消息,会先请求后台取消并清理 businessTasks / businessTaskResults 及当前任务缓存;该逻辑需要保留为删除前的尽力清理,但不能再把 ERP 状态阻断为前端不可删除。
  • 用户随后明确确认“都可以彻底删除,不要管进不进 ERP”,因此本轮需要新增真正的管理员硬删除接口,而不是继续放宽 cancelTask() 的状态转换。

2026-08-06 — 任务成功回执与错误摘要契约

  • tasks 当前只有通用 created_at / updated_at,没有成功回执时间或错误摘要时间字段;task_events.created_at 可作为事件审计时间,但不能替代固定 API 字段。
  • PublicTask 当前返回 result、failure、events,但没有 success_receipt / error_summary;前端 receiptFromTask() 通过 result.erp_receipt、报告、告警或消息文本推导回执。
  • recordExecutionResult() 已有 classifyExecutionResult()、hasCompletionEvidence() 和 executionLifecycleFacts(),可复用来保证只有可验证回执的 completed 才暴露成功回执。
  • failureSummary() 已统一解析解析失败、插件阻断、ERP 失败和不确定状态的错误码/阶段/消息,可作为最新错误摘要的来源;完整历史仍来自 task_events。
  • 本轮必须保持当前工作树中其他用户改动不变,尤其不触碰全量任务硬删除阶段的未完成实现。

2026-08-06 — 任务成功回执与错误摘要实现结果

  • 新迁移 006_task_outcomes.sql 为 tasks 增加两组 JSONB + timestamptz 字段,并建立组织范围的时间索引;服务端时间由 PostgreSQL now() 生成。
  • successReceiptFromResult() 统一识别 ERP 直接回执、团号/订单号、验证标记和批量子结果;成功任务通过 PublicTask.success_receipt 暴露 recorded_at 与安全回执。
  • classifyExecutionResult() 现在拒绝“无证据 completed”:任务转入 reconciliation_pending,并在结果中保留 result_status 原始值,防止前端把不确定结果误显示为成功。
  • error_summary 仅在错误状态转移时更新,因此成功后的历史错误仍可保留为最近一次错误记录;取消状态不被误报为错误摘要。完整错误历史继续由 task_events 提供。
  • 旧任务在迁移字段为空时,公共任务读取会用现有加密执行结果/失败信息兼容推导;新任务使用专用字段的精确时间戳。
  • 最终验证:控制面 19/19、legacy 57/57、TypeScript、JavaScript syntax、git diff --check 全部通过;没有应用数据库迁移,也没有触发 ERP 写入。
  • task_events、task_attempts、idempotency_keys、agent_sessions、agent_session_messages 均通过 ON DELETE CASCADE 依赖 tasks.id;audit_events 只保存文本 entity_id,outbox_events 只保存文本 aggregate_id,二者必须在删除主任务前显式清理。
  • 当前 SSE 历史事件查询通过 JOIN tasks,删除后不应再伪造一个持久事件;当前删除页面会直接刷新任务列表,其他页面依靠下一次同步发现任务消失。
  • 服务端删除不能回滚 ERP;插件取消只能作为尽力停止动作,ERP 写入已经开始时仍需继续删除平台记录。
  • 已实现 DELETE /api/tasks/:taskId,仍使用现有管理员会话与 CSRF 校验;服务端先清理 task-scoped audit_events / outbox_events,再删除 tasks,其余外键关联由数据库级联删除。
  • 前端删除流程已从 POST /cancel 切换为硬删除;插件 DELETE_TASK 返回取消失败时不再阻断业务系统删除,并仍尽力清理插件本地缓存。
  • 为避免“ERP 写入中取消失败”后后台结果重新写回,插件新增 LTJT_HARD_DELETE_TASK:设置内存取消标记,后续检查点停止执行且不再写入本地结果;已经发出的 ERP 请求仍不声称可回滚。

2026-08-06 — 散拼计划 HTTP 500 的部分落库与安全回查

  • 真实 ERP 列表证据:请求的 2026-09-07/09-15/09-26 中,仅 2026-09-07 唯一命中 LW-260907A-B;因此原始任务的正确平台状态应是“部分确认/待人工核对”,而不是全量完成。
  • 回查不能只依赖团号:HTTP 500 时 ERP 响应可能没有团号,插件必须使用已提交请求的产品、日期、计划收客数和拼单人数建立候选匹配。
  • 回查必须逐日期、唯一匹配、只读;客户名只用于优先消歧,不能在客户字段被 ERP 列表隐藏时导致已保存记录无法确认。
  • 只有所有请求日期都唯一确认,才允许生成完成回执;任何缺失或歧义都应保留 reconciliation_pending,且不允许自动重试原始保存。

Delivery evidence

  • dist/ltjt-order-assistant-0.5.3.zip 已通过 unzip -t,manifest 为 0.5.3,包含回查模块和产品匹配模块。
  • dist/ltjt-order-assistant.zip 已同步为同一份 0.5.3 包;dist/lwlt-newbooking.skill 通过完整性检查。
  • 本轮没有再次向 ERP 发起保存请求;真实环境验证保持只读。

2026-08-06 — 终态摘要缺少回执的真实原因

  • 任务生命周期本身已证明 Agent 返回成功:agent_parse_passed、SSE stream_completed、result_present=true。
  • 插件执行结果也已返回部分 ERP 回执:LW-260907A-B;同时 reconciliation.status=partial_dates_confirmed,缺少 2026-9-15 与 2026-9-26。
  • 控制平面的成功回执写入条件是 status === 'completed';当前状态为 reconciliation_pending,因此不会写入 success_receipt。这符合“未全量确认不宣称成功”的安全约束,但 UI 文案“暂无成功回执”掩盖了“已有部分回执”。
  • 本次日志使用的是未重启的旧进程:旧进程启动时间早于解析边界和不确定结果错误码修复,故日志中的 agent_returned=false、no_erp_write=false 和 task_failed 不是当前代码预期输出。

2026-08-06 — 任务卡片 UI 与状态日志审计

  • 当前三栏 workbench-grid 在 max-width: 920px 仍使用三个带最小宽度的列,并设置 overflow-x: auto;这是页面产生横向滑动的直接来源。
  • 当前卡片每张都渲染 .task-card-delete,与详情面板的 #deleteTaskButton 形成两个删除入口;用户要求删除只放在任务状态模块,因此卡片按钮应移除。
  • 截图中的长红色文案由 renderTaskDetail() 把 taskStatusText(task) 直接写入 #taskState 产生;taskStatusText() 在失败时会拼接失败阶段和完整错误消息。
  • 任务生命周期已有黑底日志和服务端 events,但 error_summary 当前仍在 终态摘要中单独渲染。完整错误应在日志中补一条错误摘要,状态区只保留短状态,避免重复和横向撑宽。
  • 当前任务卡片间距、内边距和状态胶囊仍偏大;卡片改为短状态后可进一步缩小,并通过 min-width: 0、可收缩状态胶囊和禁止横向溢出来稳定卡片区域。

2026-08-06 — 发团周期双通道实现核对

  • 独立团批量下单已完整保留两种 ERP 周期方式:有显式日期时勾选 zhidingzhouqi,没有显式日期时按 daily/weekly/odd_days/even_days 勾选 zhouqi 快捷标签。
  • 散拼团新增计划当前实际只调用 selectSplitPlanDates() 勾选 zhidingzhouqi;其 splitParentDates() 会先在插件本地展开周期,未直接使用 zhouqi 快捷标签。
  • 因此本次显式输入 09.07/09.15/09.26 的日期选择是正确的,不是只成功一单的原因;但散拼路径与映射文档声明的双通道尚未完全一致。
  • 另发现散拼本地展开 odd_days/even_days 使用了星期序号而非月内日期序号,若启用单双日周期存在语义错误;本轮只记录,不改写入逻辑。

2026-08-06 — 散拼周期双通道统一结果

  • team_order_batch_create 与 shared_plan_create 现在共用 cycleSelectionPlan(),不再由两条业务分别解释周期:存在显式 departure_dates 时逐日选择 zhidingzhouqi,否则把 daily/weekly/odd_days/even_days 映射为 ERP 原生 zhouqi。
  • 散拼本地日期展开只用于预检、日期范围校验和回查;odd_days/even_days 已改为按月内日历日期奇偶计算,不再误用星期序号。
  • 本次输入属于显式日期模式,历史请求已经正确序列化三个 zhidingzhouqi,所以旧实现差异不是只生成 09-07 一单的直接原因。
  • HTTP 500 的客户端可确定边界仍是:ERP 在同一个 DoInfoSPs 批次中先落库 LW-260907A-B,随后异常中止;通用 IIS 500 响应没有异常堆栈,具体失败字段或数据库语句只能由 ERP 服务端日志确认。
  • 版本 0.5.4 增加周期模式与快捷值预检信息,保留 0.5.3 的逐日期只读回查和禁止自动重试约束。

2026-08-06 — 为什么三日期只成功一单

  • 当前请求的 operation、预检和最终 POST 都包含三个日期;插件没有把用户输入解析成单日期。
  • 真实 ERP 只读查询:09-07 有 LW-260907A-B,09-15 和 09-26 均无团队;故确实是 ERP 在批量循环中第一项落库、后续处理遇到 500 中断。
  • 本次不是通用的“多日期只能成功一单”:历史同一 DoInfoSPs 机制曾返回 操作成功,共计新增 2 个团队 和 操作成功,共计新增 3 个团队。
  • 当前可见差异为 cp_id=415、客户 ID 8、小孩占床 1、第三日期 09-26;这些只能作为 ERP 端服务日志的排查变量,不能从客户端 500 页面确定哪一个字段触发异常。
  • 禁止直接把剩余两日期再次提交,因为第一日期已有真实团号,盲目重试可能造成重复团队。

2026-08-06 — 删除按钮无响应根因

  • 原 deleteTask() 在平台硬删除前 await sendToExtension('DELETE_TASK', ..., 4000);已确认/已执行任务会等待插件响应,插件未连接时用户至少等待 4 秒。
  • 删除失败时先设置“删除失败”,随后 renderTaskCards() 又把状态恢复成任务原状态,因此用户看不到反馈。
  • 修复为先发起插件清理但不等待,再立即执行平台硬删除;按钮显示处理中,失败时恢复为可点击的“重试删除”。
  • 页面资源查询版本已更新,避免浏览器继续使用旧的删除逻辑缓存。

2026-08-06 — 删除仍失败的运行态根因

  • 浏览器已加载 app.js?v=20260806-task-delete-responsive-1,说明不是前端缓存问题。
  • 点击删除后真实请求返回 HTTP 404,控制平面日志明确记录 Route DELETE:/api/tasks/... not found。
  • 源码已有删除路由,但 8786 端口进程早于该路由改动启动,因此运行态仍是旧路由表。
  • 旧实例终止后由现有守护链自动拉起新实例;健康检查返回 200,未认证虚拟删除探针返回 401,证明新实例已识别 DELETE 路由且没有触碰真实任务。

2026-08-06 — 解析任务卡住的数据库结构根因

  • 业务任务 TASK-20260806111446-V5d0hnc 于 19:14:47 进入 parse_running,事件只有 parse_queued 与 parse_running。
  • 控制平面日志于 19:15:16 记录 parse outcome persistence failed after retries,错误码为 PostgreSQL 42703;因此解析结果写回事务没有提交,任务仍停留在 parse_running。
  • 远程数据库 schema_migrations 尚未应用当前工作树的 006_task_outcomes;tasks 表缺少 success_receipt、success_receipt_at、error_summary、error_summary_at。
  • 控制平面和 AI 健康探针正常:/health/live 为 200,/api/status 报告数据库 ready、AI configured/reachable/authenticated;根因是应用版本与数据库 schema 不一致,不是 AI 连接失败。
  • 本次修复边界已获确认:应用缺失迁移并修复发布门禁;不重新解析该历史任务,不确认任务,不调用插件或 ERP。

2026-08-06 — 控制平面持久化修复完成

  • 远程数据库已成功应用 006_task_outcomes;tasks 现在包含四个结果/错误摘要字段及对应索引。
  • 控制平面新增 databaseReadiness() / assertDatabaseSchema():数据库不可用或必需迁移缺失时,/health/ready 返回 503,直接启动也拒绝监听端口。
  • npm run dev 与 npm start 现在先运行迁移;Docker Compose 原有的迁移前置保持不变。
  • 控制平面已重启为 PID 32880,/health/ready 与 /api/status 均正常;一个没有监听端口但仍保持数据库连接的重复 PID 29589 已清理。
  • 原卡住任务在修复期间被页面以 HTTP 200 删除;本轮没有重新解析、确认任务、调用插件或向 ERP 写入。
  • 复核发现端口冲突时旧启动路径可能留下无监听的队列定时器;已在 main() 的 listen 异常路径调用 app.close(),并重启验证新实例 PID 32880 正常。

2026-08-06 — 所有任务都显示“删除中”的根因

  • 最新服务日志显示用户触发的三次真实 DELETE 均返回 HTTP 200;这是显示错误,不是批量删除或后端卡住。
  • 页面只有一个详情区删除按钮。旧实现点击后直接把这个 DOM 节点设为“删除中…”,而切换任务重渲染时只更新 disabled,没有恢复按钮文案,因此其他任务视觉上继承了同一状态。
  • 删除状态已改为 taskId -> deleting/failed 映射;详情区每次重渲染均按当前任务 ID 计算按钮文案和禁用状态。

2026-08-10 — AgentBus integration findings

  • AgentBus is the channel boundary. The control plane should not add WeChat or other channel-specific adapters.
  • The onboarding document defines a Bot-side long-lived WebSocket: connect with ready=1 and a Bearer WebSocket token, retain session.ready fields, consume inbound event tasks, and respond with task.progress or one final task.result.
  • The current control plane already has a durable task/session pipeline: TaskService.createTask creates a new task/session; TaskService.ingestMessage creates a task or resumes the unique awaiting_user_input task for a conversation_id; scheduleParseQueue runs the parser; TaskService.events emits lifecycle events.
  • ORG_SLUG identifies the configured organization, but task rows require the database organization UUID. The AgentBus bridge needs a small organization-ID lookup or service bootstrap method rather than passing the slug as organizationId.
  • Public parse states are awaiting_user_input, parse_failed, and awaiting_confirmation; the latter is deliberately not an ERP execution trigger. The channel response must be a safe user-facing summary, not raw credentials or transport metadata.
  • The existing HTTP message endpoint requires an authenticated browser session and CSRF, so the AgentBus listener must call TaskService internally with a controlled service context and a bounded request ID.
  • The repository does not currently declare a WebSocket client dependency. The documented Authorization-header handshake is best implemented with the ws package rather than relying on the Node global WebSocket API.
  • A real short-lived handshake using the supplied onboarding document reached session.ready with epoch 1 and the expected Bot address; no business frame was sent and the socket was closed immediately.

2026-08-10 — 散拼团新增计划拼团信息规则确认

  • 用户确认 ERP 业务规则:散拼团新增计划创建阶段不能填写“拼团信息”,其中客户名称和人数都不能提交。
  • 当前实现存在明确契约冲突:schemas/standard_system_operation.schema.json 将 shared_plan_create.data.split_order 设为必填;Agent 提示和外部校验要求 split_order.customer / passenger_counts;浏览器适配器也会校验并填写 zutuanshe、darenshu 等字段。
  • mappings/plan_add.mapping.json 当前把拼单客户和拼单人数列为创建步骤与用户事实,需要移除这些创建映射。
  • 已确认修复边界:shared_plan_create 完全禁止 split_order 以及旧格式顶层 customer / passenger_counts;创建只保留产品、日期/周期、计划收客数和房型。客户与人数留待后续补录/修改流程。

2026-08-10 — 散拼创建契约修复完成

  • 标准 Schema 已移除 split_order 定义与必填约束,并在 shared_plan_create 分支拒绝 customer、passenger_counts、split_order。
  • Agent 端不再把旧的平铺客户/人数转换为 split_order;外部校验、插件校验和浏览器适配均 fail closed。
  • 创建适配器现在只处理产品、日期/周期、计划收客数、房型和 ERP 默认人员;失败回查的客户/人数条件改为可选,不携带时仅使用母团字段,候选不唯一不宣称成功。
  • 最终回归:控制平面 20/20、业务/插件 72/72、TypeScript、脚本语法、Schema/JSON、插件 0.5.5 包和 Skill 包完整性、git diff --check 均通过;没有触发 ERP 写入。

2026-08-10 — 散拼创建选填字段能力矩阵修正

  • 用户进一步明确:ERP 字段中必填项缺失才阻断;选填项如果用户提供就必须写入,未提供则留空/保持页面默认。此前“ERP 不强制必填”被误读成“ERP 不允许填写”,已纠正。
  • canonical shared_plan_create 继续使用 data.split_order;customer 与 passenger_counts 已改为独立可选。Schema、外部 Agent validator、插件 planner 和浏览器 adapter 均采用同一规则。
  • 浏览器母团路径现在仅在 split_order.customer 有值时等待客户 lookup 并写入 zutuanshe 及关联隐藏字段;仅在 passenger_counts 有值时写入五类人数并调用 GetVisitorsHtml();缺失字段不调用对应联动。
  • 旧平铺客户/人数字段只做无损兼容归一;嵌套和平铺冲突值 fail closed。回查条件也只在可选字段存在时加入,避免未提供字段造成误匹配。
  • 已更新 plan_add mapping、表单 Schema、Skill/业务文档、fixture、插件版本门槛和发布包;没有重新解析旧任务,没有调用插件或 ERP。
  • 针对性与全量回归均通过:业务/插件/外部解析 76/76,控制平面 27/27,TypeScript、脚本语法、JSON、ZIP 完整性和 git diff --check 通过。

2026-08-10 — Task source labeling findings

  • 任务卡片数据来自 /api/tasks 的 PublicTask,因此来源必须在任务表持久化,不能仅由 conversation_id 推断。
  • TaskService.createTask 和 ingestMessage 的新任务写入上下文来源;已有等待补充任务只追加会话消息并保留初始来源。
  • PublicTask 对 source 做安全归一化,未知值和旧行缺失值回退 manual,避免前端出现空标签或任意 CSS 类名。
  • 数据库迁移使用默认值和约束兼容既有任务;容器构建会把 control-plane/migrations 一并带入运行目录,部署前仍需执行迁移。

2026-08-10 — awaiting_user_input continuation findings

  • TaskService.ingestMessage() 已有正确的状态门禁:带 task_id 时只接受 awaiting_user_input;不带 task_id 时只查同一 conversation_id 下的等待补充任务;没有匹配项才新建任务。
  • AgentBus 当前只把入站 frame/payload 中的 conversation_id 传给任务服务;若渠道 Adapter 没有提供稳定会话字段,每轮消息都会落入新建任务分支。
  • AgentBus 入站 frame 已有稳定的 from 地址字段;它可作为缺失 conversation_id 时的会话键回退,且仍受 awaiting_user_input 状态限制。
  • 当前人工操作台此前移除了旧的回复面板,POST /api/messages 后端接口仍保留;本轮已确认补充入口应仅在当前任务 awaiting_user_input 时渲染,并携带精确 task_id。
  • 当前运行中的 8786 控制平面实例启动于 AgentBus 接入之前,健康接口未暴露 agentbus 状态;源码修复后仍需按发布流程重启运行态才能生效。

Implementation result

  • frameConversationId() 现在显式会话 ID 优先,缺失时使用截断后的 agentbus:<from>;出站 progress/result 也带回同一会话键,便于渠道侧保持路由一致。
  • 操作台通过动态 inputRequestPanel 显示补充框,isAwaitingUserInput() 只接受服务端任务状态 awaiting_user_input;提交走 /api/messages 并指定 task_id。
  • 完整回归已通过;未在真实数据库中创建测试任务。重启前确认没有排队/运行中的解析任务,应用既有 007_task_source 迁移后重启服务,AgentBus 已进入 session_ready。

2026-08-10 — AgentBus observability findings

  • 当前 8786 进程已连接 wss://mesh.nianxx.cn/ws 并收到 session.ready,但连接建立后的 stdout 没有入站任务处理日志,数据库也没有 source=agentbus 新任务。
  • 现有 listener 对不符合 type=event、id、from、payload.text 条件的帧静默返回,无法区分上游没有投递和帧格式被过滤;本轮日志必须记录明确的忽略原因。
  • AgentBus 日志应复用现有 Fastify logger,统一包含可 grep 的 agentbus_event,并在发送回调中记录成功/失败。
  • 消息正文可能包含客户资料;默认只记录长度/摘要,本地排障通过配置显式打开截断正文。

2026-08-10 — AgentBus observability implementation result

  • 当前日志已证明运行态能看到 listener_starting、connect_attempt、socket_open、frame_received 和 session_ready,且日志中不含 WebSocket Token。
  • frame_received 会记录完整协议元数据拓扑:frame keys、payload keys、event/status/task_id、来源/目标、conversation_id、reply_to、epoch,以及正文长度和摘要;正文预览受 AGENTBUS_LOG_PAYLOADS 控制并限制 2,000 字符。
  • frame_ignored 会记录具体原因,例如 unexpected_type:*、missing_id、missing_from、missing_payload_text 和保留事件,能直接区分上游投递与本地过滤。
  • 运行态当前只完成了握手验证,尚未重发用户业务消息;下一次发送后可在 /private/tmp/lwltapi-control-plane.stdout.log 中按 agentbus_event 检索完整链路。

2026-08-10 - LianSyn-platform UI visual audit

  • 页面入口为 LianSyn-platform/index.html,样式集中于 LianSyn-platform/styles.css,行为集中于 LianSyn-platform/app.js;没有前端框架或 UI 依赖,适合先做 CSS 令牌和结构化状态样式演进。
  • 当前页面是受保护的三列业务操作台:输入区、任务卡片、任务状态详情;桌面工作台高度锁定在 100dvh,各列内部滚动,窄屏在 920px 以下改为纵向工作区。
  • 当前品牌识别来自 assets/ltjt-platform-logo.png,为蓝绿 Logo;现有主色为绿色 #27675a,可保留并与 Logo 的蓝色保持次级信息/处理中状态,不引入新品牌色。
  • 当前视觉债务主要是:顶栏、业务面板和登录卡使用了两套不一致的圆角/阴影/灰度;输入、任务、状态和详情层级都使用相近的白色容器;状态标签文字偏小;右侧详情中生命周期日志占据强视觉权重;窄屏顶栏与三列堆叠后的信息顺序需要更明确。
  • 当前交互逻辑和重要状态已经完整:AI/插件连接状态可点击查看详情,任务支持空态/等待补充/失败/成功回执,右侧确认与删除动作由既有 JS 绑定控制;本轮仅调整可见层,不重写这些行为。
  • taste-skill 对 dashboard/dense product UI 明确列为 out of scope,因此本轮采用其 redesign audit、token、状态层级、可读性、focus、reduced-motion 和 responsive guardrails,不使用营销页 hero、bento 或装饰性图片。
  • 设计读数:DESIGN_VARIANCE=4,MOTION_INTENSITY=3,VISUAL_DENSITY=7。理由是业务操作台需要明确扫描路径与高信息密度,动效只用于状态反馈和可点击控件反馈。

2026-08-10 - LianSyn-platform UI implementation result

  • styles.css 追加 redesign-preserve UI 层:统一蓝绿品牌令牌、浅色中性画布、面板/控件圆角、阴影、边界、按钮 tactile feedback、focus ring、状态色、窄屏断点和 reduced-motion 规则。
  • 顶栏、登录卡、输入面板、任务卡、阶段板、重要消息、详情字段、状态弹层和生命周期 console 现在共享同一套 operational UI 视觉层级;没有引入第三方 UI 依赖、图标或图片资源。
  • 资源版本改为保留历史 query 前缀并追加 UI 版本:styles.css?...-ui-3、app.js?...-ui-2,避免线上缓存旧视觉层且不破坏既有静态断言。
  • 窄屏布局显式使用自动行高和输入区最小高度,避免 #rawInstruction 的桌面 height: 100% 造成任务面板覆盖创建按钮。
  • app.js 仅将状态弹层缺失值从长破折号改为“未记录 / 未提供 / 未返回”,未改变任务、认证、插件或 ERP 行为。
  • 浏览器回归使用静态前端服务和内存内脱敏 fixture;真实控制平面启动因数据库不可达而失败,因此没有做真实登录/数据库任务回归,也没有产生业务副作用。

2026-08-10 — 订单生命周期深度调研启动

  • 用户确认将散拼团新增计划计入已成功业务;此前登记表中的“待真实验证”属于最新契约变更后的证据/文档口径,没有否定既有真实保存与逐团号回查成功记录。
  • 用户确认后续不按运营文档编号直接开发,而是以 LTJT 的订单生命周期为主线:下单 → 名单导入/补充 → 团队安排 → 修改/取消 → 最终导出。
  • 本轮调研覆盖运营梳理 10—21 的全部板块。取消记录为可跨生命周期触发的终止分支;确认件导出放在最后,因为它消费名单、安排和修改后的最终订单数据。
  • 每个板块必须先产出 ERP 操作契约:页面/iframe、控件和 SelectBox、页面联动、序列化字段、提交 endpoint/action、响应/回查、失败边界;再推导插件适配契约与 Skill operation 契约。
  • 当前阶段只读,不重新保存 ERP,不上传或导出大批量客户资料,不直接修改插件/Skill。
  • 实时会话边界:授权协作 Chrome 的 CDP 127.0.0.1:9223 当前不可连接;本轮先以已有 findings.md、归档 API inventory、页面源码映射、插件探针和历史只读证据推进,不绕过登录或权限。

2026-08-10 — 生命周期第一轮静态 ERP 页面映射

  • LTJT 是经典 ASP/IIS 后台:业务页位于 /System/Business/*.asp,列表通常通过 /System/dat/*.asp 的 POST 表单编码 XHR 返回 HTML 片段,不是稳定 JSON API;页面通过 Mainlt.asp 内的多层 iframe/标签打开。
  • 订单主表入口已确认:独立团 /System/Business/orders.asp → /System/dat/orders.asp,散拼团 /System/Business/plan.asp → /System/dat/plan.asp。订单新增/编辑共享 orders_add.asp,散拼新增/编辑使用 plan_add.asp / plan_update.asp,散拼子单使用 plan_order.asp。
  • 订单创建页面本身已包含后续生命周期的公共数据:游客人数、名单/游客信息相关区域、应收款行、航班/大交通行程、每日餐饮/住宿/景点安排、接送机和附件引用。它是后续安排、修改、导出的数据源,不应把每个字段组误认为独立业务表。
  • 团队安排总入口为 /System/Business/teams.asp,当前静态证据列出子页面:teams_daoyou.asp(导游)、teams_cheliang.asp(车辆)、teams_jiudian.asp(酒店)、teams_piao.asp(大交通)、teams_qita.asp(备案/其他);团队列表数据使用 /System/dat/team.asp 的 PrintGridLists,备案列表使用 PrintGridListb。
  • 独立团和散拼计划列表都曾暴露 Act=DelRecord、Act=JH_set_quxiao 等取消相关动作;同时存在订单/计划编辑页和团队详情页。它们只能作为待实时确认的候选契约,当前不能直接写入插件。
  • 当前架构已经有 team_order_create、team_order_batch_create、shared_plan_create 的正式创建链;order_update、passenger_list_import 仍是只读/规划能力,lwlt-arrangement 对四类安排稳定阻断,confirmation_export 只读读取三类源响应。
  • 当前 agent-browser 对 https://lwlt.hisy.cc/System/Mainlt.asp 的新会话打开没有返回已登录快照;在没有快照、请求记录或用户重新提供授权会话前,不能把新会话页面当作实时 ERP 证据。

First lifecycle inference

orders/plan create → orders/plan detail + traveler import → teams.asp arrangement children → orders_add/plan_update modification or cancellation branch → confirmation/export sources.

The lifecycle contract must carry stable references (group_no, ddid, tid, tdid, child_order_no) across every phase. Product name or departure date alone is not a safe cross-phase identifier.

2026-08-10 — 历史名单、修改与导出探针线索

  • 历史名单探针显示,订单详情/子单编辑页的名单入口会打开 /daoru.asp 对话框;对话框候选控件为 textarea#DaoruText,确认动作候选包括 DaoruB / DaoRuDones。导入后应读取“游客信息/名单格式”区域的行数和已填写行数,并区分首次导入与补充导入。
  • 历史名单探针曾发现电话字段存在位置偏移,因此当前生产扩展明确不复用旧的无行作用域粘贴逻辑;重新调研必须按表头/行结构确认字段,不得按固定 input 下标写入身份证件或电话。
  • 历史修改探针依赖 /System/Business/orders_add.asp 或 plan_order.asp 编辑 iframe,读取订单人数、房型、应收款行、备注、ddid/tid 和页面函数,再按 set/delta/append 生成窄范围更新;当前扩展只保留无写入预览,旧写入脚本属于历史参考。
  • 历史导出探针从订单详情 iframe 的三个链接读取源文件:orders_confirm_new.asp(联泰)、orders_confirm_news.asp(星游)、teams_beian1.asp(JOB/团队申请类);过去可通过浏览器下载得到 .doc,但当前正式扩展只读取源响应摘要,不负责本地文件交付。
  • 这三类线索都需要当前授权会话重新确认:页面路径、链接参数、响应 content-type/content-disposition、实际文件内容,以及当前账号的权限/回查表现。

2026-08-10 — 安排、修改与导出契约的静态复核

  • 团队安排总入口仍是 /System/Business/teams.asp,主列表通过 POST /System/dat/team.asp 的 Act=PrintGridLists 查询;页面筛选已经暴露导游、车辆、酒店、火车/机票、其他、游客、备案和状态等业务维度,说明“安排”是围绕既有团队主单的资源履约层,不是重新创建订单。
  • 安排的五个子页面静态入口已确认:teams_daoyou.asp(导游)、teams_cheliang.asp(车辆)、teams_jiudian.asp(酒店)、teams_piao.asp(大交通/票)、teams_qita.asp(其他/备案相关);目前只掌握列表查询 action,尚未掌握各子页真实保存 action、字段序列化和保存后的回查规则,不能把现有 lwlt-arrangement Skill 的识别能力当作可执行能力。
  • 修改/取消的主列表仍分别使用独立团 JH_OrderList、散拼团 SP_OrderList;两者都出现 DelRecord 与 JH_set_quxiao,但静态证据不足以判断二者的权限、状态前置条件、是否软删除,以及取消后安排/收款/导出记录如何联动,必须在授权会话中逐项观察。
  • 现有扩展已经把下单后的三个确认源固定为 orders_confirm_new.asp(联泰)、orders_confirm_news.asp(星游)、teams_beian1.asp(JOB/团队申请),参数分别依赖 ddid/tid 或 ddid;它们属于“最终导出源读取”,不等于本地文件已经生成或交付。当前 confirmation_export 保持 export_only、never_resave,这条边界符合 ERP 页面范式。
  • 当前文档存在历史状态漂移:旧归档仍把原生批量 DoInfoJHs 标为 deferred,但当前扩展 README 记录 2026-08-06 已在 lwlt.hisy.cc 对授权案例完成原生批量提交并通过 JH_OrderList 三组回查;后续契约以当前代码/回查证据和本轮调研结论为准,不能直接复制旧归档结论。

2026-08-10 — 当前浏览器会话复核

  • 对 lwlt-research 会话执行了当前 URL 和交互快照读取,但 CLI 没有返回可用的 URL、页面节点或授权态快照;结合此前 9223 CDP 连接被拒绝,本轮没有新的实时 ERP 页面证据。
  • 因此安排子页保存、修改/取消状态联动、名单确认后的回查、确认件真实 content-type,以及文件下载/交付仍保持 live_revalidation_required,不提升为已支持能力。

2026-08-10 — 本机 Chrome 端口复核

  • 只读检查发现本机普通 Chrome 正在监听 127.0.0.1:9222;已尝试让 agent-browser 连接并读取快照,但命令没有返回可用页面内容。此前的 9223 端口仍不可用。
  • 端口发现不等于取得 ERP 授权态;在拿到明确页面/请求内容前,本轮仍不把安排、修改、取消或导出交付标为实时验证。

2026-08-10 — 9222 端口响应结论

  • 127.0.0.1:9222 可以建立 TCP 连接,但 /json/version 返回 HTTP 404 空响应,不是可用的 Chrome DevTools JSON 入口;因此不能从该端口读取普通 Chrome 当前标签页。
  • 结合 agent-browser 无快照输出,当前本机没有可直接复用的 ERP 实时调研会话;本轮继续停留在静态/历史证据边界。

2026-08-10 — 当前 Skill/适配登记与生命周期的差距

  • business-adaptation-registry.md 当前把 team_order_batch_create、team_order_create 标为已真实验证;散拼团只写“选填字段契约已更新,待真实验证”,与本轮已确认“散拼团下单成功”的业务事实不一致,后续应把它改为按已回查证据描述的成功状态。
  • lwlt-arrangement 和 lwlt-updating 目前都只是识别后稳定阻断,原因不是业务路由不清,而是 ERP 字段、对象定位、保存 action、回查和副作用尚未形成正式契约;这正好验证了应先深度调研 ERP 再完善 Skill 的顺序。
  • lwlt-confirmation 已经明确只允许已有订单的 export-only recovery,优先使用稳定 ERP 引用,禁止产品名/日期模糊定位和重新下单;该边界应继续作为生命周期末端的安全不变量。

2026-08-10 — 业务包覆盖范围盘点

  • 当前 agent设计规范 只有三个新增业务入口(独立团单个、独立团批量、散拼团新增计划)和一个确认件导出入口;名单导入、取消、导游/用车/酒店/大交通/其他安排、独立/散拼修改还没有一页式业务适配包、正式 action schema 或 ERP handoff。
  • 这意味着后续不能仅在 lwlt-arrangement 或 lwlt-updating 的自然语言识别层补几条字段;必须按同一标准补齐业务输入模板、页面映射、预检/提交/回查、失败边界、测试 fixture 和 Skill 输出契约。
  • business-behavior-registry.md 已经把 10–21 的主要意图注册到 Skill,但注册不等于可执行;当前 registry 应继续作为路由表,能力状态由生命周期证据矩阵单独决定。

2026-08-10 — 标准 operation 现状与调研约束

  • 当前标准 operation enum 只有 team_order_create、team_order_batch_create、shared_plan_create、shared_child_order_create、order_update、passenger_list_import、confirmation_export;没有取消和四类安排的正式 action,说明生命周期中段还没有被建模成可执行业务对象。
  • 现有 order_update 只支持 remark、房型、人数、价格和旅客列表等兼容目标的预览/校验;现有 passenger_list_import 只负责定位和校验导入计划;两者都明确不承诺 ERP 写入。
  • confirmation_export 的稳定引用优先级是 order_no/group_no/child_order_no/parent_group_no/identifier,但实际三个源还需要 ddid/tid;因此“业务编号 → ERP 内部引用 → 导出参数”的映射应成为生命周期公共上下文,而不是导出阶段临时猜测。
  • 读取 schemas/standard_system_result.schema.json 时发现该路径不存在(命令返回 No such file or directory);这不是 ERP 证据,但暴露出文档/测试中引用的结果契约路径需要后续清理或改为实际文件路径。

2026-08-10 — 历史表单字段不能替代资源安排契约

  • 历史订单编辑脚本曾把航班写入 banri* / banhao* / bancheng* / banchengs* / banshi* / banshis* / guankou*,酒店摘要写入 zhusus* 或住宿说明字段,接送机写入 jj_* / sj_*;这些是订单详情/编辑表单内的补充信息,不等价于 teams_piao.asp、teams_jiudian.asp、teams_cheliang.asp 等团队资源安排子页。
  • 历史脚本还曾按游客表格行内相对位置写入姓名、性别、护照号、电话和类型;结合此前发现的电话字段偏移,这类逻辑只能作为字段候选线索,不能直接迁移为名单导入或安排执行器。
  • 因此安排深调必须先回答“资源记录是否独立于订单详情、是否有供应商/状态/数量/日期主键、保存后在哪里回查”,再决定是子页 action 还是详情页补充字段;否则会把旅客信息或行程文本误当成资源履约数据。

2026-08-10 — 当前登录会话:团队安排总表与导游页

  • 通过桌面 Chrome 读取到当前授权 ERP 会话:lwlt.hisy.cc/System/Mainlt.asp,主页菜单和团队安排页面均可正常加载;本轮仍未点击任何“提交保存”。
  • 团队安排总表实时显示状态筛选(预订/已确认/已取消/收客中/已停止)、业务类型筛选,以及出发/回程日期、产品、OP、导游、客户、酒店、车队、团号和导/车/房/票/其他/游客/团包安排状态等筛选字段。
  • 结果表真实列为:团号/OP、出发日期/状态、回程日期/天数、产品、客户/人数、导游、用房数/酒店、车辆、大交通、备案/其他、团队说明;有已安排团队和“未安排”团队两类行,说明总表是安排状态回查的公共入口。
  • 已安排团队行中的导游、酒店、车辆、车票、其他字段均带独立“安排…信息”入口;未安排行也提供相同入口,后续可用同一套对象定位和空态/已有态回查。
  • 导游入口打开实时窗口“安排团队导游”。窗口上半段复显团号、业务类型、天数、日期、人数、状态、产品、现有导游/车辆/大交通等主团快照;中段显示子单、客户、人数、结算、航班/大交通、子单住宿说明和安排酒店。
  • 导游表单实时字段为:导游姓名(必填)、导游电话(必填)、导游等级、其他备注;另有 导管 字段、已落实/OK 复选框和 提交保存 按钮。页面下方显示游客名单表头(序号、子单号、姓名、NAME、性别、生日、年龄、出生地、证件号码、签发地、签发日、有效期、电话、备注),并提供名单 Word/Excel 导出链接。
  • 这证明安排页同时承担“资源安排表单 + 主团/子单上下文 + 名单/行程只读视图”,Skill 需要把写入字段和只读上下文分开;不能把整页所有字段序列化后盲写。

2026-08-10 — 当前登录会话:酒店安排页

  • 从团队安排总表进入实时窗口“安排团队酒店”;页面与导游页共享同一主团快照、子单上下文和五类安排切换入口(导游、用车、酒店、大交通、备案其他),另有“收导游款”入口。
  • 酒店明细表字段已实时确认:入住日期、离店日期、酒店、房型、地区、电话、币种、单价、间数、晚数、其他费用、金额、已付、结算方式、安排状态、其他备注、操作人、审核人;其中入住/离店/酒店/单价/间数/晚数带必填标识。
  • 一个团队可以有多条酒店记录,当前页面同时显示已有记录和空白备用行;已有状态出现“未确认”和“已确认”,页面计算酒店费用合计,并提供“提交保存”按钮。
  • 酒店页的业务对象不是单一酒店字符串,而是“入住区间 + 酒店/房型 + 房间数/晚数 + 费用结算 + 安排状态”的记录集合;后续 arrangement_hotel 必须按行级 upsert/修改建模,不能只传一个酒店名。

2026-08-10 — 当前登录会话:车辆安排页

  • 车辆入口打开实时窗口“安排团队车辆”,页面结构与酒店页一致:主团/子单上下文、五类安排切换、资源明细表、游客/行程只读区和提交保存。
  • 车辆明细字段已确认:开始日期、结束日期、结算单位、用车类型、车号、司机电话、币种、天数、数量、单价、其他费用、总金额、已付、结算方式、安排状态、其他备注、操作人、审核人;开始/结束日期、结算单位、天数、数量、单价带必填标识。
  • 车辆同样是多行资源记录,已有行显示日期区间、供应商/结算单位、车型描述、数量、费用和“已确认”状态,页面计算用车费用合计;有空白备用行和 已落实/OK 复选框、提交保存。
  • 因此 arrangement_vehicle 的最小业务对象应是“日期区间 + 结算单位/供应商 + 车型/车号/司机 + 天数/数量 + 价格/结算 + 状态/备注”,而不是一段自由文本。

2026-08-10 — 当前登录会话:大交通安排页

  • 大交通入口打开外层窗口“安排团队大交通”,内部页面标题为“安排团队车票”;这确认业务侧的“大交通/车票”不是单纯航班控位查询,而是团队资源安排记录。
  • 车票明细字段已实时确认:日期、结算单位、车票说明/控位说明、币种、数量、单价、其他费用、金额、已付、结算方式、安排状态、备注、操作人、审核人;日期/结算单位/说明/币种带必填标识。
  • 页面已有多条车票/手续费记录,状态为“已确认”,并有空白备用行、大交通费用合计、已落实/OK 复选框和提交保存按钮。
  • 当前页面还会复显订单原有航班/大交通摘要,但可编辑资源是下方逐行车票记录;因此 arrangement_transport 应按“日期 + 供应商/结算单位 + 票/控位说明 + 数量/价格/结算 + 状态/备注”建模,并与 tickets.asp 控位表区分。

2026-08-10 — 当前登录会话:其他/备案安排页

  • 其他入口打开实时窗口“安排团队其他信息”,内部页面为“安排团队其他”;它与车票页共用资源行表和主团/子单上下文。
  • 其他资源字段已确认:日期、结算单位、消费说明、结算方式、结算项目、结算币种、数量、单价、其他费用、金额、已付、其他备注、操作人、审核人;日期、结算单位、结算方式、结算项目、结算币种带必填标识。
  • 当前页面已有多条“团其他成本”记录,并计算其他费用总计;同时显示备案序号、备案日期、入境口岸、出境口岸等备案信息,以及 已落实/OK 控件。说明“其他”和“备案”在 ERP 中共用一个资源/费用安排页,但备案字段是独立的附加上下文。
  • arrangement_other 不能只接受“供应商+备注”;应至少支持日期、结算单位、消费/结算项目、数量/价格/币种、结算方式、状态/备注,并将备案号/口岸作为可选的备案对象字段。

2026-08-10 — 其他页备案附加字段细化

  • 备案附加区实时字段进一步确认:备案序号(带“New Number”连续编号动作)、备案日期、入境口岸、出境口岸、备案导游、导游电话、导游证号、导游证有效期、备案司机、司机电话、备案车号、驾驶证有效期。
  • 备案区有“导出备案表”链接,当前页面实例显示为 /system/Business/teams_beian.asp?did=<订单内部编号>,并有独立的 已落实/OK 复选框和“保存”按钮;这与总表/历史记录中的 teams_beian1.asp 源链接需要并列验证,不能直接合并成一个 export type。
  • 因此第 20 项应拆成“其他资源费用行”和“备案资料对象”两层:前者按费用/资源行维护,后者按团队备案资料维护并可独立保存/导出。

2026-08-10 — 当前登录会话:团队详情、修改入口与导出矩阵

  • 从团队安排总表打开团队号后,实时窗口标题为“计划信息查看”,说明安排总表与计划/订单详情通过团队引用连接,而不是跳到独立资源页面。
  • 团队详情顶部已有四类团队级文件入口:orders_Visitor.asp?tid=<tid>(整团游客信息)、teams_confirms_new.asp?tid=<tid>(导游确认单)、teams_hotel_confirm.asp?tid=<tid>(酒店预订单)、teams_piao_confirm.asp?tid=<tid>(大交通预订单)。
  • 子单订单表实时列出:子单号、客户/人数、OP/销售、游客信息、航班信息、住宿说明、酒店安排(房调)、领队信息、结算信息、导出/确认书;子单导出区另有客户确认单-联泰、客户确认单-星游、游客名单、备案表、接机牌,以及“未发送”状态和保存按钮。
  • 这使第 16 项的导出矩阵比历史静态证据更完整:至少需要区分 liantai-confirm、xingyou-confirm、visitor-list、filing-form、pickup-sign、guide-confirm、hotel-preorder、transport-preorder;每类文件的参数和 content-type 仍需读取验证。
  • 团队详情提供“修改团队信息”入口;订单表标题直接写明“订单信息(双击修改订单)”。下方操作记录实时出现“修改订单”“房调安排酒店”“车调安排车辆”“安排大交通信息”“修改其他安排”“导调安排导游”等事件,证明修改/安排已经被 ERP 记录成不同业务事件,不能合并成普通备注更新。

2026-08-10 — 当前登录会话:计划修改页字段快照

  • 从团队详情打开“修改团队信息”后,实际载入的是“修改发团计划”窗口;页面保存按钮为“提交保存”,页面同时提供“修改团队 / 应收团款 / 应收导游 / 应付酒店 / 导游产出”等业务分区入口。
  • 当前计划级可编辑字段至少覆盖:出发日期、业务名称、行程天数、收客状态(收客中/已停止/已取消)、产品名称、OP/负责人、计划收客数、用房数量、团队编号前缀、行程/餐饮/景点描述、住宿标准、接送/大交通摘要、团队文件上传、接待备注和分账政策;页面也带有应收/应付相关入口,不能将它当作单纯订单备注修改。
  • 页面包含“已取消”状态单选项,但本次没有改变状态、没有提交保存,因此尚不能证明它就是完整的取消语义,也不能推断收款、资源安排或导出权限会如何联动。
  • 计划修改页同时显示多天行程编辑控件和既有团队文件。行程编辑是高影响批量字段,后续适配必须按用户明确字段做窄范围变更,不能将整个表单控件集合覆盖提交。
  • 团队详情的订单表仍以“订单信息(双击修改订单)”标示子单修改入口;本次尝试双击订单行没有形成新的可确认子单窗口,下一步要在低风险测试单上单独确认子单修改/名单导入入口,不以计划修改页代替子单契约。
  • 当前仍为只读调研:没有输入值、选择状态、上传文件或点击任何“提交保存/保存”按钮。

2026-08-10 — 实时散拼子单修改与名单导入入口

  • 通过团队详情订单表的“订单信息(双击修改订单)”真实双击打开了“新增/修改 订单信息”窗口;这是散拼子单级页面,窗口内部标题为“散拼下单/修改”,与计划级“修改发团计划”是两条不同路线。
  • 子单级字段分组已确认:预订客户、计调 OP、客户联系人、销售人、客源地、订单状态(预订/已确认/已取消)、订单人数明细(成人/小占/小不占/婴儿/领队)、备案需求、上车/集合点、订单备注、住宿说明、大交通/航班信息(可增加/减少程数)、接送机信息(接团/送机地点、联系人、电话)。
  • 子单页面还有“应收团款”多行表,字段包含结算单位、控位说明、占位数、结算项目、币种、数量、单价、金额、已收、备注、操作人、审核人;每行有独立“删除”和收款单入口。该区域不能与普通旅客/订单字段混为一体。
  • 子单页面下方是游客明细可编辑表,表头为删除、序号、姓名、NAME、性别、生日、年龄、出生地、证件号码、签发地、签发日、有效期、电话、备注;当前已有多行示例数据,记录中含证件/电话等敏感信息,本轮只记字段结构,不把原始名单写入调研文件。
  • 名单导入真实入口为 [导入],打开窗口“导入游客【全部】数据”;窗口提示可从 Word/Excel 复制,要求“一行只能输入一个信息,换行后输入第二个信息”,提供一个文本输入区以及“取消导入/确定导入”按钮。当前未输入、未确定导入,也未触碰保存。
  • 子单窗口同时出现“删除订单”和“提交保存”两个独立按钮;结合订单状态中的“已取消”选项,已经有较强证据表明取消状态与删除订单不是同一个 UI 动作,但取消对收款、安排资源和导出权限的联动仍未提交验证。

2026-08-10 — 实时独立团修改与名单入口对照

  • 独立团计划表实时列表提供“全部状态/已取消”筛选、团号/客户/产品名检索、“批量取消”,每条记录有独立的“修改/删除/查账”入口;这与散拼团队详情的子单双击入口不同。
  • 独立团修改窗口标题为“修改团队”,计划级字段实时包括出发日期、业务名称、行程天数、预订客户、产品、计调 OP、销售人、订单人数、用房数量、团队状态(预订/已确认/已取消)、客源地、下单备注、备案需求、购物/自费/分账、订房/接待/政策备注和团队文件上传。
  • 独立团修改页同样包含应收团款行、航班信息(首末关口提示、可增减程数)、接送机信息、行程信息、游客表、游客信息文本/名单格式链接、[导入]、[清空] 和“提交保存”;名单导入对话框与散拼子单的“导入游客【全部】数据”结构一致。
  • 独立团列表的“批量取消”和单条“删除”均只做入口观察,没有点击;因此独立团取消也必须把批量取消、状态取消、删除三种操作拆开建模,不能复用同一个插件 action。
  • 在未勾选任何团队时打开“批量取消”,ERP 弹出“请选择要操作的团队!”并未发起取消;这确认批量取消有显式选择前置条件,但尚未证明勾选后是否二次确认、是否按团队还是按子单生效。
  • 独立团与散拼子单的状态控件标签相近,但实时 AX 显示的 radio value/组合文案并不完全一致;插件不能按一个通用数字值写入状态,必须按页面路线、控件 name/checked 状态和回查结果适配。

2026-08-10 — 酒店安排原生保存请求只读拦截完成

  • 从团队安排总表的酒店入口打开了真实子页 teams_jiudian.asp?tdid=<tdid>;页面内部是同源对话框 iframe,当前表单为 InfoForm1,POST action 为 /System/DAT/team.asp?Act=DoInfo_jiudian。
  • 页面原生 SubmitInfoForm() 先调用 Vidy.CheckMastInput("InfoForm1"),通过后执行 $.ajax({type:"POST", url:"/System/DAT/team.asp", data:"Act=DoInfo_jiudian&" + $("#InfoForm1").serialize(), dataType:"script", timeout:10000});成功回调关闭 loading,服务端脚本响应仍需后续在安全测试写入时读取。
  • 只读拦截保持页面现有值不变,调用了页面原生 SubmitInfoForm(),捕获到恰好 1 个 DoInfo_jiudian 分支,method=POST、dataType=script、序列化字段 206 个/202 个唯一字段;拦截器在网络层返回前阻止了发送,ERP 没有写入。
  • 当前表单共 208 个控件,酒店资源表固定渲染 7 行(索引 0–6)。每行字段族为:riqi/riqis(入住/离店)、danwei/danweiid(结算单位及内部 id)、fangxing、diqu、dianhua、bizhong、danjia、jianshu、wanshu、xianfanshu/xianfanjia/xianfan、xiaoji、fangshi、jianyeshu、qiandan、xiangmu、shuliang、zt、beizhu,另有 id/yf/cz/sh 等行级状态/审计字段。
  • 表单还携带 tdID/ddID、人数、出发/回程日期、发单单位、session_id、导游结算状态及多币种换算隐藏字段;因此适配必须保留主团/子单引用和隐藏状态,不应只提交可见酒店名称。
  • 页面载入时供应商/结算单位选项通过 AjaxPublicFun.asp?Act=ProDanweiZCxm&leibie=4... 获取;按日期/酒店/房型/结算方式改变行时,set_price() 会调用 AjaxPublicFun.asp?Act=set_price&jd=1... 回填币种、单价、地区、电话和现付费用。两类联动都应在正式适配中单独记录,不能把价格当作用户自由输入的孤立字段。
  • 安排状态下拉由页面原生 SelectBox 设为 已确认◇未确认;酒店行是否可编辑还受已付款/导游结算等隐藏状态影响,后续需要按行判断可写范围。
  • 当前可回查入口已经明确为同一团队安排 iframe 的 POST /System/DAT/team.asp?Act=PrintGridLists 总表,以及重新读取 teams_jiudian.asp?tdid=<tdid> 的 7 行资源表;本轮只完成保存请求捕获,未获得真实服务端响应或写后回查结果。
  • 本轮通过 SHA-256 记录了拦截载荷摘要(未保存原始字段值):序列化 payload 3657 字节;原始名单、电话、证件和财务明细均未写入调研文件。

2026-08-10 — 车辆安排原生保存请求只读拦截完成

  • 在同一团队安排对话框切换到 teams_cheliang.asp?tdID=<tdid>,确认车辆页仍使用 InfoForm1,原生表单 action 为 /System/DAT/team.asp?Act=DoInfo_cheliang。
  • 页面 SubmitInfoForm() 同样先做 Vidy.CheckMastInput("InfoForm1"),随后以 Act=DoInfo_cheliang&$("#InfoForm1").serialize() 调用 /System/DAT/team.asp,响应类型为 script、超时 10 秒。
  • 不改页面值直接调用原生保存函数并拦截,捕获到恰好 1 个请求分支;序列化字段 147 个/143 个唯一字段,网络发送为 0。表单共 149 个控件,当前固定渲染 5 行车辆资源(索引 0–4)。
  • 每行字段族包括 riqi/riqis(开始/结束)、danwei/danweiid(结算单位及内部 id)、车辆相关 chehao/shifu/dianhua、bizhong、shouyouke(s)、shuliang、danjia、xianfanshu/xianfanjia/xianfan、xiaojis、fangshi、qiandan、xiangmu、zt、beizhu,以及 id/yf/cz/sh 等行级状态/审计字段;最终业务标签仍以页面标签与控件 name 的联合映射为准。
  • 页面载入时以 ProDanweiZCxm&leibie=2 获取车辆供应商/结算选项,并把供应商内部 id、车辆字段、结算方式写回行控件;页面还为现付数量/天数和数量提供 SelectBox 选项 1◇2◇3,安排状态仍为 已确认◇未确认。
  • 车辆价格联动由 set_price() 调用 AjaxPublicFun.asp?Act=set_price&danwei=...&xiangmu=chehao...,回填结算方式、币种、单价、现付单价和备注;这与酒店的 jd=1 价格联动是不同契约。
  • 车辆回查仍应使用团队安排总表 PrintGridLists 与 teams_cheliang.asp?tdid=<tdid> 子页双重读取;本轮没有真实服务端响应和写后回查。

2026-08-10 — 大交通安排原生保存请求只读拦截完成

  • 在同一团队安排对话框切换到 teams_piao.asp?tdID=<tdid>,确认车票页使用 InfoForm1,原生保存 action 为 POST /System/DAT/team.asp + Act=DoInfo_piao,响应类型为 script。
  • 页面 SubmitInfoForm() 先调用 Vidy.CheckMastInput("InfoForm1"),通过后以 Act=DoInfo_piao& + InfoForm1.serialize() 发起 AJAX;本轮未改变值,调用原生函数并在网络发送前拦截,捕获 1 个保存分支。
  • 捕获结果为 296 个序列化字段、292 个唯一字段,固定 13 行票务/控位资源(索引 0–12),method=POST、dataType=script,网络发送为 0。
  • 票务行字段族包括日期、结算单位及内部 id、票/控位说明、币种、数量、单价、现付数量/单价/金额、总额、结算方式、签单、结算项目、状态、备注和 id/yf/xm/cz/sh 等行级字段;表单还带 tdID、session_id、主团日期/人数和多币种换算隐藏字段。
  • 供应商/资源选项联动为 AjaxPublicFun.asp?Act=ProDanweiZCxm&leibie=5...,价格联动为票务专用 AjaxPublicFun.asp?Act=set_price&danwei=...&xiangmu=shuoming...;状态选项实时包含“已确认/未确认/自损/取消/出票”。
  • 载荷摘要只保留长度与哈希:序列化 payload 6847 字节,SHA-256 为 5f40d6b3231675a4ae7b0c1e62572e4eebb9d517d446ffa96d34d19f5a48c0c4;未把票号、客户、证件或财务原值写入文档。
  • 本轮尚未读取真实服务端响应,也未做保存后总表/子页回查;因此仍是可执行适配前的请求契约证据。

2026-08-10 — 其他/备案安排原生保存请求只读拦截完成

  • 切换到 teams_qita.asp?tdID=<tdid> 后确认页面使用 InfoForm1,原生保存 action 为 POST /System/DAT/team.asp + Act=DoInfo_qita,响应类型为 script,表单共 268 个控件。
  • 在不改变页面值的情况下调用原生 SubmitInfoForm() 并拦截网络,捕获 1 个保存分支:266 个序列化字段、262 个唯一字段,网络发送为 0;当前固定 12 行其他成本资源(索引 0–11)。
  • 其他成本行字段族包括日期、结算单位及内部 id、消费说明、结算方式/项目、币种、数量、单价、现付、金额、备注和 id/yf/cz/sh 等行级字段。
  • 同一序列化载荷还包含备案号/旧备案号、备案日期、入境/出境口岸、备案导游及证件资料、备案司机及证件资料,以及 tdID/ddID/session_id 等上下文;这证明当前页面保存时技术上合并提交,但业务适配仍需把“其他成本”和“备案资料”分成两层对象。
  • 其他资源联动为 ProDanweiZCxm&leibie=7,价格联动为 set_price;备案选项还通过 ProGetTableZD、ProGetBeian 获取,备案表导出链接仍是独立的 teams_beian.asp?did=<did>。
  • 载荷摘要为 6082 字节、SHA-256 2de1bb1088577ab397d8b2cb2456e8228b8001ade7f8d0d309eca7b35ae05fa6;未记录客户、证件或财务原值。本轮未获得真实服务端回执和写后回查。

2026-08-10 — 导游安排原生保存请求只读拦截完成

  • 切换到 teams_daoyou.asp?tdID=<tdid> 后确认页面使用 InfoForm1,原生保存 action 为 POST /System/DAT/team.asp + Act=DoInfo_daoyou,响应类型为 script,表单共 19 个控件。
  • 在不改变页面值的情况下调用原生 SubmitInfoForm() 并拦截网络,捕获 1 个保存分支:17 个序列化字段、17 个唯一字段,网络发送为 0;当前表单有 2 个导游槽位(0–1)。
  • 序列化字段族为两槽位的导游姓名/内部 id/电话/等级/备注、导管、tdID、session_id、出发日期和发单单位;ap_dy 是落实复选框,本次未勾选所以没有进入原生序列化结果。
  • 导游资源联动为 ProDanweis&leibie=1,导管/员工联动为 ProDanwei_Yuangong,等级选项为“初级/中级/高级”;后续适配不能把导游姓名当作自由文本唯一键。
  • 载荷摘要为 300 字节、SHA-256 e7a583191d039ee04c399ce49b631712820cd0a1e35359f2d59fc91c49efdfef;未记录导游姓名、电话等原值。本轮未获得真实服务端回执和写后回查。

2026-08-10 — 独立团修改原生保存请求只读拦截完成

  • 从独立团列表打开 orders_add.asp?ddid=<ddid> 修改窗口,确认表单 ListForm 原生 action 为 POST /System/DAT/orders.asp + Act=DoInfoJH,表单 826 个控件。
  • 不改变现有值直接调用原生 SubmitInfoForm() 并拦截网络,捕获 821 个序列化字段、821 个唯一字段,网络发送为 0;核心上下文含 ddid/tdid/session_id。
  • 该宽表同时包含日期、组团社、产品、跟单/销售、状态、人数、航班、接送机、15 天行程、应收款行和游客表;Skill 不能把原生宽表等同于用户想改的字段集合。
  • 载荷摘要为 13743 字节、SHA-256 609a6f9e8f8631d59e3c2888bb91b30be4b395709ef76064ce44a6ffffa749a9;本轮未获得真实服务端响应或回查。

2026-08-10 — 散拼母团计划修改原生保存请求只读拦截完成

  • 从团队详情打开 plan_update.asp?tid=<tid>,确认表单 ListForm 原生 action 为 POST /System/DAT/plan.asp + Act=DoInfoSP,表单 645 个控件。
  • 不改变现有值直接调用原生 SubmitInfoForm() 并拦截网络,捕获 642 个序列化字段、642 个唯一字段,网络发送为 0;表单含 tdid/session_id、计划基础字段及 15 天行程组。
  • shoukezhuangtai 页面值包含“收客中/已停止/已取消”;本轮未切换状态或提交,不能据此推断取消联动。
  • 载荷摘要为 29043 字节、SHA-256 0085f88fe4bc35428f9cccf601c58ab172f8b1ec1ac15d1e7423b439573802b2;本轮未获得真实服务端响应或回查。

2026-08-10 — 散拼子单修改原生保存请求只读拦截完成

  • 确认 plan_order.asp?tdid=<tdid>&ddid=<ddid> 子单编辑表单 ListForm 原生 action 为 POST /System/DAT/plan.asp + Act=DoInfo_order,表单 500 个控件。
  • 不改变现有值直接调用原生 SubmitInfoForm() 并拦截网络,捕获 495 个序列化字段、159 个唯一字段,网络发送为 0;重复 name 来自应收行/游客行,不能用唯一字段数代替行数。
  • 子单表单含 tdid/oldtdid/ddid/session_id、订单状态、人数、备案、航班、接送机、应收款和游客表;状态值包含“预订/已确认/已取消”,名单入口为 DaoRuLie('全部','')。
  • 载荷摘要为 11674 字节、SHA-256 7cd2a73ac798095925f80b3559b29b9d45cc51fa1a2a2a356601d8e84d68cb12;本轮未获得真实服务端响应或回查。

2026-08-10 — 取消/删除原生动作只读拦截完成

  • 独立团列表函数 set_quxiao(cz) 的真实页面链路已在选中一条现有记录后做只读拦截:POST /System/DAT/orders.asp、Act=JH_set_quxiao,分别捕获 cz=1 取消和 cz=0 恢复;二次确认和“先选团队”前置均已观察,checkbox 状态已恢复,网络发送为 0。
  • 独立团单条删除 Act=DelRecord&dID&tID&txh 已在确认回调和 AJAX 层拦截;散拼计划/子单删除 Act=Del_order&tID&did 也已拦截;两者页面都明确提示删除不可恢复,均未发网络。
  • 编辑页的“已取消”只是状态 radio 选项,和列表批量取消、删除动作不是同一个 endpoint;本轮未切换 radio、未提交任何取消状态。
  • 取消对收款、资源安排、导出权限的联动,以及取消后的可逆性仍未完成实时验证,因此继续保持 order_cancel/order_delete/order_restore 阻断。

2026-08-10 — 最终确认件与业务文件源响应只读采集完成

  • 从当前散拼团队详情读取并以内存 fetch 方式访问现有导出链接,没有导航、下载落盘、转换、发送或回写 ERP。
  • 当前 9 类源均返回 HTTP 200:联泰确认单、星游确认单、导游确认单、当前备案表、历史/并列备案表、接机牌为 application/vnd.ms-word;整团/子单游客名单为 application/vnd.ms-excel 但首字节为 HTML 文档头;酒店预订单和大交通预订单为 text/html 打印页。
  • 已记录脱敏的路径模式、query key、content-type、Content-Disposition 是否存在、响应长度、内容特征和 SHA-256 摘要;没有把文件名、游客姓名、证件、电话或响应正文写入文档。
  • 关键响应长度:整团游客 12036、导游确认 77988、酒店预订单 2837、大交通预订单 7503、联泰确认 36967、星游确认 41236、当前备案 227979、历史并列备案 158204、接机牌 41140 字节。
  • 当前 teams_beian.asp 与历史/并列 teams_beian1.asp 都可返回 Word 兼容响应,但内容长度不同,不能合并成一个 export_type;接机牌依赖游客姓名 query,必须从已定位游客行生成。
  • 文件转换、落盘、发送、发送状态、失败重试和本地交付回执仍未实现,也未在本轮产生本地文件。

2026-08-10 — 名单导入解析与保存边界完成只读确认

  • 散拼子单 [导入] 打开 /System/Business/daoru.asp?ziduan=全部,页面只有 textarea#DaoruText、DaoruB2(取消导入)和 DaoruB(确定导入)三个关键控件;没有独立表单或 ERP 保存 action。
  • “确定导入”的原生 onclick 为 frameElement.api.opener.DaoRuDones($.trim($("#DaoruText").val()));frameElement.api.close():它只调用父窗口 DOM 解析函数并关闭对话框,不发网络请求;订单最终保存继续走子单 POST /System/DAT/plan.asp、Act=DoInfo_order。
  • DaoRuDones() 以首行作为表头,按表头别名识别序号、中文名、英文名/拼音、性别、生日、年龄、出生地、护照/证件号码、签发地/日期、有效期、电话和备注;性别 M/F 会转成中文男/女,英文名/拼音字段可能按列拼接。
  • 解析目标是父页面已有的 tr[id^='youke'] 行和行内字段数组,从第 1 个数据行开始覆盖;超过已有行数就停止,不自动增行。游客行由人数控件先通过 GetVisitorsHtml() 生成,因此 Skill 必须先校验人数/行数,再决定是否允许导入。
  • 清空 调用 CleanerLies(),只清掉游客表中的 text input,不删除游客行;导入文本中的空白会被页面脚本统一处理,证件/电话等字段必须在预检中做格式和行作用域校验。
  • 独立团修改页也复用同一 daoru.asp/父页解析范式,最终保存 action 已由独立团 DoInfoJH 只读拦截确认;本轮没有输入、粘贴、确认任何真实名单。

2026-08-10 — 生命周期验证计划的本地适配落地

  • 新 action 已按 ERP 原生页面边界分开,所有新 action 继续 browser_lifecycle_test/test_only,没有改变四条已验证创建路径的执行模式。
  • 新增 source.test_context 的统一闸门:必须含 run_id、marker=TEST-202609、AI 测试账号、native_baseline_id、live_window=2026-09;实际写入还要求 allow_live_write=true 且当前日期处在 2026 年 9 月。
  • 浏览器适配器只在显式测试上下文下尝试原生页面动作,并且同时记录预检、请求描述、服务端响应、回查和副作用;无响应/无回查不能报告完成。删除额外要求 marker、账号、allowlist、created_refs 和删除后回查。
  • 运行夹具固定 2026-09-03、09-05、09-30,单个路线使用 09-03,人数 15+1、房间 TWN 8,名单为 16 行合成 TSV;操作矩阵和发布门槛文件已入 agent设计规范/test-fixtures/lwlt-lifecycle/。
  • confirmation_export 仍严格 source-only,新增游客名单、导游、酒店、大交通、当前/历史备案和接机牌源类型;不实现 DOCX 转换、下载交付或外部发送。
  • 本地回归 30/30 通过;本轮未创建、修改、取消、恢复、导出或删除任何 ERP 测试订单。

2026-08-10 — AgentBus 重要消息与最终回执排查

  • 现象:渠道能收到“已收到消息,正在处理”和“指令已解析,等待平台管理员确认后继续执行”,但用户反馈平台 important_message 尤其最终回执没有完整返回。
  • 待核对链路:TaskService 公共任务结果 → important_message 字段 → taskResultText() → createTaskResultFrame() → outbound_result_sent。

复现证据

  • 实际任务 TASK-20260810113755-U5yTb8U 已在新库完成,success_receipt 含 3 个团号、房型数量、计划人数和回查状态。
  • AgentBus 日志只出现一次 task.result:状态为 awaiting_confirmation,文本为“指令已解析,等待平台管理员确认后继续执行”;确认接口和多次插件回执之后没有新的 outbound_result_*。
  • 当前 isTaskOutcome() 将 awaiting_confirmation 视为终态,completedTaskIds 随即锁定原始入站帧;后续 ERP completed 事件没有可用的 AgentBus 回传上下文。
  • importantSuccessText() 只拼接任务 message、团号和订单号,没有把 success_receipt 的其余内容格式化进渠道可见的 payload.text;虽然 payload.important_message 携带结构化对象,但渠道截图表明只展示文本。

修复结果

  • isTaskOutcome() 现在把 parse_queued、parse_running、awaiting_confirmation、confirmed、queued、accepted、running 统一视为非终态;等待确认通过 task.progress 返回,不会提前结束等待器或锁死入站帧。
  • waitForTaskOutcome() 继续监听同一任务的后续事件,收到真正终态后再发送最终 task.result;此前“确认后无回执”的上下文丢失问题已覆盖测试。
  • taskResultText() 会把重要消息文本与结构化详情合并为渠道可读文本;完成任务的 success_receipt 同时仍以 important_message 字段附带在结果 payload 中。
  • 当前运行态已验证数据库、schema 和 AgentBus session ready;尚未用新的外部 AgentBus 消息做真实端到端回执验证,需用户重新发送一条测试消息。

2026-08-10 — 本地 Chrome 已登录 ERP 的真实只读基线

  • 通过本地 Chrome 已登录会话接入 https://lwlt.hisy.cc/System/Mainlt.asp,页面显示账号为“测试ai员工账号”;本轮只做真实页面导航、筛选和表单预检,没有触发任何 ERP 写入。
  • 独立团列表按出发日 2026-9-3 至 2026-9-30 并勾选“只看我的”检索,结果为 0 个订单;列表中未发现已有 TEST-202609 测试对象。
  • 散拼团列表按同一 9 月区间检索,返回 32 个团队,页面未提供“只看我的”过滤,结果没有 TEST-202609 标记;这些是既有运营数据,未进入本次测试允许清单。
  • 真实新增入口与写入 action 已核对:独立单个 orders_add.asp → POST /System/DAT/orders.asp、Act=DoInfoJH;独立批量 orders_adds.asp → Act=DoInfoJHs;散拼母团 plan_add.asp → POST /System/DAT/plan.asp、Act=DoInfoSPs。三个表单均只打开到提交前,没有填写后保存。
  • 团队安排总表按五类入口拆分为 teams_daoyou.asp、teams_cheliang.asp、teams_jiudian.asp、teams_piao.asp、teams_qita.asp;对应原生保存 action 分别为 DoInfo_daoyou、DoInfo_cheliang、DoInfo_jiudian、DoInfo_piao、DoInfo_qita,本轮仅读取字段和保存按钮。
  • 详情页源导出链接已真实核对:独立团客户确认件/导游通知/接机牌/游客/酒店/大交通/JOB;散拼母团只提供整团游客、导游、酒店、大交通,客户确认件、子单游客、备案表和接机牌挂在具体子单引用下。
  • 列表级取消/恢复使用 JH_set_quxiao,删除使用独立团 DelRecord(dID,tID,txh) 或散拼 DelRecord(tID,txh);仅读取页面函数和确认文案,没有调用 AJAX。
  • 在未保存的独立团表单中本地生成 15+1=16 行游客,使用 17 行合成 TSV 调用页面 DaoRuDones():实际 DOM 保留 16 行、16 个 TEST-202609 备注、溢出第 17 行未写入,证明原生导入确有“先生成行、超行截断”边界;该操作未发网络请求。
  • 当前日期为 2026-08-10,已确认的 2026 年 9 月写入窗口尚未开始;因此真实下单、保存安排、修改、取消/恢复、导出交付和删除仍待 9 月执行。

2026-08-10 — 业务操作根目录边界校正

  • 用户明确确认:当前 AI 测试账号的可用范围是 ERP 的“业务操作”根目录;“客户信息”“导游信息”“酒店/车队/票务/其他合作商”等合作商管理页不是本次运营生命周期的操作入口。
  • 真实 Chrome 核查中从主框架点击这些资料页后,子 iframe 返回“您权限不够,不能进行操作!”;这验证了它们既不属于当前账号的可用权限,也不应作为本计划的主流程依赖。
  • 当前有效的业务操作菜单为:产品管理、独立团计划表、散拼团计划表、团队安排、酒店用房表、航班控位表、团队备案表,以及同一根目录下的退货/收付款等业务单据页。订单生命周期验证以这些页面的业务对象、原生请求和写后回查为准。
  • 业务表单中的客户、产品、OP、导游、酒店等字段仍可能通过 ERP 内嵌选择控件引用既有对象;适配只读取并复核表单返回的内部引用,不导航或改动合作商主数据页,也不把“客户信息”等资料页作为独立 operation。
  • 通过业务操作根目录重新确认:独立团计划表、散拼团计划表、团队安排、酒店用房表、航班控位表和团队备案表均可在当前登录态打开;本轮仍只读,未提交任何写入。

2026-08-10 — 业务操作页面边界与原生入口复核

  • 独立团计划表真实页面提供出发/回程日期、团号、客户、产品、OP、游客、导游、领队、确认书和“只看我的”等筛选;创建入口为“下单”和“批量下单”,列表级取消为“批量取消”,每行提供修改、查账、删除、插入、复制。
  • 业务操作页面的生命周期引用继续以页面内部返回的 ddid/tdid/团号/客户内部 ID/产品内部 ID 为准;显示名称只能用于候选检索,不能单独作为写入键。
  • 已在生命周期浏览器适配器增加业务根目录闸门:只有当前页面路径位于 /System/Business/ 时才允许进入生命周期预检;其他页面直接返回 lifecycle_business_operation_scope_required,不会触发 ERP 请求。
  • 该闸门不改变已确认的原生动作,只限制操作范围;/System/DAT/ 仍仅作为业务页面提交时的固定服务端 action,不作为独立页面入口。
  • 生命周期回归 33/33、TypeScript 检查通过,浏览器目标构建通过;本轮仍没有 ERP 写入。

2026-08-10 — 组织级全自动化流程方案确认

  • TaskService 当前把解析成功任务置为 awaiting_confirmation,只有 /api/tasks/:taskId/confirm 才转为 confirmed,随后浏览器插件通过 claimForBrowser() 领取并进入 ERP 执行;自动化实现应复用该唯一执行权/租约链路,不能新增旁路写入。
  • TaskContext 已带 organizationId,组织和用户关系由服务端会话确定;组织级开关应以组织 ID 隔离,不能使用浏览器本地状态或进程级环境变量。
  • server.ts 已有管理员会话、任务 API、事件流和审计入口;平台前端位于 LianSyn-platform/,可在现有工作台增加开关状态与操作反馈。
  • AgentBus 监听器已有入站任务上下文和最终回执等待逻辑;自动模式需要让新解析任务在确认门禁处自动转为可领取状态,同时保持 awaiting_user_input、parse_failed 和 ERP 不确定结果的终止语义。
  • 历史待确认任务不追溯执行、关闭不打断已开始 ERP 执行是已确认边界;因此开关状态应在解析/确认边界读取并写入任务审计或快照,避免关闭后改变已进入执行的任务。
  • 实际执行边界:claimForBrowser() 只接受 confirmed 任务,并创建唯一 task_attempts.phase='erp' 租约;平台 handoffTaskToExtension() 先 claim,再通过 window.postMessage 将任务交给插件。因此自动模式不能只改变 AgentBus 文案,必须同时让平台 UI 对自动确认任务自动触发 handoff。
  • 建议新增 organizations.automation_enabled(默认 false)和 tasks.confirmation_mode(manual/automatic,默认 manual);后者作为任务快照,让开关关闭后已自动确认任务仍按既定边界继续。
  • 设置 API 需使用现有管理员会话、CSRF 和组织隔离;按钮状态不能依赖 localStorage,并应通过 audit_events 记录开启/关闭。
  • 已落地 009 迁移:organizations.automation_enabled=false 默认关闭;tasks.confirmation_mode='manual' 默认保守,约束值为 manual|automatic。
  • applyParseResult() 在同一事务内读取组织开关和任务 source;只有 source='agentbus'、解析有 operation、无 blockers 且非 awaiting user input 时,才把任务从解析结果直接转成 confirmed、handoff_status='awaiting_handoff'、confirmation_mode='automatic',并写入 task.auto_confirmed 审计。
  • 平台自动派发仅筛选 confirmation_mode='automatic' 的 confirmed 任务;插件未连接、版本过低或 ERP 操作开关关闭时保留自动确认状态,后续桥接检测继续重试,不降级成需要人工确认。
  • 当前组织实际迁移后 automation_enabled=false,历史 AgentBus 任务为 confirmation_mode=manual 且已完成;没有发生历史任务追溯执行。
  • 前端自动派发使用 confirmation_mode=automatic 任务快照而非当前组织开关判断;因此关闭开关不会撤回已经自动确认的任务,符合“已进入自动链路继续完成”的约定。服务端仍只允许 confirmed 任务经唯一 claim/ERP attempt 进入插件。
  • npm start 的编译产物迁移路径已修复并验证;当前运行服务健康检查与 AgentBus session 均正常。
  • 最终回归结果:control-plane 28/28、业务/外部回归 67/67、AgentBus focused 5/5;TypeScript 构建、前端语法和 diff 校验全部通过。
  • 当前运行组织开关仍为关闭,功能已部署到代码和数据库但未自动开启;启用后的实际 ERP 写入仍由在线平台浏览器插件桥接执行。

2026-08-10 — AgentBus 渠道回执摘要过滤

  • 截图中的技术详情来自 AgentBus task.result.payload.text 对 important_message 内部对象的 JSON 拼接,而不是 ERP 回执本身缺失。
  • 渠道所需的成功摘要已经由 TaskService 生成,包含完成说明及团号/订单号;因此对外只使用这段摘要,不再展开 success_receipt 的验证状态、房型数量等字段。
  • 渠道结构化 important_message 也经过单独裁剪:等待用户补充时仅保留问题列表,成功/失败不发送内部回执和诊断对象;平台内部 API 不变。
  • AgentBus 回归新增了“摘要保留、技术字段不泄露”的断言;控制平面 28/28、业务/外部回归 67/67 全部通过,运行服务已重启并健康。

2026-08-10 — AgentBus 错误回执摘要压缩

  • 错误回执与成功回执一样,不能把平台内部诊断对象直接交给渠道;错误文本保留首条主错误,特殊的不确定写入、必填项缺失和契约校验失败统一转成用户可理解的一句话。
  • 截图中的长串会被截断在第一个中文/英文分号之前,因此保留“插件执行阻断”和“已阻断 ERP 写入”等关键结论,不再展示 GetProduct、字段 effect、匹配数量等排障细节。
  • 平台内部任务对象和生命周期日志继续保留完整 failure/error_summary,本次只改变 AgentBus 对外 payload.text 和安全版 important_message。
  • 当前服务已加载新代码并健康;相关 AgentBus 与控制面测试全部通过。

2026-08-10 — 真实 ERP 生命周期执行与来源地规则落地

  • 用户补充的关键规则已在真实会话中得到验证:产品关键字的来源地必须与客户来源地一致,例如广东/衡阳产品必须选择广东/衡阳来源客户;不匹配时出现超时/HTTP 500。修正来源地后独立批量创建成功,但散拼批量仍 HTTP 500,因此来源地匹配是必要条件而不是充分条件。
  • 当前 Chrome 登录账号为“测试ai员工账号”,所有对象均使用 2026 年 9 月日期、TEST-202609 标记和合成游客资料;所有操作局限于 /System/Business/ 业务操作根目录,没有进入或修改客户/导游/供应商主数据页。
  • 已完成真实创建与回查:独立团单个 LW-260903A-A(tid 14364、ddid 14442);独立团批量 3 条 LW-260910A-C/14369/14444、LW-260915A-A/14370/14445、LW-260925A-C/14371/14446;散拼单个母团 LW-260903A-B(tid 14365)及子单 ddid 14443。散拼批量错误尝试产生的 4 个部分母团也已逐一回查后清理。
  • 名单导入在独立单与散拼子单均返回 HTTP 200“修改成功”,16 行合成数据回查一致。已记录两个原生适配缺陷:表头必须是“证件号码”;通用电话 selector 会混入接送机电话,必须按行定位。
  • 独立单五类安排均返回 HTTP 200 并在总表/子页回查:导游、车辆、酒店、大交通、其他/备案均为未确认;车辆成本被 ERP 联动重算为 1900,作为系统副作用留档,未触发采购或付款。
  • 修改/状态结果不等价:独立单备注修改持久化;散拼子单 zhusushuoming 持久化而 xiadanbeizhu HTTP 200 后未回查到;编辑页取消/恢复通过;列表取消通过,但列表恢复出现 HTTP 200 与 UI 仍显示已取消的不一致,未盲目重试,改用编辑页恢复回到预订。
  • 已完成 10 类 source-only 导出响应读取,保存了类型、长度和脱敏 hash;未下载、转换、发送或从母团直接导出客户确认件。具体矩阵在 evidence-register-live-20260810.md。
  • 清理结果:3 条独立批量、1 个散拼母团及其子单、4 个散拼批量部分母团均删除并写后回查为 0;独立单 LW-260903A-A 因应收零行仍保留财务账记录,财务页面对当前账号返回权限不足,未绕过权限删除,已进入人工复核清单。允许清理清单见 allowlist.live-20260810.json。
  • 已实现来源地适配:新增 source-region.js,注入后台/页面执行上下文;四类创建 validator、独立单/批量/散拼页面 preflight、Schema、ERP mapping、newbooking/lifecycle Skill、外部 parser 和 source-region fixture 均同步更新。没有来源地唯一匹配、服务端响应和写后回查,不能记为成功。
  • 发布门槛仍未满足:散拼批量 HTTP 500、散拼子单一个字段 mapping 不一致、列表恢复契约不一致、独立单财务清理权限不足;新生命周期模块继续保持 test_only/阻断。

2026-08-10 — 来源地校验层级错误定位

  • 新日志 21:41:42 的终态是 agent_parse_needs_input,缺少 data.product.source_region;no_plugin_dispatch=true、erp_write_started=false,说明插件没有机会查询 ERP 产品库。
  • 外部 Agent 的契约指导在 LianSyn-platform/external-agent-client.mjs:995 明确要求产品和客户必须提供 source_region 或在保守词表中唯一解析,因此 Agent 在没有 ERP 数据时主动追问来源地。
  • 外部标准操作校验在 LianSyn-platform/external-agent-client.mjs:1592-1595 调用 validateSourceRegionCompatibility,它发生在浏览器插件执行之前;即使 Agent 放行,后端仍会把未解析来源地当作阻断条件。
  • 插件后台的 operation-plans.js:549-555 同样在打开 ERP 前调用来源地校验;真正的页面预检 inpage.js:2178-2185 才拥有候选行和 ERP 页面上下文,但目前也需要确认校验应放在产品联动可用信息之后。
  • 正确边界已由用户确认:外部层/后台 planner 只做结构性必填校验;ERP 页面在产品/客户搜索、产品联动和派生字段核验后做来源地兼容性检查,并在 DoInfoJH/DoInfoJHs 之前阻断。
  • schemas/standard_system_operation.json 的 namedRef.source_region 已经是可选字段;主要冲突来自 Prompt 和两处运行前 validator,而不是 JSON Schema 的 required 列表。
  • inpage.js 当前在候选初始匹配后、GetProduct/产品模板联动前调用来源地检查;本轮会取消这次提前调用,改在产品联动和最终核心字段形成后调用,确保实际 ERP 派生信息可参与校验。
  • 现有外部/operation-plans 测试仍断言“来源地不一致在 handoff 前阻断”,这些断言需要改为“外部操作可进入插件;语义阻断由页面预检负责”。

2026-08-10 — 新独立团完整生命周期实测增量

  • 已在登录中的业务操作页面创建新的独立测试团 LW-260920A-A(tid 14379、ddid 14447),日期 2026-09-20 至 2026-09-27,客户/产品为北京来源唯一匹配,15+1 人、TWN 8,标记为 TEST-202609 LTJT-FULL-LIFECYCLE-NEW-01;原生 DoInfoJH 返回 HTTP 200,列表逐项回查一致。
  • 新单 16 行合成游客已通过 DoInfoJH 保存并重新打开编辑页回查:16 行姓名、证件标记和顺序均存在。第一次页面原生提交结果不确定时没有自动重试;改用明确的原生 action 并以重新打开页面为权威回查。
  • 新单五类安排中导游、车辆、酒店、大交通、其他/备案均已得到 HTTP 200“操作成功”并在团队总表或子页重开后回查。所有资源保持测试/未确认语义;没有触发采购、付款、通知或外部发送。
  • arrangement_other 的真实请求为 POST /System/DAT/team.asp + Act=DoInfo_qita,本次 133 个序列化字段;其他成本行保存为结算单位内部 ID 1347、数量 1、单价 0、CNY、备注 TEST-202609 other arrangement,备案号 99092079、备案日期及进出境口岸一并持久化。总表回查到其他成本,重开子页回查到全部备案字段;ap_qt 保持未勾选。
  • 当前独立单列表显示应收总款 0、已收 0,具备继续验证修改、取消/恢复、源读取和安全清理的前置条件;已有残余单 LW-260903A-A 仍因财务账阻断,不混用为本次删除对象。
  • 第一次“多业务字段同时修改”尝试向 DoInfoJH 提交 1046 个字段并得到 HTTP 200 空响应;关闭编辑页、重新检索后人数、房数、下单备注均保持原值,证明该次没有持久化。按不确定写入规则未自动重试,后续改为单字段原生提交逐步隔离阻断字段。
  • 隔离到仅修改 xiadanbeizhu 后,直接 fetch 路径仍为 HTTP 200 空响应且列表回查保持原值,说明问题不是多字段组合本身;下一种方法改用页面原生 jQuery SubmitInfoForm()/dataType=script 路径,避免继续重复已证实不持久化的直接提交方式。
  • 页面原生 jQuery/script 路径在 Vidy.CheckMastInput("ListForm")=true 后仍得到 HTTP 200 空响应,重新检索也未持久化。三种载荷/传输组合均指向同一 ERP 阻断:该已完成五类安排的订单当前不能通过 DoInfoJH 修改,页面没有返回可解释错误。停止继续试写这张单的修改字段;独立团修改契约保留早先成功样本,并新增“安排后空响应”人工复核条件。
  • 对新单执行列表级 JH_set_quxiao(cz=1, tid=14379),服务端 HTTP 200 明确返回“还有【团队成本-应付其他】账,不能取消”;列表回查仍为“预订”。这说明 arrangement_other 即使数量 1、单价/金额为 0,也会建立取消前置账对象,不能把“金额为 0”等同于“无财务前置”。
  • 新单安排态的 10 类导出源已全部同源内存读取:客户确认单两版、JOB、游客名单、导游通知、酒店/大交通预订单、备案当前/历史和接机牌均为 HTTP 200,类型与 ERP 页面契约一致,无登录/权限错误标记;完整字节和 SHA-256 已写入真实证据表,没有下载、转换或发送。
  • 清理前重开 teams_qita.asp?tdid=14379,其他成本行的 ERP 行 ID 为 88435、付款引用 yf0=0、审核为空,结算单位/备注/备案字段均与本次测试标记一致;没有专用删除按钮,后续只能通过同一 DoInfo_qita 表单对该精确行做清空语义并回查,不能改动其他行。
  • 对精确行 ID 88435 使用 DoInfo_qita 清空资源引用和数量,服务端 HTTP 200“操作成功”;团队总表不再显示代收代付成本,重开子页 5 行均为 id=0/danweiid=0,而备案号、日期和口岸仍保留。由此确认“其他成本行删除”和“备案资料保留”虽共用一次表单载荷,但可以按业务层分离操作。
  • 车辆安排精确行 ID 88432(未付款、未审核、未确认、标记一致)通过 DoInfo_cheliang 清空后,服务端 HTTP 200“操作成功”;总表不再显示车辆资源,重开车辆页所有行均无活动 ID/供应商引用。车辆成本 190 随精确资源行删除,没有删除付款记录。
  • 酒店安排精确行 ID 88433(8 间 × 7 晚、未付款、未审核、未确认)通过 DoInfo_jiudian 清空后,服务端 HTTP 200“操作成功”;总表不再显示酒店资源,重开酒店页无活动行。总表仍显示订单基础字段 TWN8=8,这是订单房型需求,不是残留酒店安排,适配器回查必须区分两者。
  • 大交通安排精确行 ID 88434(16 张、金额 0、未付款、未审核、未确认)通过 DoInfo_piao 清空后,服务端 HTTP 200“操作成功”;总表和重开票务页均无活动资源行。
  • 团队导游槽位内部 ID 11 通过 DoInfo_daoyou 清空后,服务端 HTTP 200“操作成功”;总表只保留导管/操作账号信息,重开子页 daoyou0 为空、daoyouid0=0、落实未勾选。ERP 会在无第二导游时把 MaxI 从 2 收缩为 1,因此回查不能假设固定两个槽位。
  • 清除成本安排后,列表级取消 JH_set_quxiao(cz=1) 返回 HTTP 200“操作成功”,显式“已取消”筛选回查到状态已取消。列表级恢复 cz=0 同样返回 HTTP 200,但响应脚本仍写“已取消”;显式“预订”筛选为空、“已取消”筛选仍命中。该缺陷在第二个独立对象上稳定复现,不能再把列表恢复视为有效 action。
  • 编辑页把 danzhuangtai 从“已取消”改为“预订”后,原生 DoInfoJH 返回 HTTP 200“修改成功”;显式“预订”筛选回查命中精确团号、标记与账号,应收/已收仍为 0。恢复必须走独立的编辑页 action,不能复用列表 cz=0。
  • 清除安排成本并恢复预订后,再次组合修改人数结构、房数、接送信息、首日行程和备注,DoInfoJH 仍返回 HTTP 200 空响应且列表回查保持原值。状态字段单独可写不代表所有业务字段组合可写;正式 adapter 必须按字段组逐项验证,不能把宽表一次性提交视为通用修改契约。
  • 一次单备注修改只序列化出 314 个字段(正常完整编辑页约 1046),HTTP 200 空响应且回查未变;ERP 编辑页的游客/行程等区域是异步加载的,iframe 出现或表单存在不代表可提交。适配器必须把“完整表单元素数/游客行数/加载遮罩消失”作为提交前置,禁止在半载状态保存。
  • 在明确满足 1050 个表单元素、1046 个序列化字段、16 行游客的完整页前置后,仅修改独立团 xiadanbeizhu 仍得到 HTTP 200 空响应且回查未变;这排除了半载时序因素。xiadanbeizhu 不能进入独立团可写白名单,现有“独立团备注修改成功”证据必须重新核对其真实字段名,不能继续泛称为下单备注。
  • 同样在完整页前置下,仅修改明确标注为“订房说明”的 shuoming0 也得到 HTTP 200 空响应且回查未变。结合状态恢复可成功,当前最强证据是:该订单一旦产生过安排记录,普通业务字段更新分支被 ERP 静默拒绝,即使安排成本行已清除;zhusuanpai 仍保留操作历史摘要。插件应在检测到安排历史时阻断通用业务字段修改并要求人工复核,而不是尝试清除系统历史字段。
  • C08 删除前精确核验团号/tid/ddid/账号/标记/零应收/原生调用/allowlist 全部一致;DelRecord 返回 HTTP 200“操作成功”。删除后独立团精确查询为 0 个订单,团队安排精确查询为 0 个团队且五类安排单元格均不存在。该测试对象已不可由当前账号恢复;未触碰未入清单的 LW-260920P-A 或残余 C01。

2026-08-10 — 新散拼母团原生入口与候选预检

  • 散拼列表原生新增按钮为 OPEN_adds(),在业务页内打开 /System/Business/plan_add.asp?fabudanwei=老挝联泰;真实表单为 InfoForm1,提交 action 为 DoInfoSPs。
  • 母团字段已确认:日期 Riqi1/Riqi2、计划收客数 jihuashu、房型 frenshu0..5、产品单选 cp_id、周期 zhouqi/zhidingzhouqi、ERP 默认 OP/销售和团号前后缀。母团不需要夹带子单客户和人数,子单应通过独立 plan_order.asp 创建。
  • 当前散拼产品候选中 cp_id=412 唯一对应 老挝行程--广东 8D7N;业务页客户数据中 ID 661 唯一对应 LW衡阳国旅云南分社(广东市场)。二者满足用户补充的广东/衡阳来源一致规则;只读取业务表单候选,没有进入主数据页面。
  • 原生提交脚本检查的单选名为 cpid,实际产品控件名为 cp_id;由于该检查对 undefined 不会判空,真正提交仍依赖 InfoForm1.serialize() 中的 cp_id。适配器不能仅读取脚本中的拼写,应以真实 DOM 和服务端回执为准。
  • 新母团 DoInfoSPs 原生请求返回 HTTP 200,明确回执“新增 1 个团队”并给出 LW-260922A-A;列表回查唯一命中 tid 14384,账号“测试ai员工账号”、产品、日期、计划 16、TWN 8 均一致。
  • 新子单使用业务表单 SelectBox 数据唯一解析客户 ID 661,以预订状态、15 成人 + 1 领队、零金额应收和双备注标记提交;DoInfo_order HTTP 200 明确返回 D14452,父列表回查到 ddid 14452、客户、人数和 TEST-202609。
  • CDP 对整段插件异步创建调用在页面等待阶段超时;写后精确回查确认该次没有产生 9 月 22 日对象,因此随后才执行一次人工分步原生请求。该过程没有对不确定请求盲重试。
  • C09 子单按原生 [导入] 的 DaoRuDones() 解析 16 行合成 TSV;姓名、英文名、性别、生日、证件和备注均正确填入,但页面把通用 dianhua 集合中的接团/送机电话算作前两行,造成游客电话整体错位并污染两个接送机字段。保存前按 tr[id^=youke] 行级定位修正 16 个电话并清空接送机电话;DoInfo_order HTTP 200“修改成功”,重载回查 16 行全部一致。
  • 该实测再次证明 passenger_list_import 必须包含“16 行先验 → 原生解析 → 行级字段校验/修正 → 接送机字段隔离 → 保存 → 重开回查”完整契约;只看到导入弹窗关闭不能记成功。
  • C09 五类安排均在母团 tid 14384 下真实保存并回查:导游资源 ID 11;车辆行 88436(供应商 ID 386、6 天、未确认、付款引用 0);酒店行 88437(酒店 ID 182、子单 ddid 14452、8 间 × 7 晚、金额 0、未确认);大交通行 88438(供应商 ID 1220、16 张、金额 0、未确认);其他行 88439(供应商 ID 1347、金额 0、付款引用 0)。
  • 车辆资源 set_price 异步联动会在稍后覆盖 beizhu;首个保存明确回执成功但请求备注为空。重开确认精确行 ID/未付款/未审核后,仅对该行补写 TEST-202609 并再次回查,而不是重复新增车辆。adapter 必须等待价格联动完成后再应用用户备注并冻结最终序列化快照。
  • 其他/备案共用 DoInfo_qita,备案号 99092284、日期 2026-09-22、入境“磨丁”、出境“万象”在子页重开持久化,ap_qt 未勾选;团队总表只呈现其他成本摘要,不呈现备案明细,因此总表与子页承担不同回查字段。
  • 五类安排完成后,散拼母团 DoInfoSP 使用完整 646 元素/643 序列化字段单改 jihuarenshu,HTTP 200“修改成功”;详情与列表均回查 16 → 17,日期、产品、TWN8、子单 15+1 保持不变。散拼母团普通业务字段在安排后仍可按单字段白名单更新,与独立团安排历史静默拒绝不同。
  • 同一阶段散拼子单 DoInfo_order 在完整 374 元素/369 字段、16 行名单前置下,仅把 zhusushuoming 追加 MOD-C09;HTTP 200“修改成功”且重载持久化,客户、人数、状态和 16 行名单均不变。zhusushuoming 可进入子单白名单,xiadanbeizhu 继续保持已证实的非持久化阻断。
  • C09 首次母团列表取消被“14384 应收团款”阻断。子单业务页回查到本次创建产生的两条零金额应收 ID 31551/31552,均已收 0、未审核、操作账号一致;调用页面原生 GetYSHtml('ys', index) 清零并由 DoInfo_order 保存后,重载回查 recorded receivable 数量为 0,16 行名单与住宿说明保持不变。
  • 应收清理后再次取消,ERP 进一步明确阻断为“14384 团队成本-应付其他”。这证明取消前置按账类逐层检查;清掉应收不等于可以取消,仍需对本测试对象的安排成本做精确行清理。
  • 清理安排前已冻结 C09 10 类安排态源响应:全部 HTTP 200、无登录/权限错误;字节与完整 SHA-256 已登记。未落盘、转换或发送,母团没有被误用来导出客户确认件。
  • C09 其他成本行 88439 清理前再次确认 yf0=0、审核为空、供应商 ID 1347、备注含 TEST-202609 且账号一致;使用同一 DoInfo_qita 原生表单仅清空该成本行后,HTTP 200 明确返回“操作成功”。重开子页回查活动行已变为 id0=0/danweiid0=0,备案号 99092284、备案日期 2026-09-22、入境“磨丁”、出境“万象”及 ap_qt=false 全部保持不变,再次证明 arrangement_other 必须把成本资源与备案对象拆分建模。
  • C09 车辆行 88436 清理前精确回查到供应商 ID 386、未确认、yf0=0、审核为空和测试备注;保留行 ID、清空供应商/车型/日期/数量/金额/状态后,DoInfo_cheliang HTTP 200“操作成功”。重开车辆子页三槽位均为 id=0/danweiid=0,团队总表也不再显示车辆供应商或测试备注,酒店和大交通安排未受影响。
  • C09 酒店行 88437 清理前精确绑定 ddid 14452,为 8 间 × 7 晚、未确认、yf0=0、未审核且测试备注一致;原生 DoInfo_jiudian 清空后 HTTP 200“操作成功”。重开酒店子页 16 个槽位均无活动 ID,团队总表不再显示酒店资源,但订单基础房型需求 TWN8=8 保持不变,进一步确认“资源安排”和“订单房型”必须用不同回查字段。
  • C09 大交通行 88438 清理前为供应商 ID 1220、16 张、金额 0、未确认、yf0=0、未审核且测试备注一致;保留精确行 ID 并清空资源/数量/状态后,DoInfo_piao HTTP 200“操作成功”。重开票务页五槽位均无活动 ID,团队总表同步不再显示大交通;此时仅剩导游引用和不产生成本摘要的备案资料。
  • C09 导游页清理前只有槽位 0 命中资源 ID 11 与测试备注,槽位 1 为空且 ap_dy=false;原生 DoInfo_daoyou 仅解除本团资源引用并返回 HTTP 200“操作成功”。重开后 MaxI 从 2 动态收缩为 1、唯一槽位 daoyouid=0,团队总表也不再显示导游;整个过程未进入或修改导游主数据。
  • C09 五类活动安排清理完成后的团队总表双重回查:导游、车辆、酒店、大交通和其他成本均无资源摘要,订单基础 TWN8=8 与备案资料仍保留。此状态满足再次验证取消前置的资源侧条件。
  • C09 清除零额应收与五类活动安排后,母团列表 JH_set_quxiao(cz=1, tid=14384) HTTP 200 明确返回“操作成功”;显式“已取消”筛选唯一命中 LW-260922A-A,取消状态持久化。
  • C09 只执行一次列表恢复 JH_set_quxiao(cz=0):请求约 15 秒后 HTTP 200,但服务端响应脚本仍把状态写成“已取消”;显式“已取消”筛选继续命中,而“收客中”筛选为 0。该 ERP 缺陷现已跨独立团和散拼母团复现,列表恢复必须正式禁用,恢复只能走对应完整编辑页状态 action。
  • C09 母团编辑页完整度为 646 个元素/643 个序列化字段;在 tid、日期、产品、账号、容量与当前“已取消”全部一致后,仅产生 shoukezhuangtai: 已取消 → 收客中 一项业务差异并提交 DoInfoSP。HTTP 200 明确返回“修改成功”,重开编辑页状态为“收客中”;列表“收客中”筛选唯一命中、“已取消”筛选为 0。散拼母团恢复的已验证实现是编辑页状态更新,而不是列表 cz=0。
  • 母团恢复为“收客中”后,C09 子单详情仍为“已取消”:母团取消会向下传播子单取消,但母团恢复不会反向恢复子单。子单必须在 406 元素/401 字段、16 行游客、零已记录应收和测试标记前置下,以 DoInfo_order 单独执行 danzhuangtai: 已取消 → 预订;HTTP 200“修改成功”并重开持久化。
  • C09 子单直接执行 danzhuangtai: 预订 → 已取消 后,HTTP 200 明确返回状态修改成功(同时提示应收款不能修改),重开子单为“已取消”;母团仍保持“收客中”,但母团已收统计由 15+1 降为 0。再次单字段恢复子单为“预订”后,子单重开、16 行游客/零应收和母团 15+1 统计全部恢复。order_cancel/order_restore 必须区分母团与子单影响范围,并明确母团恢复不级联。
  • C09 清理安排并完成母/子状态恢复后再次读取 10 类 source-only 响应,全部 HTTP 200、无登录/权限错误,且未下载、转换或发送。游客名单、备案当前和接机牌 hash 与安排态一致;客户确认、JOB、导游通知、酒店/票务预订单等依赖状态/资源的响应字节与 hash 发生预期变化。导出契约必须冻结“读取时生命周期状态”,不能假设同一订单的源文件恒定。
  • C09 删除前复合预检全部通过:母团“收客中”筛选唯一命中 tid 14384,账号/日期/产品/容量/子单引用一致;子单 ddid 14452 为“预订”、16 行游客、零已记录应收且住宿说明含测试标记;团队安排总表五类资源均为空;最终 10 类源证据冻结且无外部交付。页面原生删除函数确认子单为 Del_order(tID,did)、母团为 DelRecord(tID,txh),必须按子单后母团执行。
  • C09 子单使用精确 Del_order(tID=14384,did=14452) 后,HTTP 200 明确返回“操作成功”;母团重查仍唯一存在且保持“收客中”,但 D14452 引用消失、已收统计为 0。直接重开原子单 URL 返回空文档、无表单/marker/游客行,确认子单已删除;母团尚未删除。
  • C09 母团在子单已删除、五类安排为空、最终源证据冻结和精确 allowlist 条件下执行 DelRecord(tID=14384,txh=LW-260922A-A),HTTP 200 明确返回“操作成功”。散拼计划表使用全部状态、精确团号/日期/账号回查 0 个团队;团队安排表使用精确团号/日期回查 0 个团队。C09 已不可恢复,未触碰任何未入清单对象。

2026-08-10 — Agent 后插件桥接接管延迟修复

  • 目标任务 TASK-20260810141123-FhIriEc 的 Agent 解析在 22:11:57.285 完成,服务端自动确认在 22:11:57.957;ERP attempt 直到 22:14:03.265 才创建,间隔为 125.31 秒。
  • 对应浏览器连接的 bridge_installed_at 为 22:13:59.437,claim 在 bridge 重新安装后约 3.8 秒发生;主要等待位于页面 bridge 不可用/未及时唤醒,而不是 ERP 页面执行。
  • LianSyn-platform/app.js 现在在 bridge 从断开恢复、或 bridge_installed_at 变化时对仍处于 confirmed + awaiting_handoff 的自动任务强制触发派发,绕过此前的 30 秒本地重试冷却。
  • 自动派发失败提示不再把本地任务状态改成 waiting_extension;继续保留服务端权威的 confirmed + awaiting_handoff,避免 bridge 恢复后任务失去 claim 条件。
  • 服务端 claimForBrowser()、execution ID、写入前闸门及 claim 后不确定结果处理未修改;本轮不触发 ERP 写入。
  • 验证结果:前端/桥接 JavaScript 语法通过,TypeScript no-emit 通过,控制平面 28/28、既有业务/外部回归 71/71、git diff --check 通过;/health/ready 返回数据库/schema/AgentBus 正常。

2026-08-11 — 生命周期 v2 实现结论

  • operation-plans.js 与外部 Agent parser 已统一为 v2:live write 校验目标订单日期必须位于 2026 年 9 月,不再错误要求当前日历处于 9 月;所有既有对象引用必须带明确 kind、tid、对象编号、必要 ddid、出团日期、账号归属和测试标记。
  • passenger_list_import 已固定为 ERP 实测表头 NAME / 证件号码 / 签发日、first_import/full_replace 和精确人数;adapter 会按游客行定位电话,隔离接团/送机电话并在重开后逐行回查,禁止超行截断和错位后仍报成功。
  • 五类安排已拆为导游、车辆、酒店、大交通、其他/备案五个 adapter;资源引用、原生 action、必填日期/数量/房型与价格联动等待均按 C08/C09 事实基线编码,不允许将页面宽表直接解释为用户意图。
  • 三类更新使用对象专属窄白名单:独立团仅保留受安排历史闸门保护的单字段契约,散拼母团只允许计划容量,散拼子单只允许住宿说明;系统 ID、session、审计与派生字段均不进入用户载荷。
  • order_cancel、order_restore、order_delete 已彻底分离。列表 cz=0 因跨两类对象稳定无效而禁用;散拼母团恢复不级联子单;删除使用独立团、散拼子单、散拼母团三条精确原生路由及子单优先顺序。
  • confirmation_export 现在只读独立团或具体散拼子单源响应,记录 HTTP、类型、字节和 SHA-256,并显式返回 downloaded=false / converted=false / sent=false;母团引用会被前置阻断。
  • 浏览器下单在产品联动与客户唯一解析完成后执行条件式来源地兼容检查:只有产品中存在可识别地域词时才要求客户匹配;产品没有地域词时不凭空阻断。整个过程只读取业务页面候选,不进入主数据页面。
  • 新 lifecycle-adapters.js 不以本地 DOM 变更或 HTTP 200 空响应作为成功:必须识别明确服务端成功语义并执行 fresh GET/list/team-summary 回查;不确定状态停止且不自动重试。
  • 当前实现已通过控制平面 28/28、全量 JavaScript/契约 96/96、TypeScript、相关 JavaScript 语法、Schema/JSON、diff 和 4 个 Skill 快速校验。新 adapter 是依据真实原生基线编码,尚未作为插件 action 在浏览器内完整重放,因此发布门槛继续阻断。
  • 未解除的外部事实风险包括:C01 LW-260903A-A 存在非本账号财务账,禁止清理或删除;散拼批量创建仍保留 HTTP 500 未解决样本。两者不能由静态回归替代。

2026-08-11 — 最终安全审计新增事实

  • 散拼子单导出存在两级定位语义:母团号/计划号只负责搜索 /System/Business/plan.asp,具体 child_order_no 或 ddid 才是导出目标。若共用一个通用 identifier,ddid + 母团号 组合可能把母团误当目标;现已拆分并在 Planner、外部 validator、Schema、mapping、Skill、页面 adapter 和测试中统一。
  • 页面导出匹配从字符串包含改为边界明确的标识 token 或链接中的精确 ddid,只接受一个具体子单叶子行;传入 ddid/tid 与 ERP 列表解析值冲突时立即阻断。母团搜索引用缺失、父引用不存在、子行歧义、fetch 异常均返回结构化失败。
  • 删除授权不能使用“任一编号重合”判断;当前按对象 kind、tid、团/子单号和必要 ddid 全部相等后才视为 allowlist 命中,账号、日期和 TEST-202609 仍需同时一致。
  • lifecycle-result 的成功判定现要求 status=lifecycle_completed、明确 completed=true 的 2xx 服务端响应、fresh requery matched=true 且无需人工复核;HTTP 200 空响应或 completed=false 不再可能进入成功态。
  • 最终 0.5.8 包哈希为 c94de1be6d0cfd8956e57b78e54cb23bcee092cd26457bb8c40cf12c2a2fdf7d。本地 Chrome 仍登录且进程监听 9222,但 macOS 锁屏阻止窗口读取和调试许可;这属于运行环境门槛,不改变静态结果,也不能被静态结果替代。

2026-08-11 — 页面完整度与安排槽位安全审计

  • 原 adapter 只证明表单存在,未编码 C08 已发现的“314 字段半载页”风险;现在按原生 action 使用保守的实测下限(导游 14、车辆 140、酒店 195、票务 280、其他 250、独立团 800、母团 600、子单 350),并要求页面连续稳定 1 秒、无可见加载提示。名单导入检查父编辑页而不是只看导入对话框。
  • 五类安排此前默认写第 0 行但未证明该行为空,存在覆盖既有资源的理论风险;现在只允许 id0/资源隐藏 ID/yf0/审核状态/既有备注 证明为空或零的槽位,导游用 daoyouid0 单独判定。任何占用、付款、审核或备案冲突均在网络写入前阻断。
  • 供应商/资源选择后会触发 ERP 异步联动;现在等待字段稳定后再次核对隐藏资源 ID、item、日期和房型,再写数量、状态与测试备注。车辆备注被 set_price 覆盖的 C09 事实因此成为正式门槛。
  • 安排输入现在统一要求 2026 年 9 月日期、正数量/正间数,酒店离店日必须晚于入住日;Planner、外部 parser validator 与 JSON Schema 采用同一边界。
  • fresh GET 与团队总表回查增加 15 秒超时和结构化 fetch 错误;团队总表使用包含链接/控件的行证据文本证明账号和标记,避免只读可见文本遗漏隐藏引用。
  • 本地 Chrome 的 DevToolsActivePort 仍指向 9222,进程正常监听;但 ioreg 返回 CGSSessionScreenIsLocked=Yes,CDP 连接等待用户侧调试授权。该状态下不能进行插件真实重放,也不会尝试系统级解锁或绕过。
  • 本轮安全加固单独升级为 0.5.9,平台最低兼容版本同步提升,避免已加载的旧 0.5.8 在未重载时被误判为新实现。最终两个 ZIP 的 SHA-256 均为 9eb1befab6c839f9dcadc6dc6e254f30940910e15e4d967373b239d8a1462b44,18 个包内文件与源码逐文件一致。

2026-08-11 — 运营原文复核与 0.5.9 重放前差距

  • 已重新读取 /Users/inmanx/Desktop/运营梳理.rtfd/TXT.rtf 与其内嵌 ERP 截图。原文 10—21 的真实主线仍是:四条下单路线、独立/散拼名单、三类订单编辑与状态、五类安排、源文件读取;当前生命周期拆分方向与原文一致。
  • 原文对交通、酒店、车辆明确包含“已确认/未确认/出票/取消/已落实”、增加/减少用房、改住宿日期和更换安排资料。这说明五类安排不只需要空槽位创建,还需要对当前运行自有行的窄字段更新与清理;0.5.9 的 create-only adapter 尚不足以独立完成取消/删除前清场。
  • 原文列出的独立团修改字段很宽,但真实 C08 只证明状态恢复可写,普通说明字段在完整表单下仍返回空响应且未持久化;不得因原文罗列字段就提前开放宽表修改。后续必须在全新对象上按单字段、before/after 和 fresh requery 建立白名单。
  • 用户已明确指出产品与客户存在来源地兼容规则,例如产品含“广东”时客户也须匹配“广东/衡阳”来源。当前事实基线的产品 老挝行程--广东 8D7N 与客户 广东市场衡阳客户 确实匹配;实现应保留“可识别地域词时强制兼容、无法识别时不臆测”的条件式门槛,且只读取业务页候选。
  • 原文要求的 DOC→DOCX、提前两天自动导出与对外发送不属于用户已确认的本轮 source-only 阶段;本轮只证明源响应,不把读取源误报成下载、转换或发送。
  • 内嵌截图同时展示应收条目、航班/接送机和行程明细,确认这些属于订单编辑页的业务字段,而非客户、导游或供应商主数据;任何测试仍限 /System/Business/ 页面。
  • 2026-08-11 本轮再次检查 macOS,仍为 CGSSessionScreenIsLocked=Yes。Chrome/会话可保留,但锁屏期间不请求调试授权、不触发 ERP 写入;先完成契约差距修复。

2026-08-11 — 安排清理与来源地契约代码审计

  • 运行时代码 inpage.js、team-batch-inpage.js 已经执行正确的条件式来源地门槛:产品候选能解析出地域词时,客户必须匹配;产品无地域词时返回 applicable=false 而不阻断。矛盾主要存在于外部 Agent prompt、lwlt-newbooking 文档和旧证据说明,它们仍写成“来源地不参与阻断”,需要统一为实际规则。
  • 现有五类 arrangement_* 在 Schema、planner、validator、Skill 和 adapter 中均被建模为“空槽位 0 创建”,无法表达 C08/C09 已真实验证的精确清理。取消却要求 arrangements_cleared=true,因此当前插件本身不能独立证明并完成该前置,生命周期存在闭环缺口。
  • C08/C09 已提供清理原生事实:非导游资源保留当前行 ID,清空资源、item、日期、数量、状态和备注后由相同 DoInfo_* 删除活动行;导游清空团队引用;所有目标均要求测试标记、未确认、付款引用 0、未审核。其他成本行清除时必须保留备案对象。
  • 清理可以继续复用现有五个正式 action,以 data.arrangement.mode=create|clear 区分,不需要新增另一个宽泛 action。clear 必须在精确业务页重新证明当前槽位的资源 ID、测试备注、未确认、零付款/未审核,并以 before hash 锁住载荷;它不能接受任意覆盖或主数据删除。
  • 当前 formRequery() 要求每个修改字段在 fresh GET 后仍存在并等于 after 值;资源行删除后槽位会动态收缩/字段可能消失,因此清理需要单独的 absence-aware 子页回查,再组合团队总表回查。不能把普通字段相等回查直接复用为删除证明。
  • 酒店/车辆/交通等既有行的业务更新在原文中有需求,但目前没有像“清理”一样的真实原生 before/after 证据;本轮先实现已证实的 clear,update 继续阻断,待新测试对象逐项实测后再开放。
  • create|clear 最小契约已落入 planner、外部 validator、Schema 和页面 adapter:clear 仍携带创建时的精确资源、日期、数量、状态和测试备注作为 before 断言;非导游必须另带原生 row_id,其他/备案必须声明并回查 preserve_filing=true。
  • adapter 清理时保留原生行 ID 与付款/审核字段,只清空当前测试行的资源、日期、item、数量、派生金额、状态和备注;导游只清团队引用。fresh GET 采用目标行 ID/资源 ID/测试备注均消失的 absence proof,其他备案逐字段保持,再与团队总表组合回查。
  • 针对性生命周期契约已由 14/14 增至 15/15;新增覆盖 vehicle/guide/other clear、缺 row_id、备案误删、非法 update mode 和 adapter 删除感知标记。三份修改脚本语法均通过。
  • JSON Schema 现进一步在 action 级约束非导游 clear 必须有 target.row_id,arrangement_other clear 必须同时有备案快照和 preserve_filing=true;Planner、外部 validator 与 Schema 三层对非法 clear 一致失败。
  • 来源地规则的反向描述已从外部 Agent contract guidance、lwlt-newbooking 主 Skill 和三个引用文档中清除。Agent 不虚构/追问来源地,但插件必须按最终 ERP 唯一候选执行条件式兼容校验;旧证据登记也已改成当前真实运行语义。
  • 清理写入还增加了异步联动防护:第一次清空资源/日期/数量/金额后等待页面稳定,再次清空可能被 set_price 回填的字段并验证关键字段保持空;原生 row ID 始终保留,付款/审核字段不修改。
  • lwlt-arrangement 的 UI 元数据已按 skill-creator 规范更新为 create/clear 契约,且恢复既有 implicit invocation 策略;五个相关 Skill 均通过 quick validation。
  • 0.5.10 全量回归为控制面 28/28、全部业务/契约 97/97;两个当前 ZIP 的 SHA-256 均为 13841e0e02451eb1577ebcb7f80004fd9ba2bfdfaa8ef8cb54ab4f4a57adae05,18 个文件与源码逐一一致。

2026-08-11 — 0.5.11 回放编排与契约审计结论

  • 旧 live input 含过时引用,不能安全复用。新的 replay-state.template.json 只保存运行参数和已知业务候选,真实对象引用必须由每一步服务端回执和 fresh requery 回填;生成器拒绝覆盖既有输出目录。
  • 四条创建路线现在都有显式 2026 年 9 月日期和 TEST-202609-R0511 host suffix。标准 Schema 允许 suffix-only,因为团号前缀必须由 ERP 产品/线路联动生成;普通 lwlt-newbooking Agent 仍禁止自行输出 order_number 或测试标记。
  • 独立单个、独立批量和散拼母团运行时都在产品联动后应用显式 suffix,并在提交前验证最终字段完全一致。批量路径的批准 payload hash 和单个路径的预检一致性会阻止后续页面联动静默覆盖该 suffix。
  • 来源地 helper 原先在直接调用时把“产品没有地域词”返回为失败,虽然页面包装层会提前放行;这会让未来 adapter 复用产生假阻断。底层现统一返回 ok=true, applicable=false, reason=product_has_no_source_region_token,而广东产品 + 无地域客户仍明确阻断。
  • receivable_fixture 曾只存在校验字段、没有真实执行 adapter,存在被误认为已执行的严重风险。当前三层契约均 fail closed;C09 原生零额清理不能替代新对象 0.01 新增/清零基线。
  • 回放生成器把清理依赖编码为证据门槛:8 个非导游 row ID 齐全后才生成五类 clear;安排和应收均清理后才生成取消/恢复;导出证据冻结、删除授权和 allowlist 齐全后才生成删除,并强制子单先于母团。
  • 控制面审计发现外部 parser 可携带 source.test_context.allow_live_write=true,而 AgentBus 自动确认原本没有区分生命周期测试 action。现已改为入库前强制剥离写权限、生命周期 action 永不自动确认;管理员手工确认时由服务端重新核对运行 ID、AI 测试账号、TEST-202609、2026 年 9 月日期、精确 created ref 和删除证据,再对该次加密 operation 注入写权限。平台确认界面同步显示 action、目标引用、日期和测试上下文,避免盲确认。
  • 控制面原先只把传统团号/订单号回执视为完成证据,即使 lifecycle adapter 已返回明确服务端成功和 fresh requery,也可能被错误降级为 reconciliation_pending。现已统一:写操作要求 server_response.completed=true、requery.matched=true、无 blocker 且无需人工复核;source-only 导出另要求哈希冻结。缺证据继续失败关闭。
  • 回放顺序已按真实生命周期校正为“名单 → 安排 → 修改 → 导出”;独立团因已实证存在安排历史后普通修改静默失败,单独保留安排前 arrangement_history=false 条件探针。散拼母团和子单修改均排在五类安排后。四条创建路线的每个成功/回查命中对象(含批量逐日期)必须进入 cleanup.objects,最终预期最多清理 9 个对象。
  • 当前静态结果为业务/插件/外部解析 106/106、控制平面 32/32、TypeScript、全部相关 JS/MJS、关键 JSON 和 5 个 Skill 全部通过。0.5.11 扩展包为 18 文件且与源码逐一一致,SHA-256 fc47fceab8d1d2ce8a11f948f502ebbc345d420be7a0a34b4cbde872b57a6cf1;lwlt-newbooking.skill SHA-256 ac54e7b286e1a0000e202c3ea7d7ef77d6dcc1c4f20eb22a2e932fef94423edf。
  • Chrome Profile 2 的 Secure Preferences 证明 unpacked 扩展仍从当前工作区目录加载;但源码版本更新后必须由 Chrome 重新加载才能生效。当前 Computer Use 仍明确返回 Mac locked,CDP 等待一次性“允许调试”授权,真实 ERP 重放尚未开始。
  • 本轮专用 replay-state.live-20260811-r0511-01.json 已生成 4 个创建 operation 并通过三重契约校验,但这些文件没有被提交给 ERP。证据表和 allowlist 当前均保持 pending/disabled;最后一次 ioreg 仍为 CGSSessionScreenIsLocked=Yes,所以不能宣称 0.5.11 的安排、修改、导出、应收或删除已经真实重放。

2026-08-11 — 已登录 Chrome 通道恢复事实

  • ioreg 当前不再返回 CGSSessionScreenIsLocked=Yes,控制台用户为 inmanx;Chrome 9222 监听和控制面健康检查同时通过。
  • CDP 已列出 ERP 与 AI 操作台两个既有页签,且 ERP accessibility snapshot 明确显示“测试ai员工账号”处于登录态。
  • 当前页面同时显示合作商管理与财务操作入口,但执行边界不变:只允许 /System/Business/ 下的业务订单操作,不进入客户、导游、供应商主数据或财务根目录。
  • 通道恢复只证明可以开始真实重放,不代表插件 0.5.11 已重载,也不代表任何 R0511 对象已经创建;这两项必须分别以扩展版本回执和 ERP 服务端写后回查证明。
  • Chrome 扩展页当前显示工作区未打包扩展版本为 0.5.11 且已启用;仍需点击该扩展的“重新加载”并让 ERP/平台页面重新注入,避免旧 Service Worker 或旧 content script 继续存活。
  • chrome://extensions/ 的目标扩展卡片可由固定 ID kafggjjlhebccdgkechmbgflkaifkccf 唯一定位,重载控件为其 shadow root 内的 #dev-reload-button;可以精确点击而不影响其他扩展。
  • 目标扩展重载操作已真实执行,重载后页面仍报告 0.5.11 且启用;这证明 manifest/扩展注册状态正确,但 content script 与页面 bridge 仍须通过 ERP/平台刷新后的运行时 PING 单独证明。
  • 扩展重载后的 ERP Page.reload(ignoreCache=true) 成功;AI 操作台目标首次接入返回 Daemon failed to start — did you click Allow in Chrome?。CDP 的调试许可按页签分别确认,不能把 ERP 页签已授权等同于平台页签已授权。

Errors encountered

  • 2026-08-11:刷新 AI 操作台页签时 CDP 守护进程未获该页签的“允许调试”许可;未重试任何 ERP 写入,等待用户点击该页签提示后仅重做页面刷新/PING。
  • 用户完成平台页签调试许可后,CDP snapshot 成功;平台仍保留 5 个历史 completed 任务且当前插件状态为“未连接”,符合扩展重载后平台尚未刷新/重注入的预期,不是 ERP 登录失效。
  • 平台刷新后的 pingBridge() 返回 connected=true、compatible=true、automationEnabled=true、version=0.5.11,且 bridge_installed_at=2026-08-11T02:01:24.159Z;这是实际 content script 新注入的运行时证据,不只是扩展页 manifest 文本。
  • 为防止四条正式创建 action 被 AgentBus 自动确认,平台组织设置已临时从 enabled 改为 disabled;因此 C01 解析通过后必须停在人工 operation 审核,确认前 ERP 不应有写入。
  • C01 使用平台自身的任务创建函数提交,而非直接调用扩展 CREATE_TASK 或绕过 claim;任务 ID 为 TASK-20260811020415-knTEfuA,可据此核对解析、确认、claim、回执和 ERP 写后回查完整链路。
  • C01 在提交后约 9 秒仍处于 parse_running,这只是外部 Agent 正常异步解析状态;自动化已关闭且 operation 尚未生成,ERP 写入边界尚未跨越。
  • 一次用 15 秒页面内 setTimeout 等待轮询触发 CDP Runtime.evaluate 超时;没有状态写入或 ERP 副作用,后续改用短时外部轮询。
  • C01 外部 Agent 能识别“宿主注入字段”并原样保留 order_number.suffix=TEST-202609-R0511。解析结果补入标准 passenger_list=none、空附件和系统默认值,同时省略输入中的 special_requests/expected_total;核心创建字段未发生歧义或改写。
  • C01 的正常平台审核按钮在任务同步后为可见且可用,文本为“确认并提交到 ERP 插件”;点击动作已执行。自此必须以 ERP 原生响应和写后回查决定结果,任何超时都不能自动重提。
  • C01 插件预检证明客户、产品、OP、销售均为唯一候选;产品地域词为“北京”,客户兼容检查通过。原生表单为 822 个序列化字段,提交哈希一致后仅执行一次 DoInfoJH。
  • C01 原生回执为“下单成功”,团号 LW-260912TEST-202609-R0511-A、产品 北京直飞--七晚九(SH)、人数文本 15+ (0+0+0) +1;插件回到列表并命中标识。创建 action 使用既有 erp_receipt + verification 成功结构,尚未迁移成生命周期 action 的 server_response + requery 结构。
  • C01 的 ERP 列表行 ID 为 tr_14385,修改/删除路由使用 ddid 14453,因此本轮精确对象引用为 independent_order / tid=14385 / ddid=14453 / LW-260912TEST-202609-R0511-A。列表行明确显示账号“测试ai员工账号”和 2026-09-12,可安全纳入本轮清理集合。
  • C02 输入明确同时提供日期范围和仅三个 specified_dates,用于检查 Agent/批量表单不会把范围内其他日期隐式选中;在 operation 审核前没有 ERP 副作用。
  • C02 Agent 输出同时保留 departure_dates=[09-04,09-08,09-29] 与 recurrence.pattern=specified_dates,未把 09-04 至 09-29 展开为连续日期;宿主 suffix 也未丢失。
  • C02 确认后的首个状态明确停留在批量 preflight,原生网络提交尚未发生;这允许在载荷/日期选择不一致时安全失败关闭。
  • C02 批量原生回执返回“共计新增 3 个团队”,三个指定日期各产生且只产生一个带 R0511 后缀的团号;插件逐标识回查 byte_length 3755/3755/3756,marker_occurrences 均为 9。
  • C02 完成后 ERP 可见主 iframe 仍保留 C01 的 09-12 精确过滤,因此不能从当前 DOM 直接取三条批量对象 ID;下一步使用与插件相同的只读业务列表查询逐标识解析,绝不重复提交批量创建。
  • 逐标识 POST /System/DAT/orders.asp?Act=JH_OrderList 的 HTML 片段起始即含原生 <tr id=tr_tid ondblclick=OPEN_update(ddid,...)>:三条分别为 14386/14454、14387/14455、14388/14456。这是只读业务列表查询,与插件成功回查使用同一路由。
  • C03 输入保持母团和子单职责分离:shared_plan_create 只有产品、日期、容量、房型、母团数和宿主 suffix,不把后续广东客户提前塞入母团可选字段。
  • C03 Agent 省略显式 groups_per_date=1,但 planner/adapter 对缺省值固定解释为 1,审核视图也解析为 1;customer/split_order.customer 均不存在,未虚构客户。
  • C03 确认后的初始运行态明确没有写入,先进入散拼母团页面执行;这与独立团批量的 preflight 路径不同,仍须等原生响应和母团列表回查后才能记成功。
  • C03 在平台结果仍是 write_attempted=false 时,ERP 可见页面已经出现目标母团行,说明页面/回执上报存在短暂时序差;此状态必须视为“可能已写入”,只能回查,绝不能因为控制面状态滞后而重新提交。
  • 直接向 0.5.11 bridge 查询 GET_CURRENT_TASK/GET_TASK_RESULT 显示当前 C03 execution ID 一致,但任务缓存仍 queued、结果仍 browser_execution;卡点位于扩展执行/结果收敛层,而不是平台数据库展示延迟。
  • Target.getTargets 显示扩展 Service Worker background.js 正常存在且未被页面调试会话附加;内置 cdp.mjs eval 会拒绝非 page target,因此需要浏览器级扁平 session 只读诊断,不能靠重载扩展(重载可能中断当前不确定任务)。
  • 浏览器级诊断第一次因把 DevToolsActivePort 第二行(已是完整 path)再次拼接 /devtools/browser/ 而超时,修复后连接成功;第二次 Target.getTargets 已找不到 Service Worker。结合当前任务永远停在 browser_execution,可推断(待进一步证实)MV3 Worker 在长异步页面操作期间被挂起/终止,内存中的 Promise 与最终 publish 未执行。
  • business-bridge 的 PING 完全在 content script 内处理,只读 manifest/storage,不会向 background 发消息;因此 PING 成功不能证明 Service Worker 存活,也不能恢复中断的 runAutoTask。
  • Worker 持久化 execution 证明 C03 在 02:17:31 已完成:write_started → submitted → completed,原生回执团号 LW-260916TEST-202609-R0511-A,计划16、TWN8,来源 erp_response;verification 唯一行 parent_group_found。因此先前“Worker 中途终止”的推断被新证据修正:Worker 可能在完成后正常休眠,真正缺陷是平台 polling 未把已存储终态提交控制面。
  • 诊断还发现 runningTasks=[] 且 execution state=completed,所以现在可以安全调用平台既有 pollTaskResult() 只取回/持久化结果;不得重新 claim 或执行 C03。
  • C03 结果回收后控制面成功回执完整,说明插件 publish/setResult 本地终态本身正确;平台自动轮询在 Worker 完成/休眠时漏了一次最终 GET_TASK_RESULT,需要在后续代码修复中增加服务端 running 任务的稳健终态补拉。
  • C03 散拼母团精确引用为 shared_plan / tid=14389 / LW-260916TEST-202609-R0511-A;母团没有 ddid,列表 [拼单] 原生入口为 OPEN_update('14389',0),后续 C05 必须以此母团唯一引用创建具体子单。
  • C04 作为同一 shared_plan_create 的多日期路径提交;历史 HTTP 500 风险已显式保留,任务一旦跨越 write_started 就禁止重新下发,结果按 09-06/10/24 分开登记。
  • C04 Agent 未扩大日期集合,也未把后续子单客户放入母团;审核结果与生成器 004 输入在核心业务字段上等价。
  • C04 初始运行态与 C03 相同,尚未越过写入;后续将优先检查 Worker 持久化终态,避免后台页计时器节流造成“任务仍 running”的假象。
  • C04 的显式 pollTaskResult 当前仍只取到 running,而不是像 C03 那样取到本地 completed;多日期 shared-plan 在捕获响应后还要逐团搜索/可能执行 reconciliation,20 秒尚不足以判定卡死。
  • C04 当前可见页是 09-10 精确目标而非原 C03 09-16,说明 createSplitParentLive 正在按返回团号逐个调用 searchMainPage;每次搜索会改变列表 DOM,不能用单次当前页缺少另两个日期判定未创建。
  • C04 当前页由 tid 14391 的 09-10 行推进至 tid 14392 的 09-24 行,符合三个返回团号顺序回查的第三步;长达约 50 秒主要来自页面逐次 1 秒搜索加导航/后台节流,而不是重复写入。
  • C03 单日期同路径从 write_started 到 submitted 实际约 109 秒,说明浏览器后台标签的 JavaScript timer 节流会显著延长 captureAjaxSubmit/searchMainPage;把 ERP target 激活是只改变可见性以促成已有 Promise 完成,不是业务重试。
  • C04 最终原生团号为 LW-260906TEST-202609-R0511-A、LW-260910TEST-202609-R0511-A、LW-260924TEST-202609-R0511-A,三个 response verification row 均命中;历史 HTTP 500 未复现,本次 receipt_source=erp_response。
  • 散拼计划只读列表的原生 action 是 SP_OrderList;SearchForm 当前仍保留总日期范围 09-06 至 09-24 和最后一个精确团号,可通过同路由 POST 解析三条 tid 而不改页面或触发业务写入。
  • C04 SP_OrderList 返回的 <font id=td1_tid> 与 OPEN_List(...,tid) 双重证明三个母团 tid=14390/14391/14392;所有片段均显示账号“测试ai员工账号”。
  • phase2 生成器只在已知 C03 母团后增加 shared_child_order_create,existing_refs 为母团号+tid,未提前生成名单/安排等依赖具体子单 ddid 的操作,依赖门槛工作正确。
  • C05 外部 Agent 解析比前三个任务慢,但当前状态仍是正常 parse lease 内;没有理由旁路或直接把生成器 operation 发送扩展。
  • C05 首次外部解析在约 50 秒后被外部服务取消,operation 始终为空,error_code=external_cancelled、failure stage=external_parse_request;这是解析层确定无写故障,可新建一次等价解析任务,但不能改用直接 extension dispatch。
  • 重试前 /api/status 证明 AI reachable/authenticated 且 AgentBus session_ready;新输入缩短说明但保持 parent group/tid/date/customer/15+1/test marker 全部事实不变。
  • 第二次 C05 当前没有再次取消或校验错误,只是 Agent 响应尚未返回;等待同一 parse lease,不创建第三个任务。
  • 连续两个 C05 请求都比创建母团解析明显更慢,可能与外部 Profile 对新 shared_child_order_create 路由/Skill 调用有关;在拿到最终错误前仍不能断言契约问题。
  • 两次 C05 trace 均精确在 SSE stream_connecting 后约 120 秒取消,event_count=0、recovery_count=0、contract_repair_count=0。Agent 从未返回 token,因此不是 operation Schema 校验失败;优先检查客户端 AbortSignal/超时配置和远端 Profile 对该业务的响应时间。

Errors encountered

  • 2026-08-11:C05 首次 Agent 解析请求被外部服务取消;控制面 fail-closed 为 parse_failed,明确 no plugin/no ERP。保留失败任务证据,准备一次安全解析重试。

Errors encountered

  • 2026-08-11:首次调用 ServiceWorker.startWorker 返回“ServiceWorker domain not enabled”;随后仅启用该 CDP domain,未触发 ERP 或扩展任务执行。

Errors encountered

  • 2026-08-11:尝试用标准 cdp.mjs eval 直接读取 Service Worker 时返回“No target matching prefix”;该工具仅列 page target。未重载扩展、未改变任务或 ERP 状态。
  • 2026-08-11:新 Worker 诊断工具首版错误重复拼接 DevTools browser path,连接 5 秒超时;已改为直接使用 DevToolsActivePort 第二行。随后连接成功但 Worker 已不在 target 列表,工具安全退出,未写浏览器状态。

Errors encountered

  • 2026-08-11:首次尝试将 C01 引用写入 state/allowlist 时,生成的 patch 多行插值缺少逐行 + 前缀,apply_patch 在修改前验证失败;随后改为显式补丁,未产生部分写入。

2026-08-11 — C05 散拼子单解析契约断点

  • 两次 C05 请求都在 external_parse_request 的 SSE stream_connecting 阶段约 120 秒被取消,event_count=0,因此没有进入 operation Schema 校验,也没有触发插件或 ERP。
  • 根 .env 的 PARSER_REQUEST_TIMEOUT_MS=120000 与两次取消时间一致;但更直接的业务断点是 lwlt-newbooking 主 Skill、action 表、归一化、输出契约和示例都只覆盖三个新增 action,遗漏 shared_child_order_create。
  • business-adaptation-registry.md 已把 shared_child_order_create 标为支持,却链接到不存在的 businesses/shared_child_order_create.md;business-behavior-registry.md 也没有散拼子单创建的自然语言路由行。
  • 平台 buildParserMessage() 虽列出四个 action 名,却没有给出散拼子单字段契约;插件 planner 和根 Schema 已支持该 action。修复应聚焦解析/Skill 层,保持正常平台人工确认链路,不直接派发扩展。
  • 补齐字段契约并重启控制面后,第三次 C05 在约 53 秒返回 shared_child_order_create,证明远端 Profile/通道可用且前两次并非 ERP 问题;母团号、tid、日期、客户和 15+1 均正确。
  • 第三次结果丢失原文中的 TEST-202609 子单备注。由于子单没有母团 suffix 可作为自身标记,不能确认该 operation;现已在 Skill、parser validator、planner 和 Schema 增加条件闸门:测试母团号含标记时,data.special_requests 也必须保留同一标记。
  • 系统 Python 没有 jsonschema 模块,首次语义校验命令只读失败;改用项目现有 Ajv 2020 验证,标记完整的 C05 fixture 通过、删除 special_requests 后按预期失败。
  • 最终标记完整的 C05 首次插件执行安全阻断为 parent group not found on split plan list,明确 write_attempted=false/no_erp_write=true;任务没有产生子单或半成品。
  • 阻断后只读 ERP 页面在同一搜索条件下唯一显示目标母团 LW-260916TEST-202609-R0511-A / tid=14389。这证明原固定 1 秒等待早于 Ajax 列表渲染完成;同时旧 adapter 没有使用输入 tid 做交叉核对。
  • 0.5.12 将子单母团定位改为最多 10 秒稳定轮询:优先 tr_<tid> 且精确团号匹配,否则只接受唯一叶子行;解析出的 tid 必须与输入一致。保存后的具体子单回查也轮询到子单号出现在目标母团行,超时仍失败关闭且不重试写入。
  • 扩展已精确重载为 0.5.12,ERP/平台忽略缓存刷新后运行时 PING 为 connected/compatible/automationEnabled=true、version=0.5.12;组织全自动化仍为 false。

2026-08-11 — 名单导入真实路由阻断与原生页面事实

  • C05 已由 0.5.12 真实创建为散拼子单 D14457(母团 tid 14389、ddid 14457);原生 DoInfo_order HTTP 200 返回“下单成功”,母团行内具体子单 fresh requery 命中,已登记 state、evidence 与删除 allowlist。
  • P01 独立团名单任务经平台正常解析和人工确认后,在插件 preflight 明确失败关闭:当时主业务页仍为 /System/Mainlt.asp,不存在 DaoruText、导入弹窗父窗口或 ListForm;结果为 write_attempted=false、no_erp_write=true,ERP 名单未改变。P02 仍停留在人工确认前,未下发插件。
  • 根因不是名单数据,而是生命周期 adapter 假设操作者已手工打开目标弹窗;background 在所有 frame 直接执行 preflightLifecycleOperation,没有按 existing_refs 导航到精确订单。该行为无法满足插件自主复现 ERP 原生操作的目标,必须增加失败关闭的 route preparation。
  • 独立团原生只读路径已实测:进入 /System/Business/orders.asp,按出团日和精确团号检索,唯一行 tr_14385 的修改入口是 OPEN_update('14453','0','LW-260912TEST-202609-R0511-A');随后打开 /system/Business/orders_add.asp?...ddid=14453,完整 ListForm 含 1018 个控件与 16 行游客,原生名单入口为 DaoRuLie('全部','')。
  • 原生名单弹窗是编辑页内部的 /System/Business/daoru.asp?ziduan=全部 frame;字段为 textarea#DaoruText,确认按钮原生调用 frameElement.api.opener.DaoRuDones($.trim($('#DaoruText').val())) 后关闭。弹窗的直接 parent 是目标订单编辑页,存在 ListForm、DaoRuDone 和 DaoRuDones。本次只打开和读取弹窗,没有填写或点击“确定导入”。
  • 路由修复应先在主业务 iframe 精确检索,再从唯一目标行调用原生修改入口,等待完整编辑页,最后调用原生导入入口;任何团号、tid、ddid、账号、日期或页面路径不一致都必须在写前阻断。不能靠人工预先把 ERP 停在正确弹窗来掩盖插件缺口。
  • 散拼子单原生只读路径也已确认:/System/Business/plan.asp 精确母团行 tr_14389 内,具体子单链接文本包含 D14457,onclick 为 OPEN_update(14389,14457);打开 /system/Business/plan_order.asp?tdid=14389&ddid=14457 后,完整 ListForm 有 407 个控件和 16 行游客,名单入口同样是 DaoRuLie('全部','')。该路径不能误点母团行的 [拼单](OPEN_update('14389',0))。
  • 团队安排列表的真实入口是 /System/Business/teams.asp。精确团队行 id 为 data_tr_<tid>,C01 行内五类入口分别为 OPEN_dao(14385)、OPEN_jiu(14385)、OPEN_che(14385)、OPEN_piao(14385)、OPEN_qita(14385),对应 /teams_daoyou.asp、/teams_jiudian.asp、/teams_cheliang.asp、/teams_piao.asp、/teams_qita.asp;页面都在业务操作根目录内。
  • 当前空安排页的完整表单规模与旧安全下限不一致:导游 14、车辆 99(MaxI=3)、酒店 442(MaxI=16)、大交通 130(MaxI=5)、其他/备案 135(MaxI=5)。旧 FORM_READINESS_MINIMUMS 把车辆/大交通/其他分别写成 140/280/250,会把真实完整页面误判为未加载;应改为“动作必需控件 + 当前 MaxI/slot0 + 稳定 1 秒 + 无 loading”主判据,并把绝对下限校准到实际最小完整表单。
  • 五类业务页都提供原生候选 data,无需进入导游、供应商或酒店主数据。当前只读候选中存在可唯一匹配且适合测试态的低额/零额资源:酒店 万象未确认/947/【TWN】(0)、大交通 机票成本/1220/控位-包位联运票损(0),大交通三元组在页面中精确计数为 1;其余资源继续逐页复核唯一性后写入 replay state。
  • 一次将四个安排页串行读取放在单个 CDP evaluation 中超过工具执行时限;页面只发生 GET 导航且最终停在其他安排页,没有任何表单提交。随后改为逐页导航和短读取。
  • 已在实际业务安排页逐项确认本轮五类资源唯一性:导游 11/LW张居雄 为 1 个 ID+名称候选;车辆 386/对应车队/25座…返程190 为 1 个三元组;酒店 947/万象未确认/【TWN】 为 1 个零额三元组;大交通 1220/机票成本/控位-包位联运票损 为 1 个零额三元组;其他 1347/代收代付/代收代付(人民币) 为 1 个零额三元组。这里只读取业务页候选,没有改主数据。
  • 本轮 replay state 已写入上述精确候选,并为两类团队分别使用合成备案号 99091285、99091689。adapter preflight 现会在目标安排页重新计算 ID+名称(+项目) 精确计数,候选变化、缺失或多选都在保存前阻断。

2026-08-11 — 0.5.13 路由修复与发布候选事实

  • inpage.js 已加入 prepareLifecycleOperation:插件先从当前业务根页按 kind/tid/ddid/对象编号/departure_date/owner_account/marker 唯一定位,再调用 ERP 原生入口进入目标编辑页或安排页;任何引用不一致均在 adapter 写入前阻断。
  • background.js 对所有 browser_lifecycle_test 强制先执行 route preparation,并保存 lastLifecycleRoutePreparation;路由不就绪时返回 no_erp_write,不会把错误留给后续保存阶段。
  • 名单路由覆盖独立团和具体散拼子单;散拼母团不能代替叶子子单。五类安排路由只使用 /System/Business/teams.asp 行内原生入口,不访问客户、导游、供应商、酒店等主数据模块。
  • 安排候选的唯一性由实页重新计算:导游要求 ID+名称,其余要求 ID+名称+项目;radio 写入改为选择目标项,不再尝试修改 radio 的 value 属性。
  • 完整回归为 127/127;扩展发布候选与源码一致,0.5.13 两个 ZIP 的 SHA-256 为 e64f4f40a33e7324dbb4e5f149c36963391c18c4616019e5f0cf18efdc4b5c51,安排 Skill 包 SHA-256 为 83b9a92f3f6b590b2cff4f0be49389e5608187f575807bcc7d868decd8fd9de7。
  • Chrome 尚未在此检查点重载 0.5.13;因此上述结论是静态实现和构建事实,真实运行时能力必须以扩展重载、平台 PING、服务端响应与 fresh requery 继续证明。

2026-08-11 — 0.5.13 P01 实页阻断与 0.5.14 修复事实

  • Chrome 0.5.13 runtime PING 已真实返回 connected/compatible=true、version=0.5.13;ERP 登录账号为“测试ai员工账号”,组织全自动化按钮为“已关闭”。
  • P01 TASK-20260811034431-TwHYg2o 的外部解析结果与 fixture 一致:16 行 SHA-256 3416b22335b244bdc72fd5be89740089ae614f063637a42a0cafeace26d7fd8f,精确引用 tid=14385/ddid=14453,16 个证件唯一、16 行均含 marker。
  • 人工确认后,route preparation 已真实打开 /orders.asp 唯一行 → /orders_add.asp?ddid=14453 → /daoru.asp;持久化 route report 为 lifecycle_route_ready,账号、日期、tid、ddid 与团号均匹配。
  • 第二阶段 adapter 仍在写前阻断。实页诊断证明两个 blocker 都是假阳性:art-dialog 已加载 iframe,但可见父容器的 textContent 继承隐藏 .ui_loading 的 loading...;订单编辑表单包含正确隐藏 tdid=14385、ddid=14453,却不展示完整列表团号。
  • 该任务最终结果为 blocked/lifecycle_preflight、write_attempted=false、no_erp_write=true,所以允许在修复后建立新 execution;没有名单保存、半写或不确定写入。
  • 0.5.14 仅以节点直接文本识别通用 loading 文案,并在完整业务编号不可见时要求匹配的稳定数字引用(tid + 必要 ddid);数值不一致仍保留 mismatch blocker,不能靠模糊文本放行。
  • 0.5.14 完整回归为 127/127;扩展包与别名 SHA-256 均为 1d093344f5713f1f7cb4e3717d04570583fe24d02080bb90d3aef67b8d66b9a0,18 文件、manifest 0.5.14、源码逐文件一致。

2026-08-11 — 0.5.14 ownership 假阻断与 0.5.15 原生请求事实

  • 0.5.14 P01 TASK-20260811035706-Bg6i-88 已证明 loading、表单完整度和稳定数字身份修复生效:目标 frame form_readiness.ready=true、1015 个成功控件、16 行游客、无 loading signal。
  • 唯一剩余 blocker 来自 ownership proof:旧实现把 Act=JH_OrderList 放在 POST body,并发送不存在的裸 wode=0;ERP 返回 HTTP 200 空列表,因此 marker/account/tid/ddid 都随之假失败。任务仍在保存前结束,write_attempted=false/no_erp_write=true。
  • 实际独立团 SearchForm.action 为 /System/DAT/orders.asp?Act=JH_OrderList,散拼计划为 /System/DAT/plan.asp?Act=SP_OrderList;原生 body 字段是 riqi、日期、S_fabudanwei、S_tuanxuhao 等,S_wode 仅在复选框选中时出现,不存在裸 wode。
  • 用 0.5.15 修正后的 URL/body 做只读 POST,独立团目标返回 HTTP 200/3838 bytes,团号9次、tid15次、ddid7次、测试账号2次,证明 ownership 目标行可被原生契约稳定取回。
  • 0.5.15 全量回归 127/127;两个扩展 ZIP 为 18 文件、manifest 0.5.15、源码逐文件一致,SHA-256 35aeaff18fcd422096c2176a362221fd859f6e84a3ade3c52db9464b48a01ce6。

2026-08-11 — ERP 裸 <tr> 解析事实与 0.5.16

  • 0.5.15 ownership 请求已经与原生表单一致;原始响应 HTTP 200/3838 bytes,团号出现9次。但响应从裸 <tr id=tr_14385> 开始,直接 DOMParser.parseFromString(text, 'text/html') 会按 HTML 纠错规则丢掉 tr/td 外壳,解析结果 tr=0,因此 exactRowForIdentifier 假报 not found。
  • 把同一响应包入 <table><tbody>...</tbody></table> 后得到唯一 tr_14385,完整团号、账号、tid 和 ddid 都可从该行及其控件/onclick 证明。team summary 同样可能返回裸行,因此共用同一解析 helper。
  • 独立团编辑页 fresh GET 不渲染完整团号,但 ListForm 隐藏字段保留 tdid=14385/ddid=14453,操作员值也在隐藏/文本控件中。0.5.16 的 detail identity 要求完整编号文本或匹配的稳定数字 refs,任一数字不一致仍失败关闭。
  • 当前页面只读注入 0.5.16 adapter 逻辑后,P01 目标 frame 预检已返回 lifecycle_preflight_ready:1015 控件、16 行、无 loading;ownership 的 identifier/marker/account/tid/ddid 全部 matched=true。
  • 0.5.16 完整回归 127/127;扩展 ZIP 与别名均为 18 文件、manifest 0.5.16、源码逐文件一致,SHA-256 61f6fef70a5bcad86f4a7c6371c40717aa60fb8a31d050523b22f589cd5205e4。

2026-08-11 — P01 已写入后的只读回查与残留 art-dialog

  • 0.5.18 P01 TASK-20260811044534-vmFV080 已越过写入边界:DoInfoJH HTTP 200,响应“修改成功”,payload SHA-256 51da29c3aa40476d605bb5d38d30b24eebe339a4d56804e55b5619ab90b097f5;fresh GET 为 16 行且 16 行均含 TEST-202609。唯一差异是 ERP 将三个日期字段持久为不补零的 YYYY-M-D。
  • 0.5.19 已把日期投影校准为 YYYY-M-D,并增加只读 reconciliation 路径;原服务端成功回执和唯一 execution 保留,禁止再次调用保存。
  • 第一次只读回查路由返回 passenger_list_exact_row_not_found_or_ambiguous:2。实页 DOM 证明两个文本候选分别是残留 art-dialog 标题和真实 tr_14385;只有后者包含订单业务 action。该次只导航/读取,无 ERP 写入。
  • 0.5.20 的唯一行 helper 只接受原生 ID 行或含业务 action 的行,同时用于团号和 ddid 定位,保留父子嵌套叶子行消歧逻辑。
  • 0.5.20 全量门槛通过:TypeScript、控制面 32/32、业务/插件/解析 97/97、JS/MJS 语法、44 个 JSON、5 个 Skill 和 diff。18 文件发布包与源码一致,SHA-256 01a8ff40f53254e24334b8cc88f0271a1f3a8c2c83c9bd1476ac1fad1118c492。
  • 0.5.20 路由修复后,各 frame 只读执行结果证明真正业务证据已经匹配:actual_count=expected_count=16、marker 16、identity/account 命中、expected/actual projection SHA-256 同为 ec9d217dd22e5245eee899f234e58edc29f9c89dd69178fec5c5f65a04af48b7。失败只是 4 个 frame 返回同一成功证据后被 selector 判为 ambiguous。
  • 0.5.21 让名单回查只在 /System/Business/daoru.asp 执行,上传、KindEditor、顶层和列表 frame 均返回 passenger_requery_context_mismatch;正式 selector 将只收到一个 matched。全量门槛再次通过,18 文件包 SHA-256 276ce1c2d3fe4cee520381c3cf76df1a66c024eee0826e41a58d671b19c2587c。
  • 正式 0.5.21 只读 reconciliation 已将原 P01 execution 133192df-30fb-4753-b560-8ff08218684c 收敛为 completed;平台持久结果同时保留原 server_response、新 matched requery、reconciliation_resolved=true 和 no_additional_erp_write=true。
  • P02 旧任务 TASK-20260811030755-Oee_Pt4 在保存前因 passenger_shared_child_edit_link_count:0 阻断;实页链接确为 D14457-LW衡阳国旅云南分社(广东市场) 和 OPEN_update(14389,14457)。根因是通用编号边界把连字符当作编号字符。
  • 0.5.22 新增散拼子单专用文本规则:D<数字> 后只允许连字符或结束,且仍要求 onclick 的 tid/ddid 精确一致。全量门槛通过,18 文件 ZIP SHA-256 fd08860041b87ff6097b4d0722b488512130c2e5b1ab559df48f2ab6db87364a。
  • 0.5.22 P02 新 execution 已进入 plan_order.asp 和 daoru.asp,原生表单 readiness 为 403 控件/16 行/无 loading;唯一 blocker 来自 DAT SP_OrderList 裸行 parser 对同一 D14457-客户 文本边界的假未命中。该次没有 server request,write_attempted=false。
  • 0.5.23 把专用 child identifier 后边界同步给 ownership 行和叶子行解析,仍强制 marker、账号、tid、ddid;18 文件 ZIP SHA-256 261c82e8e62501054704e65398626afe9465e275362cfd8d4941d2caccdd8957。

2026-08-11 — P02 散拼名单真实持久映射

  • 0.5.23 canonical 任务 TASK-20260811053631-LjDMyCc 已证明散拼路由、ownership 和 403 控件完整度全部通过;DaoRuDones() 在未保存 DOM 中正确写入 16 行,但证件号控件名是 haoma,与独立团的 zjhaoma 不同。旧 projection 因找不到该控件而在服务端请求前阻断,确定无 ERP 写入。
  • 0.5.24 将两个原生控件统一映射为业务字段 document_no,其余安全门不变;全量 32/32 + 99/99、语法、JSON 和 5 Skills 通过,18 文件 ZIP SHA-256 8489f60ea7be77226d0ed32879d171b683fca398a2b47ea7a4f1e5253aa5225d。
  • 新任务 TASK-20260811054424-EDZ2f-M / execution 1e7a2bc0-21de-4904-a287-2fe6b4b117e3 已取得 DoInfo_order HTTP 200“修改成功”;fresh GET 为 16/16、marker 16,预期/实际投影 SHA-256 同为 ec9d217dd22e5245eee899f234e58edc29f9c89dd69178fec5c5f65a04af48b7,无采购、付款、通知或外发。

2026-08-11 — U01 独立团普通字段修改事实

  • canonical JSON 的通用 normalizer 曾给 U01 注入无关 passenger_list=none;该候选在确认前被 hash 对照拦截。严格路径现只在原文存在时保留 passenger_list,自然语言兼容路径不变。
  • 0.5.24 首个严格 U01 路由已实际打开精确 orders_add.asp,但 background 的首次 all-frame 枚举尚未包含新 edit frame,错误选择顶层 Mainlt.asp blocker;该次保存前阻断、确定无写。0.5.25 只对纯 frame-discovery blocker 做最多 5 秒读重试。
  • 0.5.25 U01 TASK-20260811060217-spxiqTg / execution cce9d492-2265-4357-9499-b3d7567a14fe 已跨写入边界。请求与页面原生 SubmitInfoForm() 一致:POST /System/DAT/orders.asp + Act=DoInfoJH&ListForm.serialize();服务端返回 HTTP 200/0 bytes,无成功脚本,fresh GET 中 xiadanbeizhu 仍为空。
  • 因响应和回查均未满足成功条件,任务保持 reconciliation_pending,不得重试。该事实说明“无安排历史”本身仍不足以保证普通 booking note 持久化;后续必须把此字段列为 ERP 原生限制/人工复核项,而不是宣称插件修改成功。

2026-08-11 — 0.5.32 与 C01 导游安排收敛

  • C01 导游安排的原始 execution a7f2cb47-8e0d-4cb3-be08-98435445de21 只有一次 ERP 写入,原生 DoInfo_daoyou 返回 HTTP 200“操作成功/ความสำเร็จ!”,326 bytes,响应 SHA-256 02434db5c7cccdef4f110f6ce272697ed337ea7951db5d2e8c7d2b14cf053143。
  • ERP fresh HTML 持久化了导游姓名、ID、电话、等级、导管账号和测试备注,但原始 HTML 不包含由页面 JavaScript 异步加载的导游候选 data;0.5.31 将 fresh 持久值与同一精确业务 frame 的唯一 id+name 候选分开取证。
  • PrintGridLists 裸行的首列序号与团号会在 textContent 中拼成 1LW-...;0.5.32 改为以唯一业务行的精确链接/action/控件证据识别团号,未放宽为模糊包含。
  • 0.5.32 对原 execution 的只读 reconciliation 已完成:导游 ID 11、LW张居雄、电话 59211177、等级“中级”、导管“测试ai员工账号”、测试备注和 ap_dy=false 全匹配;团队总表唯一行同时命中团号、账号和标记,no_additional_erp_write=true。

2026-08-11 — P01 原生名单映射新证据

  • DaoRuDones() 读取 TSV 时先对每行执行 replace(/\s/g, ""),因此 NAME=TEST GUEST 01 在页面与持久层均成为 TESTGUEST01。
  • 游客真实控件分别为 xingmingz、pinyinxm、xingbie、shengri、chushengdi、zjhaoma、qianfadi、fazhengri、youxiaori、dianhua、kbeizhu。
  • ERP 不存在独立证件类型控件;TSV 中的“证件类型”不能被声称为独立持久字段。当前选择失败关闭:只允许“护照”,并在 requery 中返回 implicit_document_type 和 non_persisted_source_fields。
  • P01 0.5.16 任务 TASK-20260811041739-Zs1YC0k 只在未保存 DOM 中调用原生解析,随后因投影不一致阻断;server_response=null、write_attempted=false,可以安全用 0.5.17 创建新 execution 重放。
  • 0.5.17 TASK-20260811043638-cd-o31A 证明 replace(/\s/g, "") 作用于整行而不仅是 NAME;第 16 行备注中的空格也被去除。该次同样在网络保存前阻断。

2026-08-12 — 第二轮真实回放最终事实

  • 第二轮 sept-2026-lifecycle-plugin-e2e2-01 创建 9 个全新对象:独立团 14395—14398 / 14460—14463、散拼母团 14399—14402、子单 D14464。四条创建路线全部取得明确原生响应和唯一写后回查。
  • 独立团与子单名单均为 16/16;独立团和散拼母团各五类安排 create/clear 全部完成,最终净安排为空。最小 0.01 应收 row 31562 已清除,独立团自动零额 row 31560/31561 也已精确清除;无真实收款、结算、采购或付款。
  • booking_note 在全新且无本轮安排历史的独立团上仍不持久化;页面原生 SubmitInfoForm 对照与插件结果一致。结论不再是“安排历史条件限制”,而是当前独立团普通字段没有正向可执行白名单。
  • 7 个状态转换确认:母团取消会让子单取消,母团恢复不会恢复子单。0.5.76 已把母团取消后每个子单的 fresh 详情 GET 和“已取消”状态纳入同一 operation 成功门槛。
  • 四次 source-only 导出共 40 个 artifact,全部 HTTP 200 并冻结类型、字节与 SHA-256;downloaded=false、converted=false、sent=false。
  • 9 个对象按允许清单顺序全部删除。最终探针 READONLY-REFS-sept-2026-lifecycle-plugin-e2e2-01-1786464329912 证明 8 个列表引用候选数为 0、D14464 无详情表单/marker、running_tasks=[]。
  • 控制平面一度被精确定位的 stale PostgreSQL idle in transaction backend 锁住;终止该 backend 后事务回滚,只持久化已有插件回执,没有重放 ERP 删除。该风险已进入收尾检查契约。
  • 0.5.77 将独立团普通修改在外部 parser、插件 planner、JSON Schema 和浏览器 adapter 四层失败关闭;order_update_independent 当前仅允许按精确 row ID 执行 clear_generated_zero。

2026-08-12 — 运营原始需求 10—21 重新审计

  • 已重新从 /Users/inmanx/Desktop/运营梳理.rtfd 提取原文,而不是只依赖现有能力矩阵。原文包含四类下单、两类名单、取消前应收清理、独立团宽字段修改、七类以上导出、五类安排,以及 DOC→DOCX、提前触发和安排变更模板等延伸诉求。
  • 第二轮真实回放证明的是当前窄契约:四类创建、代表性独立团/散拼子单名单、五类安排 create|clear、散拼母团容量、散拼子单住宿说明、精确测试应收清理、取消/恢复、source-only 读取和删除。它不能证明原文所有子项已经完成。
  • 原文与当前实现的主要缺口为:独立团日期/客户/团号/产品/人数/房型/行程/OP/销售/航班/接送机等普通修改;大交通落实/出票及多状态更新;酒店确认、加减房和改日期;车辆确认、换车和改日期;DOC→DOCX、提前两天自动触发、下载/外发;文件上传及真实采购/付款/结算流程。
  • 这些缺口必须在逐子项审计中明确标为 blocked_erp、not_live_validated、deferred 或 out_of_authorized_scope,不得被核心生命周期的通过结果带动为“已完成”。
  • 散拼批量母团 3/3 已验证,但原文 13.6—13.8 所暗示的“每个批量日期同时形成客户子单”尚没有逐日期子单证据;当前只对单个代表母团创建并验证一个具体子单。
  • 当前 mappings/lifecycle.mapping.json 的 live_replay_20260811.narrow_updates=3 会把两个成功窄修改和一个失败独立团探针混成同一成功计数,需拆为 update_probes=3 / persistent_update_successes=2 / blocked_update_probes=1。
  • lwlt-lifecycle 同时保留了“独立团安排前单字段探针”旧表述和“普通字段全部阻断”0.5.77 新表述,存在自相矛盾;正式 Skill 应只保留 0.5.77 的失败关闭契约。
  • lwlt-newbooking 已准确说明第二轮只有一个代表母团创建了具体子单,但现有简表没有把“散拼批量逐日期子单未验证”单列;详细审计和 Skill 均需明确该边界。
  • lwlt-confirmation 已声明不下载/不转换/不发送,但还需明确提前两天/提前一天等定时触发不是当前 action 能力,避免把 source-only 误解为自动交付。
  • 第二轮 C03/C04 的 shared_plan_create 只包含产品、日期、计划人数 16、TWN8、每日期 1 团和测试 suffix;客户 15+1 只存在于随后对 C03 单个母团执行的 C05 shared_child_order_create。因此原文 13.6—13.8 不能按批量路线宣称已验证。
  • 独立团创建适配已真实要求找到“更新行程”按钮、观察 GetProduct 成功请求和序列化字段变化,并校验产品模板产生的产品、行程天数、路线前缀、客户等核心字段;10.4 可以标为创建链路内已验证的产品联动,而不能标为任意行程手工修改能力。
  • 第二轮代表性安排输入已覆盖:车辆供应商/item/日期/数量/未确认/备注;酒店资源/房型/入住退房/8 间/未确认/备注;大交通供应商/item/日期/16 张/未确认/备注;其他供应商/item/日期/数量/备案四字段/备注;导游唯一 ID/名称/备注。它们只证明空槽新增和精确清理,不证明既有行 update 或其他状态。
  • 注册表仍有第二轮前的陈旧状态:把散拼子单写成“发布待第二轮”、把独立团普通修改写成“无安排历史窄字段测试态”,并将 confirmation_export 命名为文件导出。这些表述与 0.5.77/0.5.78 的真实证据冲突,必须在候选发布前同步为“核心已重复验证、宽能力阻断、源读取不交付文件”。
  • agents/openai.yaml 中 lifecycle/confirmation 的短描述仍使用“导出”;Skill 元数据会影响路由和用户预期,也必须同步为 source-only 源读取。所有 YAML 字符串需保持引号,default prompt 必须显式提及对应 $skill-name。
  • 扩展端现已要求 source-only 根结果和 artifacts 的四个副作用标志全部为 false,但控制平面 successReceiptFromResult 仍只检查 requery.hashes_frozen=true。若不补齐,伪造或旧版插件结果仍可能在控制平面生成“verified”回执;0.5.78 必须在该边界同步失败关闭。
  • Schema 的 confirmation 定义虽然在 action 条件中阻断 format,基础定义仍向调用方暴露未实测的 language 和 format 属性;planner 对 language 也未失败关闭。为了避免工具端继续生成伪能力,0.5.78 的 confirmation 子对象应只允许 canonical type。
  • 第三轮 C04 虽已通过 parser/planner/Schema,但平台 runner 对所有创建 action 原先只检查 instruction、9 月日期和 suffix,未独立复核专用散拼批量 probe 的 run/account/native baseline/phase/target dates,也未禁止 fixture 自授权 live write。runner 需要增加这一独立执行边界,避免仅靠上游校验。

2026-08-12 — C04 写后事实门槛审计

  • createSplitParentLive() 当前会把可选客户与 15+1 写入 plan_add.asp,但成功门槛只要求保存响应中的母团号或按日期在散拼计划列表找到母团行;现有 child_information 仅说明字段已提供/已提交,不能证明字段持久化,也不能证明每个日期已生成具体子单。
  • reconcileSplitParentByRequest() 已能逐日期唯一定位母团,但返回行证据只有团号、日期、文本长度和文本匹配;它尚未冻结 tid、具体子单 ddid 引用,且不能区分“客户/人数仅显示在母团行”与“形成客户子单”。
  • 生命周期 adapter 已有可复用的只读事实提取:sharedChildReferencesForParent() 从 OPEN_update(parentTid, childDdid) 提取子单引用,ownershipListProof() 对 shared plan 返回 child_count/child_refs。C04 应把同等严格度的逐日期证据放进创建 operation 自身,不能依赖后续 fixture 自报 refs。
  • 第三轮 C04 的正确成功语义应是“每个日期的保存对象和 split-order 事实均可确定”;只找到母团但无法确定子单事实时必须返回 uncertain/manual review,而不是 split_parent_completed。
  • 0.5.78 运行时现对多日期 split facts 做第二道 test-context 防线,并要求 ERP 返回团号数与请求日期数相等,或由逐日期唯一回查补齐;不能再用“响应里至少有一个团号”覆盖部分创建。
  • 每个日期的原生列表证据现冻结 parent group、tid、排除 ddid=0 新增入口后的全部具体子单 ddid、客户可见性、人数标记可见性和 outcome。三日期 facts 未全部确定时状态为 uncertain;parent-only 或字段 mismatch 即使事实确定,也保持 manual_review_required=true。
  • 新增纯逻辑回归覆盖具体子单、parent-only、缺失 tid/不完整扫描和跨母团链接排除;联合 planner/Schema/runner/lifecycle 定向集合 72/72 通过。
  • 控制面 successReceiptFromResult() 原先会优先接受带团号的直接回执,未对非 lifecycle 创建 action 的 report.manual_review_required 做统一拒绝;因此 C04 即使被插件标为 parent-only 人工复核,上层仍可能生成成功回执。
  • 该边界现已同步失败关闭:插件将任何 manual_review_required 的连接浏览器结果归为 uncertain;控制面在生成成功回执前统一拒绝人工复核/blocker,并对 split-order probe 重新验证三日期 group、parent tid、具体 child ddid、客户/人数一致、非零 child_count 和 all_dates_facts_determined。
  • 新增控制面回归分别证明完整三日期具体子单事实可生成成功回执、parent-only/manual-review 与 partial facts 均不能生成成功回执;定向 TypeScript、控制面 28 项和 lifecycle 25 项通过。
  • 第三轮前置数据库发现 5 条历史 awaiting_confirmation 草稿;逐条证明都只有 parse attempt、没有 ERP attempt、lease 或写入边界后,已使用 TaskService.cancelTask() 的正式事务路径转为 cancelled,保留任务、事件和审计记录,没有删除任务或调用 ERP。
  • 8786 旧源码实例退出后由既有守护机制自动拉起 PID 86215;人工准备的重复实例因 EADDRINUSE 自行退出。当前唯一监听器 database/schema/AgentBus ready,活动任务 0、组织自动化=false、idle in transaction=0。
  • 最近数据库浏览器连接仍报告扩展 0.5.76;0.5.78 尚未 reload 到承载自定义扩展的实际浏览器。内置浏览器仍无标签,因此当前真实写入门槛继续阻断。
  • 平台 fixture runner 的结果摘要此前会丢弃 C04 的 erp_receipt、verification、reconciliation 与 submit,使三日期母团/子单事实无法从正式 runner 产物冻结;现已保留这些字段和 warnings。
  • 第三轮 allowlist 初稿使用了非契约字段 created_objects,而回放与删除闸门实际读取 created_refs。现已统一为 canonical created_refs,并保持 delete_enabled=false/delete_authorized=false。
  • 新增 record_split_probe_result.mjs:只在 run、marker、账号、日期和逐日事实全部匹配时,把 C04 动态母团/具体子单同步写入 replay state 与 allowlist;默认仅预览,显式 --apply 才落盘,且绝不自动声明无子单或授权删除。
  • 记录器三类回归(真实子单、parent-only、partial/mismatched facts)及相关生命周期定向集合共 35/35 通过;parent-only 只为后续清理保留母团引用,业务验证仍保持失败/人工复核。

2026-08-12 — E2E4 与 0.5.81 最终事实

  • 实际执行使用用户授权的本地 Chrome 登录会话,而非未登录的内置浏览器;账号为“测试ai员工账号”,业务写入只发生在 /System/Business/ 与对应 /System/DAT/。
  • E2E4 共创建 12 个对象:独立团 4、散拼母团 4、具体子单 4。全部目标日期在 2026 年 9 月并带 TEST-202609-E2E4。
  • 散拼批量 C04 在 09-03/09-16/09-29 每日期形成一个具体子单 D14477/D14478/D14479,客户和成人 15 + 领队 1 均在原生列表持久化;E2E3、E2E4 已形成两轮重复事实。
  • 代表独立团和具体子单名单均 16/16;独立团/母团五类安排共 10 create + 10 clear,非导游 row 为 88504—88511,其他成本清理后备案保持。
  • 0.5.80 的 standalone receivable 契约在 row 31568 上真实通过 add/clear;两次写后住宿说明均精确保持 TEST-202609。独立团 row 31566/31567 也已精确清零。
  • 取消/恢复共 7 次再次证明:母团取消传播到子单,母团恢复不恢复子单,子单需单独恢复;取消态子单父引用以 oldtdid 为稳定来源。
  • 真实状态转换前,辅助 My97/编辑器 about:blank frame 继承业务列表 URL,旧 frame discovery 误报 exact frame 数为 2。任务在写前安全阻断;0.5.81 只允许顶层或有显式非空 src 的 frame 进入 action 候选,后续真实转换全部通过。
  • 安排态与最终态共 40/40 source-only artifact,根和 artifact 四个副作用标志均 false。
  • 删除顺序为 4 子单→4 母团→4 独立团;最终探针 READONLY-REFS-sept-2026-lifecycle-plugin-e2e4-01-1786510672875 证明 12/12 缺席、HTTP 全 200、无登录/权限文本、running_tasks=[]。
  • 第四轮是 0.5.79→0.5.80→0.5.81 的运行中稳定化全流程,不应伪称单一不可变构建从头到尾;若发布制度要求单制品证据,可再做一次不改版本的最终验收。
  • 当前可发布判断必须拆层:核心窄契约具备业务审批候选证据;独立团普通修改、订单宽字段、安排 update/确认/出票/落实、DOCX/调度/下载/外发仍明确阻断。

2026-08-12 — 运营业务 AI 输入模板契约

  • 已建立权威运营入口 agent设计规范/templates/business-input-templates.md:每个输入块第一行只写标准业务指令,后续按字段:值逐行表达业务事实。
  • 用户模板现覆盖 17 个可执行/系统指令:四类新增、两类名单、五类安排、两类窄修改、取消、恢复、source-only 源读取和系统内部测试清理;另有 5 个需求登记:...模板承接独立团宽修改、安排变更、真实应收、文件交付自动化和文件上传。
  • 可见业务引用与内部执行引用已分层:业务人员只提供团号、母团团号、具体子单号和日期;tid/ddid/row_id/账号/运行编号/测试标记/allowlist 由宿主/插件唯一解析或注入,且不得成为用户追问。
  • 预订客户定为规范标签,预定客户只作为兼容别名;范围日期与实际周期日期分开,人数保留分类表达,房间必须带房型。
  • 用户给出的散拼团新增计划短格式已原样保留为回归断言;可选拼团客户/拼团人数决定是否表达具体子单事实,多日期执行仍保留现有发布闸门。
  • 五类安排用户模板只表达未确认新增;clear、测试应收和删除均留在系统内部编排。source-only 模板不接收格式、语言、下载路径、调度或发送字段。
  • Agent Prompt、业务行为/适配注册表、四个既有新增业务入口及五个 Skill 已同步;每个 Skill 新增本地 references/input-contract.md,五个 .skill 包已重建并逐文件比对源码。
  • 校验结果:模板 5/5、核心业务 122/122、控制面 33/33、TypeScript、五个 Skill 官方 validator 和 git diff --check 全部通过。

2026-08-12 — 输入最小化修订原则

  • 用户明确否定任何依赖“记住修改前值”的模板;所有修改、变更和财务登记只收目标内容,当前值必须由系统 fresh 查询并写入 before_snapshot。
  • 统一交互规则改为“模板只列最小必填,可选信息显式标注选填”;能够从单号、订单详情、当前会话或 ERP 联动读取的类型、日期、人数、状态和内部引用不再要求用户重复填写。
  • 团队文件源读取的最小输入固定为单号 + 文件类型;接机牌游客姓名是条件选填/缺失时再追问,不要求订单类型、父团号或发团日期。
  • 清理测试订单不再属于生产用户输入:从模板、业务路由、适配登记和模板测试移除。底层 order_delete 仍保留给测试生命周期按 allowlist 回收测试对象,不形成生产口令。
  • 逐模板审计后,名单导入最小为单号+完整名单,取消/恢复最小为单号,五类安排不再重复要求团队类型、发团日期和固定未确认状态;日期只在无法安全默认或属于安排本身业务事实时保留。
  • 中央模板新增“最小必填速查”,并由回归测试固定 21 个规范模板的必填字段集合;任何重新加入原值、当前安排、当前收结状态或生产清理口令的改动都会失败。
  • 核心 action 的完整 operation 仍要求 existing_refs、日期和 test context;变化发生在交互入口:宿主/插件必须先按单号查询并注入,而不是把内部契约字段转嫁给用户。

2026-08-12 — 双段式输入模板规范

  • 用户确认最终展示单位必须是“一个操作 + 模板 + 示例”,不能把速查表、规则、多个示例和 operation 摘要交错在用户目录中。
  • 中央目录现有 21 个操作均严格包含两个相邻 text 代码块:模板在前、示例在后;不再保留重复的能力状态表、最小必填速查或散拼计划第二份示例。
  • 模板中的每个用户字段都显式使用(必填):或(选填):,值只用占位符;示例移除必填/选填标记和占位符,只展示可直接理解的具体业务值。
  • 用户给出的独立团单个下单示例已按原文保留,其中预定客户作为示例中的自然别名;规范模板仍使用预订客户。散拼团新增计划短示例继续原样保留。
  • 五份 Skill input-contract.md 按职责覆盖全部 21 个操作:newbooking 4、arrangement 6、updating 4、confirmation 3、lifecycle 4;每项同样采用双段式。
  • 四个既有下单业务适配页已把模板和示例调整为相邻的 1.1/1.2 小节;业务适配模板也把这套结构固定为新增业务的默认写法。
  • 自动测试不再只检查“出现某个指令”,而是检查 21 个连续编号、每项恰好两个文本块、字段标记、示例无占位符、最小必填集合、Skill 覆盖和四个业务页一致性。
  • 本轮仅整理本地输入契约和 Skill 制品,没有打开 ERP、提交任务或改变任何 ERP 对象。

2026-08-12 — 导出团队文件命名与平台责任边界

  • 运营侧标准指令已从技术名称读取团队文件源响应改为导出团队文件;模板最小输入仍是单号 + 文件类型,接机牌游客姓名按需选填。
  • 内部 action 保持 confirmation_export,避免破坏 Schema、插件路由、真实证据和历史任务兼容性;变化只发生在业务指令、界面标签和说明口径。
  • 当前 ERP 插件阶段的“导出完成”只表示已取得并校验 ERP 文件源内容,且冻结 HTTP、类型、字节数与 SHA-256;仍显式返回 downloaded=false/converted=false/scheduled=false/sent=false。
  • 文件下载、DOCX/PDF 等格式处理、定时生成和对外传输属于后续平台模块,不向当前插件 action 添加路径、格式、收件人或渠道字段。
  • 平台任务摘要和插件 operation 标签都显示导出团队文件;回归测试同时固定“用户名称已改、内部 action 未改、旧技术名称不再作为标准模板首行”。
  • confirmation 和 lifecycle 两个 Skill 的描述、主规则、输入/输出/ERP 衔接与 UI 元数据已同步,两个 Skill 包通过官方 validator 并重建。
  • 本轮没有进入 ERP,也没有读取、下载、修改或发送任何真实团队文件。

2026-08-12 — 修改类范围与当前 18 项输入

  • 用户确认原第 17 项独立团信息修改、第 18 项安排变更都属于“修改”,不应放在独立的“尚未开放需求登记”板块。
  • 当前目录按生命周期重新编号:12 散拼母团容量修改、13 散拼子单订房说明、14 独立团信息修改、15 安排变更、16 取消、17 恢复、18 导出团队文件。
  • 两项修改去掉需求登记:前缀并保留“模板 + 示例”。它们会提取目标值、查询当前值并形成 before/after;分类变化不构成 ERP 写入放行,普通独立团修改和既有安排 update 仍返回人工复核、operation=null。
  • 原 19 真实应收、20 文件交付自动化、21 文件上传已从中央运营目录、Skill 输入契约、Agent Prompt 和业务路由入口移除;底层测试应收、安全阻断与历史研究证据继续保留,不形成生产用户口令。
  • 当前运营输入目录为 18 项:16 项现有可执行/测试态能力 + 2 项修改类人工复核入口,不再存在“需求登记”分类。
  • updating、arrangement、confirmation、lifecycle 四个 Skill 已按新范围同步;外部解析 guidance 明确两项修改不能被改写为散拼窄修改或安排新增。
  • 本轮没有进入 ERP,也没有创建或修改任何业务对象。

2026-08-12 — 原需求 17/18 可执行性初审

  • 当前模板中的原 17/18 指「独立团信息修改」和「安排变更」,不能与运营原文里编号为 17/18 的大交通/酒店章节混淆。
  • 运营原文的独立团修改是宽字段集合,至少包含日期、客户、团号、业务/产品、人数、用房、下单备注、行程天数、OP/销售、团队状态、备案与多类说明、航班和接送机;不能用单个备注成功代表全部字段。
  • 当前插件/parser/Schema 对独立团普通字段显式失败关闭;唯一可执行的 order_update_independent 分支是测试零额应收行清理。既有 booking_note/xiadanbeizhu 探针得到 HTTP 200 空响应但 fresh 回查不持久,说明原请求路径或页面保存语义尚未掌握。
  • 当前安排 adapter 只支持五类安排的 create|clear。既有安排的日期、数量、资源、备注、确认状态、出票/落实等 update 尚未进入 operation 契约;parser 明确阻断普通 update。
  • 因此目前答案是“还不能真实跑”;本轮必须重新从独立团编辑页和安排编辑页取得正确 action/隐藏引用/保存响应,再按真实通过字段逐项开放。未实测字段仍保留阻断。
  • 用户指定的 Chrome 当前存在已登录 ERP 标签:标题老挝联泰_LW5.1.3,URL 为 https://lwlt.hisy.cc/System/Mainlt.asp;同时存在本地 LianSyn 操作台和扩展管理页。
  • 认领 ERP 标签后的完整跨 iframe DOM snapshot 超时,控制会话被重置;没有发生页面点击、表单提交或 ERP 写入。后续改用轻量/定向读取。
  • 第二次重连只尝试认领并读取 URL/title,仍在现有标签接管阶段超时;问题不来自 ERP 表单读取。按浏览器故障指引保留 Chrome 选择,下一步改用同一登录配置的新专用标签。
  • 同一 Chrome 配置可以立即创建 about:blank 专用标签;普通 goto(Mainlt.asp) 因旧 ASP 多 iframe 页面加载事件不结束而超时。不能把导航等待超时误判为未登录或写入失败,下一步使用浏览器提供的 CDP 能力做非阻塞导航与定向检查。
  • 浏览器公开了 tab 级 cdp 能力,但其契约要求先通过普通导航进入目标 HTTP(S) 页面。将 goto 放入 8 秒竞速后确认它仍未提交导航,标签保持 about:blank;因此暂不能绕过这条前置直接发 CDP 命令。
  • 后续对现有已登录 ERP 标签的认领也改为有界竞速,避免再让整个控制会话因单次调用挂死。
  • 有界认领在后台约 13 秒后成功,但原用户 tab 绑定随后变陈旧;浏览器同时报告此前专用标签 927774308 已完成延迟导航,标题和 URL 均为 ERP Mainlt.asp。这说明同一 Chrome 会话共享登录且专用标签可用,应改从 chrome.tabs.list() 取得该当前受控标签。
  • chrome.tabs.list() 精确确认受控专用标签 927774308 已是已登录 ERP 首页;随后首个 Page/Runtime 定向 CDP 读取仍超时并重置会话。三次不同读取方式均未进入表单或写入。
  • 项目已有更合适的同一浏览器执行通道:LTJT 扩展、LianSyn 平台与控制平面能够在 Chrome 登录上下文中执行 operation,并冻结原生请求、服务端响应和 fresh requery;后续真实验证转向该专用通道,不再继续 UI 接管重试。
  • 现有 run_native_independent_update_baseline_via_extension.mjs 的历史实现会通过平台标签和扩展 service worker 注入页面原生 SubmitInfoForm(),并严格校验 AI 账号、9 月、marker、tid/ddid 与 payload hash;它证明了现有事实,但其启动层依赖旧 CDP target 常量,不能未经当前目标重解析直接复用。
  • 当前 E2E4 测试对象已全部删除,不能修改历史对象;若要完成真实验证,需要重新创建本轮专用独立团及安排测试行,并登记新的 created_refs/allowlist。
  • 控制平面提供正式任务 API(创建、确认、claim、result)并把唯一 ERP execution、租约和不确定态持久化;它是比直接操纵 ERP DOM 更合适的写入入口。
  • 但普通 /api/* 需要现有 HttpOnly 登录会话和 CSRF;不能从 shell 读取浏览器 cookie,也不应绕过认证。需要确认扩展/平台是否会自动领取 confirmed 任务,或使用现有受控测试编排入口。
  • 平台前端的正式 handoff 是:确认任务→POST /api/tasks/:id/claim 取得唯一 execution→sendToExtension('CREATE_TASK')。扩展不会仅凭数据库出现 confirmed 任务自行执行;因此不能只在 shell/数据库造任务。
  • 当前 Chrome 已打开并登录 http://127.0.0.1:8786/ 操作台;后续可在这个轻量页面通过正式 UI 创建、确认和投递,实际 ERP 仍由扩展在同一 Chrome 登录会话内完成。
  • 新建的专用操作台标签已正常加载,当前登录为管理员;页面显示 AI 已连接、插件已连接、全自动化关闭、当前无任务。这个正式 UI 通道可用于人工确认式真实测试,不需要绕过认证或读取浏览器 cookie。
  • 插件状态详情确认:当前加载版本 0.5.81,最低要求同为 0.5.81,版本兼容、页面桥接已响应、ERP 自动化已开启、最近错误为空。可以先用既有已验证 action 创建本轮专用测试对象。
  • E2E4 已验证的唯一客户/产品组合可复用为本轮测试基线:客户LW北京山河途国际旅行社有限公司(新概念),产品北京直飞--七晚九(SH);二者来源地一致,可避免用户已说明的来源地/产品关键字超时规则。
  • 本轮必须使用新的 9 月日期和 suffix/marker,历史 E2E4 引用已删除,仅可作为输入基线,不能作为修改目标。
  • 已通过正式操作台创建测试任务 TASK-20260812094119-oO5DCPk,目标日期 2026-09-24,使用已验证客户/产品、15+1、8 标间,并显式携带 TEST-202609-U1718 后缀及本轮 run marker。
  • 当前任务仍为 parse_queued,系统写入和回执均未开始;尚未确认、未下发插件、未发生 ERP 写入。
  • 控制平面 live/ready 均健康,PostgreSQL/schema/AgentBus 均 ready;服务进程 PID 44696 正常监听 8786。
  • 数据库权威状态已前进到 parse_running,parse attempt 1 正在运行,租约有效且没有错误;页面只是尚未刷新。ERP attempt 尚不存在。
  • 五类安排页已经以同一 DoInfo_* + InfoForm1 保存整张安排表;每个非导游测试行带原生 id0,日期/资源/项目/数量/状态/备注字段都能被 create/clear 路径读取和精确回查。这为新增 mode=update 提供了直接基础,但必须先证明已有行在无付款/审核/落实锁时可原地修改。
  • 独立团页同样通过 DoInfoJH + ListForm 保存;当前 UPDATE_FIELDS 为空且 Schema 只放行 clear_generated_zero。先前仅 xiadanbeizhu 失败,尚不能据此判断日期、人数、房量或普通 textarea 等全部字段都不可修改。
  • 安排 update 最适合沿用五类 action 并增加 arrangement.mode=update:原生 action、页面和 form 与 create/clear 相同,差异只在精确锁定已有 row/resource、冻结 before、修改白名单字段并按 fresh GET 回查。这样不需要伪造第六类安排。
  • applyArrangement() 当前的 create 填充逻辑已经能设置资源、日期、项目、数量、状态、备注和备案;新增 update 的关键不是重写保存,而是扩展 arrangementSlotEvidence() 的占用/目标/财务锁守卫、允许部分目标字段并新增 update requery。
  • 独立团宽修改不能一次全部放开。现有证据显示状态和名单通过同一 DoInfoJH 可持久,而 xiadanbeizhu、shuoming0 曾不持久;需要本轮按字段族取得 live baseline,最后只开放真实通过的字段。

2026-08-12 — 原需求 17/18 真实执行结论

  • 原需求 17 已真实通过,但证据只支持独立团 twin_room_count/frenshu1 的正整数 set:本轮 8→9 与恢复 9→8 两次 DoInfoJH 都取得明确成功响应和 fresh 详情匹配;其他独立团字段不能从该事实外推。
  • 原需求 18 已真实通过,但证据只支持唯一、当前未确认酒店行的 end_date 和/或 room_count:row 88528 完成 09-12/8→09-13/9,资源、房型、入住日、状态和备注均保持,子页与团队总表同时匹配。
  • ERP 的 update_CZR(0) 会在离店日期/房间数失焦时清空备注;首次插件任务因此在写前安全阻断。最终 adapter 等待回调稳定后恢复 frozen remark,恢复失败继续阻断,修复后真实请求成功。
  • 0.5.84 已在 Chrome 重载,平台最低版本同步为 0.5.84。终态只读探针确认标间数为 8、酒店 row/资源/测试备注缺席,两次均 write_attempted=false。
  • 本专项没有采购、付款、通知、出票、落实或外发。三张测试订单仍按精确 allowlist 保留:未冻结导出证据,所以删除闸门保持关闭,不能为了收尾绕过前置。

2026-08-12 — 插件、Skills 与主提示词一致性审计

  • 17/18 的字段白名单已在 planner、外部 validator、Schema 和 adapter 四层存在,但真实运行提示仍由 LianSyn-platform/external-agent-client.mjs 内嵌生成;agent设计规范/agent-prompt.md 目前没有版本标识,也没有测试证明其关键路由与运行时提示完全同步。
  • 主提示词当前只写处理原则,缺少 18 个标准首行指令到 action/Skill 的紧凑路由表,以及 passed / needs_input / blocked 三种解析结果的明确选择顺序。补齐后可减少把缺失用户字段、内部引用不唯一和未开放目标混为一种错误。
  • 修改 adapter 的 setControl() 会对“目标值已经等于当前值”继续触发 input/change/blur;对酒店这会无谓触发 update_CZR(0),对独立团也可能提交无效果宽表。应在 update 专用路径比较业务值,只应用真正变化的目标;全部相同时写前阻断。
  • updating/arrangement/lifecycle 三个 Skill 的核心边界正确,但主文件混入大量历史 task/row ID 和运行过程说明。按 skill-creator 原则,应让 SKILL.md 保留可复用流程,把 operation 形状、页面映射和证据边界放入直接引用文件,并把 UI 元数据改为中文、与当前能力一致。
  • 现有自然语言 parser 会在 operation.source.parser_prompt_version 缺省时写入笼统的 external-profile,不能确认具体提示词版本。应由宿主覆盖为固定版本,canonical JSON 仍单独记录 canonical-json-v1。

Implementation result

  • 主提示词和运行时 parser 现在共用版本 ltjt-agent-prompt-v1.0-u1718-live,同时固定 18 个标准指令路由和 agent_parse_passed / agent_parse_needs_input / agent_parse_blocked 决策顺序。宿主覆盖供应商返回的伪版本值;canonical JSON 仍使用 canonical-json-v1。
  • 插件 0.5.85 的独立团修改和酒店 update 会在调用 applyExact/setControl 前比较 fresh 控件值。已等于目标的字段不派发事件;所有目标都无变化时返回 arrangement_update_no_effect 或 lifecycle_update_no_effect,且在原生提交前保持 write_attempted=false。
  • lwlt-updating、lwlt-arrangement、lwlt-lifecycle 的主文件现在只保留可复用工作流;原生 action、字段映射、mode 门槛、顺序和证据结构已移入直接 references。三个 Skill 不再把某次 task/execution/row ID 当作通用规则。
  • 静态门槛通过:TypeScript 检查/构建、控制面 33/33、核心回归 133/133、三个 Skill quick validator、JSON/语法/diff 和制品逐文件比对。
  • Chrome 实时 PING 证明平台最低版本和扩展均为 0.5.85,ERP 会话归属测试 AI 账号,无登录/权限错误。针对旧 17/18 对象的只读终检返回 0 候选;用户随后确认已手工删除全部旧测试订单,因此不将该结果解释为插件回查通过或回归失败。本轮没有 ERP 写入。