Files
LWLT-AIBOT/archive/research/2026-07-07/adapter_design.md
T

8.3 KiB

LTJT Adapter Design Principles

Runtime Principle

Production order creation must not depend on AI/LLM decisions.

AI may be used during discovery to inspect pages, draft schema notes, and propose mappings, but the runtime adapter must be deterministic, testable, and auditable.

The platform is the source of truth for tasks, sessions, confirmations, summaries, and user communication. The Agent emits only a parse-state business operation. The LTJT adapter validates its visible business fields, resolves ERP objects and current state deterministically, and builds a separate execution operation; it does not infer missing business intent from chat text at runtime. Platform metadata never becomes ERP business data.

  1. Session manager

    • Maintains an approved LTJT browser/session context.
    • Detects login-expired scripts and permission-alert scripts.
    • Never stores raw passwords in adapter logs.
  2. Page-context loader

    • Opens /System/Business/orders_add.asp in a controlled browser context.
    • Waits for lookup data and page JavaScript initialization to finish.
    • Avoids coordinate-based or visual clicking.
  3. Standard data mapper

    • Converts a user-owned standard order object from the business system/database into explicit ListForm field assignments.
    • Uses a versioned mapping table from standard fields to LTJT field names.
    • Does not ask an AI model what to fill at runtime.
  4. Lookup resolver

    • Resolves customer, product, staff, route, fee item, and resource fields using the page's own lookup endpoints.
    • Uses exact-match or configured matching rules.
    • Fails closed when a lookup is ambiguous.
  5. Staged operation gates

    • The dispatch/front gate checks only facts available before ERP lookup: action, minimum required business input, format, internal consistency, and supported narrow scope.
    • The ERP resolver enriches a private execution operation with exact object/resource references and fresh current state.
    • The strict pre-write gate rejects unresolved, ambiguous, stale, unsupported, or no-change writes before the native submit boundary.
  6. Dry-run serializer

    • Fills the page in a controlled context.
    • Reads ListForm.serialize().
    • Validates required fields, passenger counts, hidden ids, currency/unit metadata, and expected generated fields.
    • Produces an audit payload before submission.
  7. Submitter

    • Disabled by default until a test workflow is approved.
    • Submits Act=DoInfoJH& plus the serialized form only after deterministic validation passes.
    • Records request fingerprint, response classification, and created order identifier if returned.

Non-Goals

  • No AI/LLM in the production decision path.
  • No OCR/visual coordinate automation for normal operation.
  • No privilege bypass or hidden permission escalation.
  • No blind POSTs without first building and validating the browser-form payload.

Current Build Artifacts

The first deterministic contract and local dry-run artifacts are in place:

  • schemas/standard_system_operation.schema.json
  • mappings/orders_add.mapping.json
  • tools/dry_run_order_create.mjs
  • tools/browser_order_add_dry_run.mjs
  • tools/browser_order_add_preflight.mjs
  • samples/team_order_create.dry-run.example.json

The local dry-run script outputs the Act=DoInfoJH&... request body without submitting. The browser dry-run helper has now matched a live orders_add.asp ListForm.serialize() field set with fake-only sample values: 822 local fields, 822 live browser fields, zero mapped-field mismatches. It redacts session_id by default and never clicks submit.

Important correction: serializer compatibility is not enough for production. Many fields are LTJT SelectBox widgets, where values must be chosen from existing rows and the page's SetVal rules auto-fill linked fields. The adapter must run deterministic lookup validation before browser serialization or submit.

Next Build Artifact

Build the deterministic lookup resolver:

  • resolve product, customer, route, OP, and salesperson through LTJT lookup data/widgets; OP/sales fall back to the current login defaults
  • enforce exact-match or configured alias rules
  • populate hidden metadata such as zutuansheid, customer currency/contact fields, route-derived tuanxuhao1, and product pricing metadata
  • compare browser ListForm.serialize() after lookup resolution against the dry-run payload
  • keep live submit behind the business-system confirmation, execution-ID, payload-hash, and reconciliation gates

New helper scripts:

  • tools/inspect_orders_add_selectboxes.mjs records SelectBox bindings, endpoints, row/column counts, and linked fields without storing option values.
  • tools/validate_order_add_lookups.mjs checks a standard operation against existing LTJT options and blocks zero/multiple matches.
  • tools/resolve_order_add_lookups.mjs applies exact-match SelectBox rows to LTJT SetVal rules and can emit actual resolved field patches only when explicitly requested with --resolved-out.
  • tools/inspect_order_add_product_effect.mjs executes the product Find_product()/GetProduct(cpm) side effect in the browser without submitting and stores only redacted field-change metadata.
  • tools/browser_order_add_preflight.mjs is the historical closest-to-submit dry run: it exact-matches LTJT lookups, executes product side effects, validates product-template consistency, and serializes the live browser form without clicking submit. The active extension preserves product-owned receivable rows and updates only quantities/derived amounts.
  • tools/browser_order_add_submit_intercept.mjs installs an AJAX intercept before calling the page's SubmitInfoForm(), so the page's own validation and submit branch can be tested while preventing DoInfoJH from reaching the network.
  • tools/browser_order_add_template_selftest.mjs uses a real existing LTJT product template in browser memory only, fills obvious AI-DRYRUN-NO-SUBMIT markers, and proves the end-to-end non-writing page path can pass with actual SelectBox values.
  • tools/browser_order_add_submit_approved.mjs is the guarded live-submit tool. It refuses before browser access unless a real preflight report and a separate submit-intercept report both pass and have the same payload hash, plus --execute-live-submit and the exact approval token.
  • tools/verify_order_marker.mjs verifies the submitted test marker through JH_OrderList without storing business row values.

Controlled Submit Evidence

The active extension applies the same guarded pipeline to formal production operations. The reports/ directory is an output location only and is not a maintained evidence archive.

Required pipeline before a formal production write:

  1. validate_order_add_lookups.mjs or resolve_order_add_lookups.mjs must pass for the real standard operation so zero/multiple matches are blocked early.
  2. browser_order_add_preflight.mjs --input <real-operation> --open-form must pass in the logged-in browser. This is the authoritative pre-submit payload path because it runs LTJT's own product-template script.
  3. Product-template output must be nonempty and consistent with any explicitly supplied standard-operation value for product, trip, route, route prefix, customer, and customer id. Mismatch blocks submit.
  4. Product-owned receivable rows and prices must be preserved after product side effects; only passenger quantities and derived amounts may be updated deterministically.
  5. browser_order_add_submit_intercept.mjs --call-submit should capture exactly one intercepted DoInfoJH request with no validation alerts and DoInfoJH_network_prevented=true.
  6. browser_order_add_submit_approved.mjs may be used only when the real preflight approved payload hash equals the real submit-intercept hash, and only with the explicit approval token APPROVE-LTJT-DOINFOJH-SUBMIT.
  7. After submit, an ERP group-number receipt or equivalent order-list/detail verification should prove the order is visible. Historical marker lookup is only a fallback.

The earlier dry_run_order_create.mjs and browser_order_add_dry_run.mjs remain useful for schema and serializer compatibility checks, but they are no longer sufficient as the final production submit gate because a real product selection can mutate more than 100 form fields.

See system_operation_scope.md for the historical business-action to LTJT-system-operation boundary.