feat: ship deterministic parser and lifecycle release

This commit is contained in:
inman
2026-08-28 17:13:58 +08:00
parent 208c434b31
commit 7b5d855b09
176 changed files with 20248 additions and 1362 deletions

View File

@@ -1,7 +1,7 @@
{
"contract_version": "ltjt-lifecycle-v2.8-updating-wide-parse-2026-08",
"current_agent_parse_prompt_version": "ltjt-agent-prompt-v1.5-next-date-rollover",
"current_extension_version": "0.5.140",
"contract_version": "ltjt-lifecycle-v2.9-roster-leader-contact-2026-08",
"current_agent_parse_prompt_version": "ltjt-agent-prompt-v1.8-independent-headcount-categories",
"current_extension_version": "0.5.157",
"historical_test_marker": "TEST-202609",
"scope": "/System/Business/",
"erp_session_keepalive": {
@@ -31,6 +31,45 @@
"failure_policy": "record structured recovery status and require manual login/inspection; never retry a business operation"
}
},
"operation_timing": {
"schema_version": "ltjt-operation-timing-v1",
"scope": "all plugin business executions through the shared result state machine",
"starts_at": "unique execution acceptance",
"ends_at": "first terminal plugin result; later human-triggered reconciliation does not include the idle gap",
"stage_boundary": "a new result stage closes the previous stage; terminal status closes the current stage",
"page_action_details": [
"script_injection",
"action_roundtrip.<allowlisted_action_code>",
"action_runtime.<allowlisted_action_code>",
"network_wait.<allowlisted_action_code>",
"frame_discovery.web_navigation",
"preflight_lookup.<lookup_code>",
"preflight_product_linkage",
"preflight_customer_restore",
"preflight_submit_intercept",
"storage_queue.<operation_code>",
"storage_read.<operation_code>",
"storage_write.<operation_code>",
"storage_prune.local_history",
"tab_lookup.<operation_code>"
],
"performance_policy": "read-only lookup endpoints may run concurrently; webNavigation narrows readiness probes to exact ERP frames; current-version action runtimes and the allowlisted ERP tab may be reused within a task; product linkage and DoInfoJH wait on native ajax completion callbacks, customer restoration uses immediate exact protected-field verification, and no write gate depends on background-throttled page polling; active or reconcilable local task roots are never pruned",
"result_delivery": "storage change push with per-task latest-result coalescing; 2.5-second polling remains a fallback",
"privacy_allowlist": [
"schema/version code",
"stage/step/status code",
"duration in milliseconds",
"bounded numeric counters"
],
"forbidden": [
"ERP URL or query string",
"form or operation field value",
"customer or passenger data",
"response body or alert text",
"cookie, token or session identifier"
],
"storage": "runtime state in extension local storage; sanitized public snapshot in the encrypted execution result plus a PII-free JSONB summary"
},
"execution_policy": {
"release_state": "guarded_narrow_candidate_pending_business_approval",
"platform_envelope_requires": [
@@ -89,7 +128,7 @@
"passenger_list_import full-list first_import or confirmed full_replace",
"five arrangement create/clear operations at status 未确认",
"arrangement_hotel update for one exact 未确认 row: end_date and room_count only",
"order_update_independent twin_room_count plus field-mapped rooms.SGL/rooms.TWN and pax.adult/pax.child_bed/pax.leader pending fresh authorized ERP validation",
"order_update_independent twin_room_count plus field-mapped rooms.SGL/rooms.TWN and pax.adult/pax.child_bed/pax.child_no_bed/pax.leader pending fresh authorized ERP validation",
"order_update_shared_plan planned_capacity only",
"order_update_shared_child lodging_note append with final length <= 50",
"exact synthetic receivable fixture add/clear and generated-zero cleanup",
@@ -101,13 +140,13 @@
"multi-date shared_plan_create split facts are no longer factually undetermined, but remain restricted to phase=shared_batch_split_order_probe until business release approval"
],
"blocked_erp": [
"order_update_independent fields other than twin_room_count/rooms.SGL/rooms.TWN/pax.adult/pax.child_bed/pax.leader",
"order_update_independent fields other than twin_room_count/rooms.SGL/rooms.TWN/pax.adult/pax.child_bed/pax.child_no_bed/pax.leader",
"list order_restore through JH_set_quxiao(cz=0)",
"shared_child xiadanbeizhu",
"shared_child lodging_note final length > 50"
],
"not_live_validated": [
"independent order date/customer/group/product/non-three-passenger-count/room types other than SGL/TWN/itinerary/OP/sales/flight/pickup ordinary updates",
"independent order date/customer/group/product/non-four-passenger-count/room types other than SGL/TWN/itinerary/OP/sales/flight/pickup ordinary updates",
"arrangement update outside one exact unconfirmed hotel row, plus confirmed, ticketed, realized, self-loss or cancel states",
"hotel resource/room_type/start_date/remark update and every arrangement status update",
"vehicle end-date/change operations",
@@ -150,28 +189,37 @@
"allowed_modes": ["first_import", "full_replace"],
"preconditions": [
"existing_refs.kind is independent_order or shared_child_order",
"expected_passenger_count is read from the exact ERP edit form, never copied from user row_count",
"every supplied sequence is unique and within the current ERP passenger-slot range",
"expected_passenger_count is read from the exact ERP edit form as the initial merge baseline, never copied from user row_count and never treated as a business maximum",
"every supplied sequence is a unique positive integer within the 5000-row technical safety bound; the minimum target row count is max(initial ERP rows, highest supplied sequence)",
"first_import may fill blank rows or accept idempotent rows but cannot change occupied rows",
"full_replace requires confirmed=true and authorizes only the supplied sequences",
"full_replace requires confirmed=true and forces a native overwrite of every supplied sequence even when its current persisted projection is equal; the plugin must not downgrade confirmed user intent to no_changes",
"passenger_list.marker is exactly TEST-202609 only for an explicit historical test context",
"every source row has 证件类型 exactly 护照"
"every source row has 证件类型 exactly 护照",
"the workbook header is exactly row 2; row 1 is group metadata and never enters canonical TSV",
"at most one row has trimmed 备注 exactly 领队; that row requires nonblank 姓名 and 电话 and must match passenger_list.leader_contact"
],
"native_defects": [
"parser overwrites from row 1 and stops at existing row count",
"parser overwrites from row 1; independent orders commonly begin with 16 rows and shared-child orders with 31, but these are initial editable slots rather than a post-save minimum and the parent form may compact trailing blank slots",
"generic dianhua selector can include jj_dianhua and sj_dianhua",
"parser removes all whitespace from the entire source row before splitting columns, affecting NAME, remark, and every persisted value",
"证件类型 has no standalone native control and is not independently persisted"
"confirmed replacement of an occupied row can leave the existing pinyinxm value unchanged after native parsing",
"证件类型 has no standalone native control and is not independently persisted",
"post-save raw or hydrated passenger-row inspection can report false mismatches even after ERP has accepted and persisted the parent form"
],
"adapter_corrections": [
"use exact TSV headers 证件号码 and 签发日",
"merge supplied rows by explicit 序号 against the current ERP passenger slots",
"restore every unspecified native row after DaoRuDones so partial input cannot clear or shift existing passengers",
"merge supplied rows by explicit 序号 against the current ERP passenger rows and append canonical blank rows through the highest supplied sequence",
"restore every unspecified pre-existing native row after DaoRuDones so partial input cannot clear or shift existing passengers",
"fail closed before parent save when DaoRuDones does not materialize at least the calculated target row count",
"when the resolved native page materializes fewer passenger slots than the list requires, publish erp_passenger_count_limit_exceeded with the supplied count and actual ERP slot limit; retain passenger_native_* blockers only as technical evidence",
"block an occupied differing target row unless the user explicitly confirmed replacement",
"re-apply canonical whitespace-normalized NAME to pinyinxm only for merge-authorized changed sequences before strict projection validation",
"correct traveler phones within tr[id^=youke]",
"preserve jj_dianhua and sj_dianhua",
"restore jj_lianxiren/jj_dianhua and sj_lianxiren/sj_dianhua after native parsing; when a validated leader_contact exists, intentionally overwrite only jj_lianxiren/jj_dianhua with the marked row name/phone",
"project document number through independent-order zjhaoma or shared-child haoma, with pinyinxm/fazhengri/youxiaori for the remaining native fields",
"normalize every persisted source value by removing whitespace and report implicit_document_type=护照 plus non_persisted_source_fields=[证件类型]"
"normalize every persisted source value by removing whitespace and report implicit_document_type=护照 plus non_persisted_source_fields=[证件类型]",
"treat the exact parent-form native success response as terminal success for passenger_list_import after every pre-save projection and native blocker has passed",
"do not perform a post-save row requery or automatic hydrated reconciliation for a newly submitted passenger list"
],
"final_save": {
"independent_order": {
@@ -185,7 +233,8 @@
"form": "ListForm"
}
},
"requery": ["fresh detail GET", "exact object/account identity", "row count", "full post-merge projection hash immediately after write", "supplied-row projection for later reconciliation", "marker row count", "explicit non-persisted document-type evidence"]
"completion_evidence": ["all attachment, target identity, merge, overwrite-confirmation, passenger projection, and leader-contact projection checks pass before save", "the exact parent native save response is explicitly successful", "no post-save passenger-row requery is required", "no automatic reconciliation or second native save is started for a newly submitted passenger list"],
"completion_policy": "passenger_list_explicit_server_success"
},
"arrangements": {
"common": {
@@ -201,8 +250,16 @@
"clear_mode": "clear_exact_current_run_slot_0_only",
"slot_guard": ["resource row id is 0/empty", "resource hidden id is 0/empty", "payment reference yf0 is 0/empty", "audit fields are empty", "existing slot remark/item is empty"],
"clear_guard": ["same resolved resource id", "same persisted remark", "same date/item/quantity/status", "non-guide target.row_id from create requery", "payment reference is 0/empty", "audit and realized flags are empty"],
"date_window": "operation target dates; explicit historical test context remains restricted to 2026-09",
"subpage_identity": "host/list ownership still requires the full created ref (including independent ddid), while native teams*.asp forms prove the target by tdID because they do not carry ddid",
"business_preflight_rules": {
"arrangement_hotel_shared_plan_child_required": {
"evidence": ["resolved existing_refs.kind is shared_plan", "same-origin ERP page explicitly reports no child-group data", "SubmitButton is absent"],
"error_code": "erp_shared_plan_child_required_for_hotel",
"message": "散拼母团尚未创建子单ERP 不允许安排酒店。请先新增散拼子单,再重新提交酒店安排。",
"policy": "block before ERP write; do not retry automatically"
}
},
"date_window": "operation target dates; explicit historical test context remains restricted to 2026-09",
"subpage_identity": "host/list ownership still requires the full created ref (including independent ddid), while native teams*.asp forms prove the target by tdID because they do not carry ddid",
"positive_quantity_required": true,
"linkage_sequence": "resolved reference/date/item -> wait stable -> quantity/status/remark",
"preflight": ["route-specific minimum serialized control count", "no visible loading indicator", "stable form for at least 1 second", "exact current-run ownership list proof"],
@@ -306,11 +363,12 @@
"rooms.TWN": "frenshu1",
"pax.adult": "darenshu",
"pax.child_bed": "xiaorenshu",
"pax.child_no_bed": "ertrenshu",
"pax.leader": "quanrenshu"
},
"parsed_business_fields": "Skill 可解析人数、房型、日期、客户、产品、领队、行程、状态、备注和价格等用户明确目标;未逐字段实测的目标不得自动写入",
"executable_business_updates": ["set one or more non-negative integer rooms.SGL/rooms.TWN targets, one positive integer twin_room_count, or one or more non-negative passenger counts per request; passenger-count mappings are pending the next fresh authorized ERP validation"],
"manual_review_policy": "保留完整 updates.actions当前插件对 twin_room_count、rooms.SGL、rooms.TWN、pax.adult、pax.child_bed、pax.leader 做字段映射和写后回查,其余目标在插件预检阶段转人工复核且 no_erp_write=true",
"manual_review_policy": "保留完整 updates.actions当前插件对 twin_room_count、rooms.SGL、rooms.TWN、pax.adult、pax.child_bed、pax.child_no_bed、pax.leader 做字段映射和写后回查,其余目标在插件预检阶段转人工复核且 no_erp_write=true",
"allowed_non_business_operation": "receivable_fixture.clear_generated_zero only, using exact current-run row ids",
"known_result": "booking_note failed to persist both before and after arrangement history; HTTP 200 alone is never success",
"release_state": "wide_parse_field_mapped_room_and_passenger_counts_pending_live_validation_other_fields_manual_review"
@@ -407,6 +465,14 @@
"transitions": {
"order_cancel": {
"preconditions": ["receivables_cleared=true", "arrangements_cleared=true"],
"resolved_route_policy": {
"independent_order": "list",
"shared_plan": "list",
"shared_child_order": "edit",
"current_status_gate": "exact list row or exact edit form must expose exactly one allowed current status; missing, conflicting, or target-equals-current status blocks before write"
},
"edit_route_identity": "prefer exact form oldtdid/tdID/tid and ddid/dID/did values; fall back to case-insensitive query keys only when form refs are absent; conflicts fail closed",
"route_document_identity": "route preparation binds a fresh opaque 128-bit token only to the exact selected list/edit Document; frame discovery requires the token plus existing path/marker/reference checks, never logs the token, and still runs full business preflight before write",
"list": {
"supported_kinds": ["independent_order", "shared_plan"],
"action": "JH_set_quxiao",
@@ -470,16 +536,20 @@
}
},
"confirmation_export": {
"allowed_kinds": ["independent_order", "shared_child_order"],
"forbidden_kind": "shared_plan",
"required_refs": ["concrete child_order_no or ddid", "parent_group_no or parent_plan_no or plan_no for shared child", "concrete tid or unique-row resolution"],
"lookup_contract": "search shared parent list by parent ref, then lock one exact child leaf row by child_order_no or ddid and reconcile supplied ddid/tid",
"allowed_kinds": ["independent_order", "shared_plan", "shared_child_order"],
"shared_plan_narrow_scope": "single visitor-list only; resolve one mother plan, require group/plan identifier plus tid, forbid child did/ddid, and request orders_Visitor.asp with tid only",
"required_refs": ["independent order or shared child: concrete ddid plus tid", "shared child: parent_group_no or parent_plan_no or plan_no", "shared plan whole-group visitor: concrete group/plan identifier plus tid and no child did/ddid"],
"lookup_contract": "independent order resolves one exact order row; shared child searches the parent list then locks one exact child leaf and reconciles ddid/tid; shared-plan whole-group visitor resolves one exact mother row and reconciles tid only",
"artifact_result": ["http_status", "content_type", "content_disposition", "bytes", "sha256", "downloaded=false", "backend_stored=true", "artifact_id", "file_name", "byte_size", "storage_backend", "download_url", "converted", "conversion_status (pdf|xlsx|converted_xlsx|already_xlsx|source_native|source_fallback|mixed)", "conversion_fallback", "native_source_count", "converted_count", "pdf_converted_count", "xlsx_count", "source_artifact_count", "derived_artifact_count", "delivered_artifact_count", "artifact_role", "agentbus_visible", "scheduled=false", "sent=false"],
"sources": {
"xingyou-confirm": "/System/Business/orders_confirm_news.asp?did={ddid}&tid={tid}",
"liantai-confirm": "/System/Business/orders_confirm_new.asp?did={ddid}&tid={tid}",
"job-order": "/System/Business/teams_beian1.asp?did={ddid}",
"visitor-list": "/System/Business/orders_Visitor.asp?did={ddid}&tid={tid}",
"visitor-list": {
"independent_order": "/System/Business/orders_Visitor.asp?did={ddid}&tid={tid}",
"shared_child_order": "/System/Business/orders_Visitor.asp?did={ddid}&tid={tid}",
"shared_plan": "/System/Business/orders_Visitor.asp?tid={tid}"
},
"guide-confirm": "/System/Business/teams_confirms_new.asp?tid={tid}",
"hotel-preorder": "/System/Business/teams_hotel_confirm.asp?tid={tid}",
"transport-preorder": "/System/Business/teams_piao_confirm.asp?tid={tid}",