diff --git a/.project-docs/30-worklog/tasks/20260929-hotel-native-remark-01a0858b.md b/.project-docs/30-worklog/tasks/20260929-hotel-native-remark-01a0858b.md new file mode 100644 index 0000000..ff06bd6 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260929-hotel-native-remark-01a0858b.md @@ -0,0 +1,36 @@ +# 酒店新增保留原生备注 + +## Scope + +- 用户授权修复新增酒店时默认备注被空值覆盖:未填写备注保留选中酒店原生备注,明确填写时覆盖;酒店变更继续保留未指定的原记录备注。 +- 单条与同团批量共用执行路径。无真实 ERP 写入、部署、重启、扩展重载或外部发送。 + +## Worktree gate + +- Branch: main;worktree: `/Users/andy/IdeaProjects/LWLT-AIBOT`;base: `c2c71d35afbb7c1b9d28bda1b28926a9681414b6`。 +- 唯一 worktree;既有改动仅暂存 `.idea/` 文件,与本任务无重叠,保留原状。Overlap: Clear。 +- Feature 模式;单智能体;canonical 项目记忆只读。 + +## Plan + +1. 捕获所选酒店原生备注,防止日期/数量回调清空;用户明确备注优先。 +2. 将冻结后的备注纳入保存前保护和持久回查证据,旧版历史回查兼容。 +3. 增加单条/批量及异常回归,更新插件版本、最低版本、mapping、ZIP 和清单,完成仓库检查。 + +## Results / Validation + +- 完成默认酒店备注捕获与冻结;显式备注覆盖;资源/日期/数量回调不能静默清空待保存备注,其他行与已有酒店变更语义保持。 +- 默认备注创建证据 v2 绑定原始操作与备注摘要,保存前 guard 和写后 fresh GET/只读回查验证;缺失或不一致时阻断/不确定,历史 v1 回查兼容。批量按条独立生效。 +- 本地控制面 299/299 通过;插件/兼容 452 项中沙箱通过 450 项,另 2 项 HTTP 监听受限,经批准后定向重跑 2/2 通过。类型检查、构建及干净同内容源码副本仓库检查 10/10 通过。 +- 原工作目录仅有两项既有卫生检查失败(.idea、.DS_Store、历史日志),未删除或认领;.env 未读取。 +- 插件、平台最低版本、mapping、测试与发布清单同步 0.5.191。ZIP 21 文件逐字节匹配源码;原 0.5.190 ZIP 验证原清单哈希后归档。扫描仅清单引用旧 ZIP,无其他活动链接需修复。 +- 无新迁移;解析器/Skill/运营模板/DOCX 不变。当前未提交 Git,未部署或真实 ERP 验收。 +- [验证证据](../../../archive/evidence/2026-09-29/hotel-native-remark-01a0858b/README.md);[发布清单](../../../dist/release-manifest.json)。 + +## Follow-ups + +- 更新插件至 0.5.191 并同步平台最低版本,刷新平台/ERP 后在授权环境验收原生备注联动;历史已保存空备注不自动回填。 + +## Promotion Candidates + +- 目标:canonical 安排规则。建议登记酒店新增未指定备注继承所选资源默认备注,显式值覆盖,变更保留未指定原记录值;v2 证据用于新增默认备注持久核验。用户已授权方向,本地验证通过,生产真实验收待执行。 diff --git a/LianSyn-platform/app.js b/LianSyn-platform/app.js index 54db9e5..a6d076c 100644 --- a/LianSyn-platform/app.js +++ b/LianSyn-platform/app.js @@ -103,7 +103,7 @@ const persistedExtensionResultVersions = new Map(); let taskCreateInProgress = false; const AUTO_HANDOFF_RETRY_MS = 30_000; -const REQUIRED_EXTENSION_VERSION = '0.5.190'; +const REQUIRED_EXTENSION_VERSION = '0.5.191'; const MANUAL_HANDOFF_LABEL = '确认并提交到 ERP 插件'; const RETRY_HANDOFF_LABEL = '继续提交到 ERP 插件'; const RECONCILE_LABEL = '只读回查 ERP 现有结果'; diff --git a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md index f687475..6f0b092 100644 --- a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md +++ b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md @@ -2,7 +2,8 @@ ## 当前基线 -- Chrome 插件:`0.5.190` +- Chrome 插件:`0.5.191` +- `0.5.191` 酒店新增默认备注保留:原生选择后立即冻结备注,用户明确填写时覆盖;保存前保护及持久回查核对,单条/批量共用。旧 v1 回查与已有安排变更保持。仅本地合成回归,真实 ERP 验收待部署方完成;需更新插件/平台最低版本,无迁移。见[验证证据](../../../archive/evidence/2026-09-29/hotel-native-remark-01a0858b/README.md)及[任务记录](../../../.project-docs/30-worklog/tasks/20260929-hotel-native-remark-01a0858b.md)。 - `0.5.190` 同团批量酒店新增:2—10 个完整酒店块先整批验证,串行逐条复用原生保存/回查,首次失败或不确定停止,保留成功前缀和未执行清单;只读核验不自动续写。需同步控制面/平台和插件,无新增迁移;本地合成验证,真实 ERP 验收待部署方完成。见[验证证据](../../../archive/evidence/2026-09-24/hotel-batch-01a0858b/README.md)和[任务记录](../../../.project-docs/30-worklog/tasks/20260924-hotel-batch-01a0858b.md)。 - `0.5.189` 仅修复大交通与其他/备案新增的默认日期空行误判:行日期等于页面有效发团日期且数量为原生空/0/1 时允许进入原有空行校验,资源、说明、备注、费用、付款、审核与独立备案保护仍保留;其他安排、非默认日期和变更/清除不放宽。需更新插件、平台最低版本并刷新 ERP 页面,无服务端逻辑/迁移变更;真实 ERP 验收待部署方完成。见[本地验证](../../../archive/evidence/2026-09-22/arrangement-default-date-01a0b77e/README.md)及[任务记录](../../../.project-docs/30-worklog/tasks/20260922-arrangement-default-date-01a0b77e.md)。 - `0.5.188` 与程序解析器 `v1.0.14` 修复单个下单的产品格式匹配:比较双方统一 NFKC/空白,保留标点及业务限定词,唯一候选使用 ERP 原名联动;keyword 保留输入原始格式。初始失败跳过后续依赖校验,零/多产品候选提供独立中文原因。真实公共预检入口的合成回归通过,生产 ERP 验收待部署方完成;需同步服务端、插件和平台,无迁移。见[验证证据](../../../archive/evidence/2026-09-19/product-name-normalization-01a0b77e/README.md)及[任务记录](../../../.project-docs/30-worklog/tasks/20260919-product-name-normalization-01a0b77e.md)。 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/README.md b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/README.md new file mode 100644 index 0000000..e1f175a --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/README.md @@ -0,0 +1,20 @@ +# 酒店新增默认备注本地验证 + +此目录保存 2026-09-29 修复的不可变本地证据,不定义当前业务规则,也不是运行时输入。 + +## 结果 + +- 酒店原生选择后、资源/日期/数量事件前冻结所选行备注;省略备注继承该值,明确填写覆盖。其他行保持,已有酒店变更未填备注保持原记录。 +- 默认备注保存前校验,v2 创建证据绑定原操作与备注摘要,fresh GET/只读回查验证持久值;缺失证据或保存后变化不报成功。历史 v1 回查保持原语义。单条与批量逐条均覆盖。 +- 控制面 299/299 通过;插件/兼容测试共 452 项,沙箱中 450 项通过,2 项仅因本机监听 `EPERM` 失败,经批准解除该限制后定向重跑 2/2 通过。完整日志和定向结果均保留,没有隐藏失败日志。 +- 类型检查、构建通过;同内容干净源码副本仓库检查 10/10 通过,ZIP 的 21 个文件已与当前插件源码逐字节比对。 +- 原工作目录的仓库检查有两项既有卫生失败:`.idea/`、`.DS_Store`、历史日志。均保留不动;干净副本只排除这些已有杂项及秘密配置,未读取 `.env`。 +- 发布插件/平台最低版本/mapping/ZIP 为 0.5.191。无 Schema、解析器、Skill、运营模板/DOCX 或数据库迁移变更。 +- 未访问/写入真实 ERP,未部署、重启、扩展重载或外部发送。生产验收仍需更新后执行。 + +## 日志 + +- [控制面](control-plane-tests.txt) +- [插件/兼容完整沙箱结果](legacy-tests-sandbox.txt)、[HTTP 两项定向重跑](http-tests.txt) +- [干净副本仓库检查](repository-clean-tests.txt)、[原目录既有残留](repository-local-residue.txt) +- [类型检查](typecheck.txt)、[构建](build.txt)(成功时无输出) diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/build.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/build.txt new file mode 100644 index 0000000..e69de29 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/control-plane-tests.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/control-plane-tests.txt new file mode 100644 index 0000000..aec82ec --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/control-plane-tests.txt @@ -0,0 +1,1875 @@ +TAP version 13 +# Subtest: account migration adds roles, actor attribution, and reversible archive without purging history +ok 1 - account migration adds roles, actor attribution, and reversible archive without purging history + --- + duration_ms: 55.178209 + type: 'test' + ... +# Subtest: team-lead migration adds the role and bounded dashboard indexes without a tenant concept +ok 2 - team-lead migration adds the role and bounded dashboard indexes without a tenant concept + --- + duration_ms: 21.757208 + type: 'test' + ... +# Subtest: business authorization migration adds a fail-closed per-user allowlist for all registered routes +ok 3 - business authorization migration adds a fail-closed per-user allowlist for all registered routes + --- + duration_ms: 29.984125 + type: 'test' + ... +# Subtest: AgentBus account-worker migration adds fail-closed channel, task, browser, and ERP identity ownership +ok 4 - AgentBus account-worker migration adds fail-closed channel, task, browser, and ERP identity ownership + --- + duration_ms: 4.609125 + type: 'test' + ... +# Subtest: administrator task-isolation migration removes legacy bindings and rejects future data-plane principals +ok 5 - administrator task-isolation migration removes legacy bindings and rejects future data-plane principals + --- + duration_ms: 8.28 + type: 'test' + ... +# Subtest: AgentBus channel keys and owners are unique so one inbound identity cannot fan out to multiple employees +ok 6 - AgentBus channel keys and owners are unique so one inbound identity cannot fan out to multiple employees + --- + duration_ms: 23.235625 + type: 'test' + ... +# Subtest: account lifecycle is administrator-gated and protects passwords, sessions, and the last administrator +ok 7 - account lifecycle is administrator-gated and protects passwords, sessions, and the last administrator + --- + duration_ms: 3.73275 + type: 'test' + ... +# Subtest: administrators manage employee task-type grants while remaining outside manual intake +ok 8 - administrators manage employee task-type grants while remaining outside manual intake + --- + duration_ms: 3.797458 + type: 'test' + ... +# Subtest: operations dashboard is leadership-gated, cross-source, business-facing, and separate from normal task authority +ok 9 - operations dashboard is leadership-gated, cross-source, business-facing, and separate from normal task authority + --- + duration_ms: 11.747709 + type: 'test' + ... +# Subtest: ordinary task access is enforced across reads, mutations, artifacts, events, and browser connections +ok 10 - ordinary task access is enforced across reads, mutations, artifacts, events, and browser connections + --- + duration_ms: 5.878208 + type: 'test' + ... +# Subtest: administrators are excluded from task events and plugin result routing +ok 11 - administrators are excluded from task events and plugin result routing + --- + duration_ms: 3.036875 + type: 'test' + ... +# Subtest: ERP browser claims serialize only the assigned account queue +ok 12 - ERP browser claims serialize only the assigned account queue + --- + duration_ms: 1.662666 + type: 'test' + ... +# Subtest: force delete physically removes accessible tasks without the archive state gate +ok 13 - force delete physically removes accessible tasks without the archive state gate + --- + duration_ms: 3.15075 + type: 'test' + ... +# Subtest: operator UI exposes role-aware accounts, executive drill-through, archive, and explicit permanent deletion +ok 14 - operator UI exposes role-aware accounts, executive drill-through, archive, and explicit permanent deletion + --- + duration_ms: 4.404583 + type: 'test' + ... +# Subtest: account authorization editor uses a scroll-safe open layout without overriding the closed account list +ok 15 - account authorization editor uses a scroll-safe open layout without overriding the closed account list + --- + duration_ms: 4.701875 + type: 'test' + ... +# Subtest: AgentBus configuration stays disabled until connection fields are supplied +ok 16 - AgentBus configuration stays disabled until connection fields are supplied + --- + duration_ms: 2.413667 + type: 'test' + ... +# Subtest: AgentBus accepted delivery payloads keep final ownership metadata server-only +ok 17 - AgentBus accepted delivery payloads keep final ownership metadata server-only + --- + duration_ms: 0.789458 + type: 'test' + ... +# Subtest: AgentBus auto configuration rejects partial credentials +ok 18 - AgentBus auto configuration rejects partial credentials + --- + duration_ms: 0.708416 + type: 'test' + ... +# Subtest: database-managed channels may use the global WebSocket URL without a global key +ok 19 - database-managed channels may use the global WebSocket URL without a global key + --- + duration_ms: 0.21075 + type: 'test' + ... +# Subtest: WeChat transport envelope exposes only its business text to the global parser +ok 20 - WeChat transport envelope exposes only its business text to the global parser + --- + duration_ms: 2.178042 + type: 'test' + ... +# Subtest: channel directory prefers the current listener over stale persisted disabled status +ok 21 - channel directory prefers the current listener over stale persisted disabled status + --- + duration_ms: 0.717167 + type: 'test' + ... +# Subtest: AgentBus protocol helpers preserve reply routing fields +ok 22 - AgentBus protocol helpers preserve reply routing fields + --- + duration_ms: 0.642542 + type: 'test' + ... +# Subtest: AgentBus result text uses the unified important message and preserves the confirmation gate +ok 23 - AgentBus result text uses the unified important message and preserves the confirmation gate + --- + duration_ms: 0.720834 + type: 'test' + ... +# Subtest: AgentBus attachment references omit archived visitor XLS and keep only XLSX delivery +ok 24 - AgentBus attachment references omit archived visitor XLS and keep only XLSX delivery + --- + duration_ms: 0.3445 + type: 'test' + ... +# Subtest: AgentBus listener connects with the documented Authorization header and returns one final result +ok 25 - AgentBus listener connects with the documented Authorization header and returns one final result + --- + duration_ms: 117.908916 + type: 'test' + ... +# Subtest: WeChat attachment placeholder without file metadata fails closed before task ingestion +ok 26 - WeChat attachment placeholder without file metadata fails closed before task ingestion + --- + duration_ms: 31.016042 + type: 'test' + ... +# Subtest: attachment validation rejection returns an immediate failed result without scheduling parsing +ok 27 - attachment validation rejection returns an immediate failed result without scheduling parsing + --- + duration_ms: 6.474208 + type: 'test' + ... +# Subtest: roster direct listener sends waiting, attachment-received, and one final reply across two frames +ok 28 - roster direct listener sends waiting, attachment-received, and one final reply across two frames + --- + duration_ms: 11.590666 + type: 'test' + ... +# Subtest: listener reload stop does not overwrite the channel status as disabled +ok 29 - listener reload stop does not overwrite the channel status as disabled + --- + duration_ms: 1.087916 + type: 'test' + ... +# Subtest: channel manager replays a reload requested while another reload is in flight +ok 30 - channel manager replays a reload requested while another reload is in flight + --- + duration_ms: 1.381208 + type: 'test' + ... +# Subtest: listener shutdown carries its session epoch for stale-writer protection +ok 31 - listener shutdown carries its session epoch for stale-writer protection + --- + duration_ms: 0.430292 + type: 'test' + ... +# Subtest: durable channel listener persists route and resends accepted/result deliveries +ok 32 - durable channel listener persists route and resends accepted/result deliveries + --- + duration_ms: 1021.883708 + type: 'test' + ... +# Subtest: durable roster lifecycle assigns the final result only to the attachment frame +ok 33 - durable roster lifecycle assigns the final result only to the attachment frame + --- + duration_ms: 1004.547 + type: 'test' + ... +# Subtest: durable channel persists and sends an attachment rejection result while the task keeps waiting +ok 34 - durable channel persists and sends an attachment rejection result while the task keeps waiting + --- + duration_ms: 1050.103 + type: 'test' + ... +# Subtest: successful arrangements capture actual linked fields and retain separate original input/evidence +ok 35 - successful arrangements capture actual linked fields and retain separate original input/evidence + --- + duration_ms: 5.328 + type: 'test' + ... +# Subtest: parser, failed, queued, dry-run, uncertain and incomplete proof never change arrangement state +ok 36 - parser, failed, queued, dry-run, uncertain and incomplete proof never change arrangement state + --- + duration_ms: 37.902917 + type: 'test' + ... +# Subtest: full group identity is normalized without collapsing suffixes or accepting a different ERP group +ok 37 - full group identity is normalized without collapsing suffixes or accepting a different ERP group + --- + duration_ms: 0.311459 + type: 'test' + ... +# Subtest: five arrangement types have independent status and guides remain singleton after replacement +ok 38 - five arrangement types have independent status and guides remain singleton after replacement + --- + duration_ms: 17.096292 + type: 'test' + ... +# Subtest: update and clear target stable row IDs, preserving other rows regardless of slot renumbering +ok 39 - update and clear target stable row IDs, preserving other rows regardless of slot renumbering + --- + duration_ms: 0.995459 + type: 'test' + ... +# Subtest: late reconciliation replays by original execution time rather than overwriting newer arrangements +ok 40 - late reconciliation replays by original execution time rather than overwriting newer arrangements + --- + duration_ms: 0.097 + type: 'test' + ... +# Subtest: narrow hotel updates retain existing resource/date details but honor a verified cleared remark +ok 41 - narrow hotel updates retain existing resource/date details but honor a verified cleared remark + --- + duration_ms: 0.175417 + type: 'test' + ... +# Subtest: clearing external/untracked rows does not erase this account recorded arrangements +ok 42 - clearing external/untracked rows does not erase this account recorded arrangements + --- + duration_ms: 0.082084 + type: 'test' + ... +# Subtest: receipt summary is a frozen snapshot and remains single when public receipts are rebuilt +ok 43 - receipt summary is a frozen snapshot and remains single when public receipts are rebuilt + --- + duration_ms: 1.673667 + type: 'test' + ... +# Subtest: ledger storage encrypts details, deduplicates and scopes reads to both organization and account +ok 44 - ledger storage encrypts details, deduplicates and scopes reads to both organization and account + --- + duration_ms: 5.581625 + type: 'test' + ... +# Subtest: backfill includes archived successes and skips failed/other-account tasks, preserving encrypted evidence +ok 45 - backfill includes archived successes and skips failed/other-account tasks, preserving encrypted evidence + --- + duration_ms: 0.639125 + type: 'test' + ... +# Subtest: ledger migration has no cascading source-task dependency and blocks admin ownership +ok 46 - ledger migration has no cascading source-task dependency and blocks admin ownership + --- + duration_ms: 10.525709 + type: 'test' + ... +# Subtest: real success-result transaction saves summary/history once and force delete preserves details +ok 47 - real success-result transaction saves summary/history once and force delete preserves details + --- + duration_ms: 7.223542 + type: 'test' + ... +# Subtest: original hotel dates never roll forward with the submission date or group number +ok 48 - original hotel dates never roll forward with the submission date or group number + --- + duration_ms: 205.011292 + type: 'test' + ... +# Subtest: original dates retain explicit years and allow cross-year, mixed-year and leap-day selectors +ok 49 - original dates retain explicit years and allow cross-year, mixed-year and leap-day selectors + --- + duration_ms: 131.439416 + type: 'test' + ... +# Subtest: vehicle, transport and other original dates also preserve month/day including filing date +ok 50 - vehicle, transport and other original dates also preserve month/day including filing date + --- + duration_ms: 1.995042 + type: 'test' + ... +# Subtest: hotel creation and legacy target-date changes retain their existing year semantics +ok 51 - hotel creation and legacy target-date changes retain their existing year semantics + --- + duration_ms: 9.939833 + type: 'test' + ... +# Subtest: vehicle type is an optional candidate filter on create and update, never an original date or direct item edit +ok 52 - vehicle type is an optional candidate filter on create and update, never an original date or direct item edit + --- + duration_ms: 425.443167 + type: 'test' + ... +# Subtest: guide update separates original dates from replacements +ok 53 - guide update separates original dates from replacements + --- + duration_ms: 1.041459 + type: 'test' + ... +# Subtest: vehicle update separates original dates from replacements +ok 54 - vehicle update separates original dates from replacements + --- + duration_ms: 0.737292 + type: 'test' + ... +# Subtest: transport update separates original dates from replacements +ok 55 - transport update separates original dates from replacements + --- + duration_ms: 1.635083 + type: 'test' + ... +# Subtest: other update separates original dates from replacements +ok 56 - other update separates original dates from replacements + --- + duration_ms: 0.807542 + type: 'test' + ... +# Subtest: updates require an original date and new resource; quantity remains optional only for other +ok 57 - updates require an original date and new resource; quantity remains optional only for other + --- + duration_ms: 32.873083 + type: 'test' + ... +# Subtest: ticket description is optional on transport create/update and stays separate from linked item and original dates +ok 58 - ticket description is optional on transport create/update and stays separate from linked item and original dates + --- + duration_ms: 17.760167 + type: 'test' + ... +# {"level":30,"time":1790658579777,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.initialized","diagnostic_stage":"startup","host":"127.0.0.1","port":8786,"log_level":"info","database_schema":"public","database_ssl":"disable","artifact_storage_backend":"database","agentbus_enabled":false,"leader_summary_webhook_enabled":false,"leader_summary_webhook_configuration_error":null,"parser_loop_enabled":false,"data_retention_enabled":false,"raw_payload_logging":false,"msg":"control plane initialized"} +# Subtest: message routing starts a new session for a business directive, not for a supplement +ok 59 - message routing starts a new session for a business directive, not for a supplement + --- + duration_ms: 18.433708 + type: 'test' + ... +# Subtest: task access contract excludes administrators and isolates employee owners +ok 60 - task access contract excludes administrators and isolates employee owners + --- + duration_ms: 0.23525 + type: 'test' + ... +# Subtest: task data-plane HTTP classifier covers every task-bearing surface and excludes management APIs +ok 61 - task data-plane HTTP classifier covers every task-bearing surface and excludes management APIs + --- + duration_ms: 0.098458 + type: 'test' + ... +# Subtest: task service rejects administrator operations before touching task storage +ok 62 - task service rejects administrator operations before touching task storage + --- + duration_ms: 5.725792 + type: 'test' + ... +# Subtest: business route authorization is an explicit allowlist for team leads and ordinary users +ok 63 - business route authorization is an explicit allowlist for team leads and ordinary users + --- + duration_ms: 0.123917 + type: 'test' + ... +# Subtest: field encryption round-trips without storing plaintext +ok 64 - field encryption round-trips without storing plaintext + --- + duration_ms: 1.127583 + type: 'test' + ... +# Subtest: field encryption round-trips binary task attachments +ok 65 - field encryption round-trips binary task attachments + --- + duration_ms: 0.967417 + type: 'test' + ... +# Subtest: database artifact store sends encrypted bytes to the persistence boundary +ok 66 - database artifact store sends encrypted bytes to the persistence boundary + --- + duration_ms: 0.80275 + type: 'test' + ... +# Subtest: production OSS configuration requires provider credentials and derives the region +ok 67 - production OSS configuration requires provider credentials and derives the region + --- + duration_ms: 0.790167 + type: 'test' + ... +# Subtest: OSS artifact store writes metadata with an idempotent UUID execution path and cleans captured keys +ok 68 - OSS artifact store writes metadata with an idempotent UUID execution path and cleans captured keys + --- + duration_ms: 0.895916 + type: 'test' + ... +# Subtest: token hashes compare safely and do not expose the original token +ok 69 - token hashes compare safely and do not expose the original token + --- + duration_ms: 0.095875 + type: 'test' + ... +# Subtest: organization automation applies uniformly to every valid task source +ok 70 - organization automation applies uniformly to every valid task source + --- + duration_ms: 0.06025 + type: 'test' + ... +# Subtest: control plane exposes a live health endpoint without a database connection +ok 71 - control plane exposes a live health endpoint without a database connection + --- + duration_ms: 426.561709 + type: 'test' + ... +# {"level":30,"time":1790658579951,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.initialized","diagnostic_stage":"startup","host":"127.0.0.1","port":8786,"log_level":"info","database_schema":"public","database_ssl":"disable","artifact_storage_backend":"database","agentbus_enabled":false,"leader_summary_webhook_enabled":false,"leader_summary_webhook_configuration_error":null,"parser_loop_enabled":false,"data_retention_enabled":false,"raw_payload_logging":false,"msg":"control plane initialized"} +# {"level":30,"time":1790658579939,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.closing","diagnostic_stage":"shutdown","msg":"control plane closing"} +# {"level":40,"time":1790658579995,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"8b389a38-c34c-43c6-918e-b334991f9d4c","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"8b389a38-c34c-43c6-918e-b334991f9d4c","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658579995,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"8b389a38-c34c-43c6-918e-b334991f9d4c","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"8b389a38-c34c-43c6-918e-b334991f9d4c","method":"GET","path":"/api/tasks","status_code":403,"duration_ms":13.729,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658579996,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"05897777-87ae-4ef6-9070-93eedf56ed27","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"05897777-87ae-4ef6-9070-93eedf56ed27","method":"POST","path":"/api/tasks","content_length":27,"msg":"HTTP request started"} +# {"level":40,"time":1790658579997,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"05897777-87ae-4ef6-9070-93eedf56ed27","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"05897777-87ae-4ef6-9070-93eedf56ed27","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658579998,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"05897777-87ae-4ef6-9070-93eedf56ed27","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"05897777-87ae-4ef6-9070-93eedf56ed27","method":"POST","path":"/api/tasks","status_code":403,"duration_ms":2.22,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658579999,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6140da69-8690-4f3a-83f0-3165314da1f3","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"6140da69-8690-4f3a-83f0-3165314da1f3","method":"POST","path":"/api/messages","content_length":26,"msg":"HTTP request started"} +# {"level":40,"time":1790658580100,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6140da69-8690-4f3a-83f0-3165314da1f3","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"6140da69-8690-4f3a-83f0-3165314da1f3","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580102,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6140da69-8690-4f3a-83f0-3165314da1f3","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"6140da69-8690-4f3a-83f0-3165314da1f3","method":"POST","path":"/api/messages","status_code":403,"duration_ms":103.304,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580102,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"98907745-f0d4-4c27-8995-325d3bf73665","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"98907745-f0d4-4c27-8995-325d3bf73665","method":"GET","path":"/api/tasks/TASK-1","msg":"HTTP request started"} +# {"level":40,"time":1790658580102,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"98907745-f0d4-4c27-8995-325d3bf73665","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"98907745-f0d4-4c27-8995-325d3bf73665","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580103,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"98907745-f0d4-4c27-8995-325d3bf73665","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"98907745-f0d4-4c27-8995-325d3bf73665","method":"GET","path":"/api/tasks/:taskId","status_code":403,"duration_ms":0.334,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580103,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"17b4a2ca-ca14-4a59-8f52-4578675e2269","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"17b4a2ca-ca14-4a59-8f52-4578675e2269","method":"GET","path":"/api/tasks/TASK-1/input-history","msg":"HTTP request started"} +# {"level":40,"time":1790658580103,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"17b4a2ca-ca14-4a59-8f52-4578675e2269","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"17b4a2ca-ca14-4a59-8f52-4578675e2269","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580117,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"17b4a2ca-ca14-4a59-8f52-4578675e2269","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"17b4a2ca-ca14-4a59-8f52-4578675e2269","method":"GET","path":"/api/tasks/:taskId/input-history","status_code":403,"duration_ms":14.287,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580118,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"49628e99-08ef-4544-a3ac-7ae228ad720b","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"49628e99-08ef-4544-a3ac-7ae228ad720b","method":"GET","path":"/api/tasks/TASK-1/artifacts/44444444-4444-4444-8444-444444444444","msg":"HTTP request started"} +# {"level":40,"time":1790658580118,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"49628e99-08ef-4544-a3ac-7ae228ad720b","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"49628e99-08ef-4544-a3ac-7ae228ad720b","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580118,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"49628e99-08ef-4544-a3ac-7ae228ad720b","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"49628e99-08ef-4544-a3ac-7ae228ad720b","method":"GET","path":"/api/tasks/:taskId/artifacts/:artifactId","status_code":403,"duration_ms":0.264,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580118,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"2a48b91d-5d47-4cb3-9786-c66129fc1113","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"2a48b91d-5d47-4cb3-9786-c66129fc1113","method":"POST","path":"/api/tasks/TASK-1/confirm","content_length":2,"msg":"HTTP request started"} +# {"level":40,"time":1790658580121,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"2a48b91d-5d47-4cb3-9786-c66129fc1113","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"2a48b91d-5d47-4cb3-9786-c66129fc1113","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580122,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"2a48b91d-5d47-4cb3-9786-c66129fc1113","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"2a48b91d-5d47-4cb3-9786-c66129fc1113","method":"POST","path":"/api/tasks/:taskId/confirm","status_code":403,"duration_ms":3.716,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580126,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"5e989a25-9188-46f0-b6df-e00cabe5189b","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"5e989a25-9188-46f0-b6df-e00cabe5189b","method":"POST","path":"/api/tasks/TASK-1/claim","content_length":53,"msg":"HTTP request started"} +# {"level":40,"time":1790658580126,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"5e989a25-9188-46f0-b6df-e00cabe5189b","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"5e989a25-9188-46f0-b6df-e00cabe5189b","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580127,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"5e989a25-9188-46f0-b6df-e00cabe5189b","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"5e989a25-9188-46f0-b6df-e00cabe5189b","method":"POST","path":"/api/tasks/:taskId/claim","status_code":403,"duration_ms":0.688,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580127,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"b050d298-655c-44c4-ac67-e9b02c75dd9f","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"b050d298-655c-44c4-ac67-e9b02c75dd9f","method":"POST","path":"/api/tasks/TASK-1/result","content_length":119,"msg":"HTTP request started"} +# {"level":40,"time":1790658580127,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"b050d298-655c-44c4-ac67-e9b02c75dd9f","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"b050d298-655c-44c4-ac67-e9b02c75dd9f","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"b050d298-655c-44c4-ac67-e9b02c75dd9f","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"b050d298-655c-44c4-ac67-e9b02c75dd9f","method":"POST","path":"/api/tasks/:taskId/result","status_code":403,"duration_ms":0.359,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","method":"POST","path":"/api/tasks/TASK-1/cancel","content_length":2,"msg":"HTTP request started"} +# {"level":40,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"f0ba76c9-5d8c-4d33-afd9-5be9ce00ef1d","method":"POST","path":"/api/tasks/:taskId/cancel","status_code":403,"duration_ms":0.249,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"30cb8fc2-4744-459d-85e3-1ac4453989f4","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"30cb8fc2-4744-459d-85e3-1ac4453989f4","method":"POST","path":"/api/tasks/bulk-delete","content_length":23,"msg":"HTTP request started"} +# {"level":40,"time":1790658580128,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"30cb8fc2-4744-459d-85e3-1ac4453989f4","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"30cb8fc2-4744-459d-85e3-1ac4453989f4","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"30cb8fc2-4744-459d-85e3-1ac4453989f4","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"30cb8fc2-4744-459d-85e3-1ac4453989f4","method":"POST","path":"/api/tasks/bulk-delete","status_code":403,"duration_ms":0.465,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"c3533f02-a4ed-4712-b0d7-703f78b494f6","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"c3533f02-a4ed-4712-b0d7-703f78b494f6","method":"POST","path":"/api/tasks/bulk-archive","content_length":23,"msg":"HTTP request started"} +# {"level":40,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"c3533f02-a4ed-4712-b0d7-703f78b494f6","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"c3533f02-a4ed-4712-b0d7-703f78b494f6","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"c3533f02-a4ed-4712-b0d7-703f78b494f6","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"c3533f02-a4ed-4712-b0d7-703f78b494f6","method":"POST","path":"/api/tasks/bulk-archive","status_code":403,"duration_ms":0.322,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"8e641e50-b521-464d-9c83-a83655c63bf3","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"8e641e50-b521-464d-9c83-a83655c63bf3","method":"DELETE","path":"/api/tasks/TASK-1","msg":"HTTP request started"} +# {"level":40,"time":1790658580129,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"8e641e50-b521-464d-9c83-a83655c63bf3","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"8e641e50-b521-464d-9c83-a83655c63bf3","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"8e641e50-b521-464d-9c83-a83655c63bf3","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"8e641e50-b521-464d-9c83-a83655c63bf3","method":"DELETE","path":"/api/tasks/:taskId","status_code":403,"duration_ms":0.12,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"4f011a80-1358-4320-87f9-416d64462b56","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"4f011a80-1358-4320-87f9-416d64462b56","method":"POST","path":"/api/tasks/TASK-1/archive","content_length":2,"msg":"HTTP request started"} +# {"level":40,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"4f011a80-1358-4320-87f9-416d64462b56","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"4f011a80-1358-4320-87f9-416d64462b56","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"4f011a80-1358-4320-87f9-416d64462b56","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"4f011a80-1358-4320-87f9-416d64462b56","method":"POST","path":"/api/tasks/:taskId/archive","status_code":403,"duration_ms":0.44,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"18c873c7-d383-42f4-8258-6db654be2efa","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"18c873c7-d383-42f4-8258-6db654be2efa","method":"POST","path":"/api/tasks/TASK-1/restore","content_length":2,"msg":"HTTP request started"} +# {"level":40,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"18c873c7-d383-42f4-8258-6db654be2efa","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"18c873c7-d383-42f4-8258-6db654be2efa","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580130,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"18c873c7-d383-42f4-8258-6db654be2efa","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"18c873c7-d383-42f4-8258-6db654be2efa","method":"POST","path":"/api/tasks/:taskId/restore","status_code":403,"duration_ms":0.199,"msg":"HTTP request completed with client error"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"41ea237e-68d2-496e-9c0f-ad21e719a808","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"41ea237e-68d2-496e-9c0f-ad21e719a808","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"41ea237e-68d2-496e-9c0f-ad21e719a808","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"41ea237e-68d2-496e-9c0f-ad21e719a808","method":"POST","path":"/api/connections/heartbeat","status_code":403,"duration_ms":0.195,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"80b28320-77d2-4aa2-96fd-68a08284c3d0","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"80b28320-77d2-4aa2-96fd-68a08284c3d0","method":"GET","path":"/api/events","msg":"HTTP request started"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"80b28320-77d2-4aa2-96fd-68a08284c3d0","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"80b28320-77d2-4aa2-96fd-68a08284c3d0","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"80b28320-77d2-4aa2-96fd-68a08284c3d0","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"80b28320-77d2-4aa2-96fd-68a08284c3d0","method":"GET","path":"/api/events","status_code":403,"duration_ms":0.095,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","method":"GET","path":"/api/operations-dashboard","msg":"HTTP request started"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"3a75af8f-b215-4187-ab3d-20ee2a8166dd","method":"GET","path":"/api/operations-dashboard","status_code":403,"duration_ms":0.09,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","method":"GET","path":"/api/operations-dashboard/tasks/TASK-1","msg":"HTTP request started"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"6ccf89b7-4ec3-42ad-8752-0bd17f0c3462","method":"GET","path":"/api/operations-dashboard/tasks/:taskId","status_code":403,"duration_ms":0.101,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580131,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","method":"POST","path":"/api/tasks/TASK-1/reparse","content_length":31,"msg":"HTTP request started"} +# {"level":40,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","task_id":"TASK-1","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"25d1dd5f-da0f-46c1-b42c-bd49fa353598","method":"POST","path":"/api/tasks/:taskId/reparse","status_code":403,"duration_ms":0.228,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","diagnostic_event":"http.request.started","diagnostic_stage":"http","request_id":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","method":"PUT","path":"/api/parser-decisions/44444444-4444-4444-8444-444444444444/review","content_length":24,"msg":"HTTP request started"} +# Subtest: administrator sessions receive 403 before every task data-plane handler +ok 72 - administrator sessions receive 403 before every task data-plane handler + --- + duration_ms: 193.28625 + type: 'test' + ... +# Subtest: AI primary connection state follows service reachability, not historical authentication evidence +ok 73 - AI primary connection state follows service reachability, not historical authentication evidence + --- + duration_ms: 0.30625 + type: 'test' + ... +# {"level":40,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","diagnostic_event":"http.request.rejected","diagnostic_stage":"http","request_id":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","status_code":403,"error_code":"task_access_forbidden","error_name":"AuthError","msg":"HTTP request rejected by application guard"} +# {"level":40,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","reqId":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","diagnostic_event":"http.request.completed","diagnostic_stage":"http","request_id":"cb358032-00b6-4df4-bbda-c2cf8a0a9b6e","method":"PUT","path":"/api/parser-decisions/:decisionId/review","status_code":403,"duration_ms":0.184,"msg":"HTTP request completed with client error"} +# {"level":30,"time":1790658580132,"pid":47732,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.closing","diagnostic_stage":"shutdown","msg":"control plane closing"} +# Subtest: migration contains the durable state tables and safety fields +ok 74 - migration contains the durable state tables and safety fields + --- + duration_ms: 2.308167 + type: 'test' + ... +# Subtest: control plane requires the arrangement ledger migration before readiness +ok 75 - control plane requires the arrangement ledger migration before readiness + --- + duration_ms: 6.404709 + type: 'test' + ... +# Subtest: ERP execution results fail closed after a possible write +ok 76 - ERP execution results fail closed after a possible write + --- + duration_ms: 2.266458 + type: 'test' + ... +# Subtest: successful ERP executor results expose consistent lifecycle boundary facts +ok 77 - successful ERP executor results expose consistent lifecycle boundary facts + --- + duration_ms: 1.840791 + type: 'test' + ... +# Subtest: reconciliation can only be downgraded to no-write with explicit page evidence +ok 78 - reconciliation can only be downgraded to no-write with explicit page evidence + --- + duration_ms: 0.205584 + type: 'test' + ... +# Subtest: success receipts require verifiable ERP evidence +ok 79 - success receipts require verifiable ERP evidence + --- + duration_ms: 0.100583 + type: 'test' + ... +# Subtest: multi-date split-order probes require complete child facts and no manual review +ok 80 - multi-date split-order probes require complete child facts and no manual review + --- + duration_ms: 0.359875 + type: 'test' + ... +# Subtest: unified lifecycle response plus fresh requery is accepted as completion evidence +ok 81 - unified lifecycle response plus fresh requery is accepted as completion evidence + --- + duration_ms: 0.302542 + type: 'test' + ... +# Subtest: passenger list explicit server success does not require a post-save row requery +ok 82 - passenger list explicit server success does not require a post-save row requery + --- + duration_ms: 0.167583 + type: 'test' + ... +# Subtest: backend-attached export requires frozen hashes and explicit no-delivery evidence before it becomes a success receipt +ok 83 - backend-attached export requires frozen hashes and explicit no-delivery evidence before it becomes a success receipt + --- + duration_ms: 0.58925 + type: 'test' + ... +# Subtest: confirmation export archives visitor XLS, delivers real XLSX, and converts other types to PDF +ok 84 - confirmation export archives visitor XLS, delivers real XLSX, and converts other types to PDF + --- + duration_ms: 2046.092083 + type: 'test' + ... +# Subtest: visitor XLSX conversion failure blocks export delivery instead of returning raw XLS +ok 85 - visitor XLSX conversion failure blocks export delivery instead of returning raw XLS + --- + duration_ms: 7.223958 + type: 'test' + ... +# Subtest: pre-write ERP blockers remain explicit after plugin dispatch +ok 86 - pre-write ERP blockers remain explicit after plugin dispatch + --- + duration_ms: 0.537792 + type: 'test' + ... +# Subtest: write-capable running progress is not mislabeled as write-started +ok 87 - write-capable running progress is not mislabeled as write-started + --- + duration_ms: 0.239541 + type: 'test' + ... +# Subtest: successful parse events show Agent return and explicit pre-plugin no-write boundaries +ok 88 - successful parse events show Agent return and explicit pre-plugin no-write boundaries + --- + duration_ms: 0.392834 + type: 'test' + ... +# Subtest: lifecycle live-write authority is removed after parsing and injected only by manual confirmation +ok 89 - lifecycle live-write authority is removed after parsing and injected only by manual confirmation + --- + duration_ms: 1.357667 + type: 'test' + ... +# Subtest: normal lifecycle confirmation keeps platform metadata outside the business operation +ok 90 - normal lifecycle confirmation keeps platform metadata outside the business operation + --- + duration_ms: 0.11125 + type: 'test' + ... +# Subtest: lifecycle delete authorization rechecks the frozen evidence and allowlist at confirmation time +ok 91 - lifecycle delete authorization rechecks the frozen evidence and allowlist at confirmation time + --- + duration_ms: 0.398 + type: 'test' + ... +# Subtest: uncertain ERP writes have a reconciliation-specific failure code +ok 92 - uncertain ERP writes have a reconciliation-specific failure code + --- + duration_ms: 0.476125 + type: 'test' + ... +# Subtest: successful parse lifecycle facts are not promoted to a task failure +ok 93 - successful parse lifecycle facts are not promoted to a task failure + --- + duration_ms: 0.139042 + type: 'test' + ... +# Subtest: expired plugin results fail safely and preserve reconciliation when the write boundary is unknown +ok 94 - expired plugin results fail safely and preserve reconciliation when the write boundary is unknown + --- + duration_ms: 0.118167 + type: 'test' + ... +# Subtest: ERP business-rule rejection preserves the native message for the user +ok 95 - ERP business-rule rejection preserves the native message for the user + --- + duration_ms: 0.061709 + type: 'test' + ... +# Subtest: passenger capacity rejection preserves the business message and retains technical evidence +ok 96 - passenger capacity rejection preserves the business message and retains technical evidence + --- + duration_ms: 0.053 + type: 'test' + ... +# Subtest: nested ERP business feedback is promoted when the executor omitted failure metadata +ok 97 - nested ERP business feedback is promoted when the executor omitted failure metadata + --- + duration_ms: 0.052292 + type: 'test' + ... +# Subtest: ERP migration enforces one execution attempt per task +ok 98 - ERP migration enforces one execution attempt per task + --- + duration_ms: 2.794875 + type: 'test' + ... +# Subtest: task session migration binds one encrypted conversation to each task +ok 99 - task session migration binds one encrypted conversation to each task + --- + duration_ms: 0.974583 + type: 'test' + ... +# Subtest: task outcome migration stores independently timestamped success and error summaries +ok 100 - task outcome migration stores independently timestamped success and error summaries + --- + duration_ms: 0.800917 + type: 'test' + ... +# Subtest: task source migration distinguishes manual and AgentBus tasks +ok 101 - task source migration distinguishes manual and AgentBus tasks + --- + duration_ms: 0.8895 + type: 'test' + ... +# Subtest: organization automation migration persists the switch and task confirmation mode +ok 102 - organization automation migration persists the switch and task confirmation mode + --- + duration_ms: 0.878541 + type: 'test' + ... +# Subtest: task query optimization migration adds bounded list and event indexes +ok 103 - task query optimization migration adds bounded list and event indexes + --- + duration_ms: 9.618833 + type: 'test' + ... +# Subtest: task artifact migration keeps encrypted bytes scoped to the owning task +ok 104 - task artifact migration keeps encrypted bytes scoped to the owning task + --- + duration_ms: 1.668375 + type: 'test' + ... +# Subtest: AgentBus channel migration scopes encrypted keys and durable replies +ok 105 - AgentBus channel migration scopes encrypted keys and durable replies + --- + duration_ms: 94.802792 + type: 'test' + ... +# Subtest: business parser migration snapshots modes and encrypts dual candidates +ok 106 - business parser migration snapshots modes and encrypts dual candidates + --- + duration_ms: 4.943667 + type: 'test' + ... +# Subtest: parser promotion uses immediate correctness checks without time, volume, or fallback-rate waits +ok 107 - parser promotion uses immediate correctness checks without time, volume, or fallback-rate waits + --- + duration_ms: 4.489 + type: 'test' + ... +# Subtest: persistent-session migration removes automatic expiry for active sessions +ok 108 - persistent-session migration removes automatic expiry for active sessions + --- + duration_ms: 35.135917 + type: 'test' + ... +# Subtest: operator page has a login gate and uses the durable task API +ok 109 - operator page has a login gate and uses the durable task API + --- + duration_ms: 28.847209 + type: 'test' + ... +# Subtest: system task events persist a null actor instead of an invalid empty UUID +ok 110 - system task events persist a null actor instead of an invalid empty UUID + --- + duration_ms: 0.466334 + type: 'test' + ... +# Subtest: public task wrappers keep session IDs out of operation and transport metadata +ok 111 - public task wrappers keep session IDs out of operation and transport metadata + --- + duration_ms: 1.258083 + type: 'test' + ... +# Subtest: public task exposes persisted outcome timestamps and keeps the latest error summary +ok 112 - public task exposes persisted outcome timestamps and keeps the latest error summary + --- + duration_ms: 0.740666 + type: 'test' + ... +# Subtest: platform only synthesizes an error timeline entry for a currently failed task +ok 113 - platform only synthesizes an error timeline entry for a currently failed task + --- + duration_ms: 51.535958 + type: 'test' + ... +# Subtest: diagnostic errors preserve code and stack location without leaking the error message +ok 114 - diagnostic errors preserve code and stack location without leaking the error message + --- + duration_ms: 12.676708 + type: 'test' + ... +# Subtest: diagnostic request identifiers and paths are stable and query-safe +ok 115 - diagnostic request identifiers and paths are stable and query-safe + --- + duration_ms: 0.358625 + type: 'test' + ... +# Subtest: control-plane logger redacts credentials and includes deployment identity +ok 116 - control-plane logger redacts credentials and includes deployment identity + --- + duration_ms: 28.144083 + type: 'test' + ... +# Subtest: HTTP diagnostics reuse one request ID and never log query values +ok 117 - HTTP diagnostics reuse one request ID and never log query values + --- + duration_ms: 227.8315 + type: 'test' + ... +# Subtest: successful heartbeats, health probes and workbench polling stay silent while their handlers still run +ok 118 - successful heartbeats, health probes and workbench polling stay silent while their handlers still run + --- + duration_ms: 137.3765 + type: 'test' + ... +# Subtest: failed heartbeats and readiness probes retain severity, error codes and request correlation +ok 119 - failed heartbeats and readiness probes retain severity, error codes and request correlation + --- + duration_ms: 51.542542 + type: 'test' + ... +# Subtest: polling failures stay visible and task writes and detail reads keep access logs +ok 120 - polling failures stay visible and task writes and detail reads keep access logs + --- + duration_ms: 172.245834 + type: 'test' + ... +# Subtest: automation settings reads are quiet but failures and actual settings changes remain visible +ok 121 - automation settings reads are quiet but failures and actual settings changes remain visible + --- + duration_ms: 56.8775 + type: 'test' + ... +# Subtest: task state and audit diagnostics record keys but never business values +ok 122 - task state and audit diagnostics record keys but never business values + --- + duration_ms: 0.591 + type: 'test' + ... +# Subtest: production configuration rejects raw AgentBus payload logging +ok 123 - production configuration rejects raw AgentBus payload logging + --- + duration_ms: 0.650458 + type: 'test' + ... +# Subtest: same execution read-only failure resolves provisional dispatch uncertainty +ok 124 - same execution read-only failure resolves provisional dispatch uncertainty + --- + duration_ms: 0.968083 + type: 'test' + ... +# Subtest: maintenance-expired dispatch uncertainty still accepts the original explicit no-write result +ok 125 - maintenance-expired dispatch uncertainty still accepts the original explicit no-write result + --- + duration_ms: 0.160125 + type: 'test' + ... +# Subtest: late no-write resolution enforces execution, original connection and immutable state boundaries +ok 126 - late no-write resolution enforces execution, original connection and immutable state boundaries + --- + duration_ms: 0.224083 + type: 'test' + ... +# Subtest: true post-write uncertainty and prior native evidence cannot be overwritten +ok 127 - true post-write uncertainty and prior native evidence cannot be overwritten + --- + duration_ms: 0.091875 + type: 'test' + ... +# Subtest: bare no-write flags, contradictory write evidence and non-lookup results are rejected +ok 128 - bare no-write flags, contradictory write evidence and non-lookup results are rejected + --- + duration_ms: 4.552416 + type: 'test' + ... +# Subtest: page-level no-write evidence must be complete and internally consistent +ok 129 - page-level no-write evidence must be complete and internally consistent + --- + duration_ms: 1.427 + type: 'test' + ... +# Subtest: provisional timeout cannot replace already-received plugin progress or a final outcome +ok 130 - provisional timeout cannot replace already-received plugin progress or a final outcome + --- + duration_ms: 0.541291 + type: 'test' + ... +# Subtest: real result-ingestion transaction closes only eligible dispatch failures and emits consistent facts +ok 131 - real result-ingestion transaction closes only eligible dispatch failures and emits consistent facts + --- + duration_ms: 45.090709 + type: 'test' + ... +# Subtest: PDF sources pass through with PDF metadata +ok 132 - PDF sources pass through with PDF metadata + --- + duration_ms: 5.604208 + type: 'test' + ... +# Subtest: conversion failure falls back to the source file +ok 133 - conversion failure falls back to the source file + --- + duration_ms: 23.144958 + type: 'test' + ... +# Subtest: PDF conversion selects Writer HTML import only for HTML documents + # Subtest: ERP Word HTML with vendor MIME + ok 1 - ERP Word HTML with vendor MIME + --- + duration_ms: 3183.038625 + type: 'test' + ... + # Subtest: HTML doctype in a Word file + ok 2 - HTML doctype in a Word file + --- + duration_ms: 19.268625 + type: 'test' + ... + # Subtest: legacy body-only Word HTML + ok 3 - legacy body-only Word HTML + --- + duration_ms: 13.866083 + type: 'test' + ... + # Subtest: HTML extension + ok 4 - HTML extension + --- + duration_ms: 111.203417 + type: 'test' + ... + # Subtest: HTML MIME without extension + ok 5 - HTML MIME without extension + --- + duration_ms: 42.652791 + type: 'test' + ... + # Subtest: binary Word + ok 6 - binary Word + --- + duration_ms: 22.517583 + type: 'test' + ... + # Subtest: DOCX package + ok 7 - DOCX package + --- + duration_ms: 22.204584 + type: 'test' + ... + # Subtest: RTF + ok 8 - RTF + --- + duration_ms: 27.527541 + type: 'test' + ... + 1..8 +ok 134 - PDF conversion selects Writer HTML import only for HTML documents + --- + duration_ms: 3450.644333 + type: 'test' + ... +# Subtest: a valid converter output replaces the source with a PDF +ok 135 - a valid converter output replaces the source with a PDF + --- + duration_ms: 872.201917 + type: 'test' + ... +# Subtest: HTML-in-XLS visitor sources become real XLSX workbooks +ok 136 - HTML-in-XLS visitor sources become real XLSX workbooks + --- + duration_ms: 870.364208 + type: 'test' + ... +# Subtest: visitor XLSX conversion failure remains a source fallback +ok 137 - visitor XLSX conversion failure remains a source fallback + --- + duration_ms: 5.733583 + type: 'test' + ... +# Subtest: wide Word HTML tables are scaled to the printable width before conversion +ok 138 - wide Word HTML tables are scaled to the printable width before conversion + --- + duration_ms: 889.244125 + type: 'test' + ... +# Subtest: external webhook request uses the confirmed fixed contract exactly +ok 139 - external webhook request uses the confirmed fixed contract exactly + --- + duration_ms: 143.093709 + type: 'test' + ... +# Subtest: external webhook accepts only HTTP 200 with code zero and data true +ok 140 - external webhook accepts only HTTP 200 with code zero and data true + --- + duration_ms: 4.992917 + type: 'test' + ... +# {"level":30,"time":1790658580545,"pid":47932,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.initialized","diagnostic_stage":"startup","host":"127.0.0.1","port":8786,"log_level":"info","database_schema":"public","database_ssl":"disable","artifact_storage_backend":"database","agentbus_enabled":false,"leader_summary_webhook_enabled":false,"leader_summary_webhook_configuration_error":"webhook_configuration_incomplete","parser_loop_enabled":false,"data_retention_enabled":false,"raw_payload_logging":false,"msg":"control plane initialized"} +# Subtest: webhook configuration is fail-closed and independent from AgentBus configuration +ok 141 - webhook configuration is fail-closed and independent from AgentBus configuration + --- + duration_ms: 34.752042 + type: 'test' + ... +# Subtest: client rejects blank content and malformed tokens before making a request +ok 142 - client rejects blank content and malformed tokens before making a request + --- + duration_ms: 1.117584 + type: 'test' + ... +# {"level":30,"time":1790658580703,"pid":47932,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.closing","diagnostic_stage":"shutdown","msg":"control plane closing"} +# {"level":30,"time":1790658580756,"pid":47932,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.initialized","diagnostic_stage":"startup","host":"127.0.0.1","port":8786,"log_level":"info","database_schema":"public","database_ssl":"disable","artifact_storage_backend":"database","agentbus_enabled":false,"leader_summary_webhook_enabled":true,"leader_summary_webhook_configuration_error":null,"parser_loop_enabled":false,"data_retention_enabled":false,"raw_payload_logging":false,"msg":"control plane initialized"} +# {"level":40,"time":1790658580779,"pid":47932,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"leader_summary.webhook_initialization_failed","notification_event":"webhook_initialization_failed","error_code":"EPERM","error_name":"Error","error_fingerprint":"14ff2b2c56f54be8a71944f4","error_stack":["at /Users//IdeaProjects/LWLT-AIBOT/node_modules/pg-pool/index.js:45:11","at process.processTicksAndRejections (node:internal/process/task_queues:103:5)","at async AuthService.getOrganization (/control-plane/src/auth.ts:214:20)","at async buildServer (/control-plane/src/server.ts:870:28)","at async TestContext. (/control-plane/test/external-webhook-client.test.ts:221:21)","at async Test.run (node:internal/test_runner/test:1054:7)","at async Test.processPendingSubtests (node:internal/test_runner/test:744:7)"],"error_errno":-1,"error_syscall":"connect","msg":"Leader summary webhook initialization failed; normal task services remain available"} +# Subtest: invalid configuration or webhook initialization failure does not block the normal HTTP service +ok 143 - invalid configuration or webhook initialization failure does not block the normal HTTP service + --- + duration_ms: 495.669459 + type: 'test' + ... +# {"level":30,"time":1790658580840,"pid":47932,"hostname":"andydeMacBook-Pro.local","service":"ltjt-control-plane","environment":"test","deployment_revision":"unknown","diagnostic_event":"service.closing","diagnostic_stage":"shutdown","msg":"control plane closing"} +# Subtest: hotel input splits five repeated group blocks and preserves multi-night stays and ordinary input +ok 144 - hotel input splits five repeated group blocks and preserves multi-night stays and ordinary input + --- + duration_ms: 303.323125 + type: 'test' + ... +# Subtest: the entire batch blocks on cross-team, missing field, duplicate, mixed action, invalid date and oversized input +ok 145 - the entire batch blocks on cross-team, missing field, duplicate, mixed action, invalid date and oversized input + --- + duration_ms: 33.048667 + type: 'test' + ... +# Subtest: all rows require bound, distinct write/requery evidence before whole-batch success +ok 146 - all rows require bound, distinct write/requery evidence before whole-batch success + --- + duration_ms: 3.138 + type: 'test' + ... +# Subtest: partial stop retains distinct successful ledger events and uncertainty never counts as success +ok 147 - partial stop retains distinct successful ledger events and uncertainty never counts as success + --- + duration_ms: 43.709041 + type: 'test' + ... +# Subtest: published operator batch example parses to three complete ordered stays +ok 148 - published operator batch example parses to three complete ordered stays + --- + duration_ms: 2.222375 + type: 'test' + ... +# Subtest: dated hotel replacement parses old dates separately from the new resource and count +ok 149 - dated hotel replacement parses old dates separately from the new resource and count + --- + duration_ms: 180.885708 + type: 'test' + ... +# Subtest: hotel replacement rejects missing dates, invalid count, reversed dates and mixed update styles +ok 150 - hotel replacement rejects missing dates, invalid count, reversed dates and mixed update styles + --- + duration_ms: 11.728875 + type: 'test' + ... +# Subtest: legacy hotel departure and count changes remain supported +ok 151 - legacy hotel departure and count changes remain supported + --- + duration_ms: 1.143833 + type: 'test' + ... +# Subtest: manual roster attachment base64 is bounded and hash verified +ok 152 - manual roster attachment base64 is bounded and hash verified + --- + duration_ms: 1.875375 + type: 'test' + ... +# Subtest: manual roster attachment rejects unsupported names, invalid base64 and mismatched hash +ok 153 - manual roster attachment rejects unsupported names, invalid base64 and mismatched hash + --- + duration_ms: 0.309584 + type: 'test' + ... +# Subtest: AgentBus attachment URLs allow private HTTPS endpoints but reject unsafe URL syntax +ok 154 - AgentBus attachment URLs allow private HTTPS endpoints but reject unsafe URL syntax + --- + duration_ms: 1.233416 + type: 'test' + ... +# Subtest: AgentBus attachment metadata is normalized without exposing URL credentials +ok 155 - AgentBus attachment metadata is normalized without exposing URL credentials + --- + duration_ms: 0.720208 + type: 'test' + ... +# Subtest: AgentBus attachment DNS accepts internal names and private literal addresses +ok 156 - AgentBus attachment DNS accepts internal names and private literal addresses + --- + duration_ms: 88.329708 + type: 'test' + ... +# Subtest: AgentBus attachment DNS pinning follows the Node lookup callback shape +ok 157 - AgentBus attachment DNS pinning follows the Node lookup callback shape + --- + duration_ms: 11.00275 + type: 'test' + ... +# Subtest: AgentBus attachment diagnostics expose stages and codes without URL data +ok 158 - AgentBus attachment diagnostics expose stages and codes without URL data + --- + duration_ms: 3.219 + type: 'test' + ... +# Subtest: input attachment migration stores only encrypted normalized data and waiting-task index +ok 159 - input attachment migration stores only encrypted normalized data and waiting-task index + --- + duration_ms: 9.28675 + type: 'test' + ... +# Subtest: migration retires only the legacy leader-summary transport and creates an encrypted webhook outbox +ok 160 - migration retires only the legacy leader-summary transport and creates an encrypted webhook outbox + --- + duration_ms: 74.234875 + type: 'test' + ... +# Subtest: webhook worker is independent from normal task execution and AgentBus delivery +ok 161 - webhook worker is independent from normal task execution and AgentBus delivery + --- + duration_ms: 5.884083 + type: 'test' + ... +# Subtest: projection is organization-scoped, future-only, role-safe, source-limited and encrypted +ok 162 - projection is organization-scoped, future-only, role-safe, source-limited and encrypted + --- + duration_ms: 4.175417 + type: 'test' + ... +# Subtest: delivery makes one attempt and preserves ambiguous outcomes instead of retrying +ok 163 - delivery makes one attempt and preserves ambiguous outcomes instead of retrying + --- + duration_ms: 3.004292 + type: 'test' + ... +# Subtest: HTTP exposes administrator-only status and no mutation or live test-send endpoint +ok 164 - HTTP exposes administrator-only status and no mutation or live test-send endpoint + --- + duration_ms: 4.42425 + type: 'test' + ... +# Subtest: administrator UI explains the isolated fixed webhook and accepted-not-delivered semantics +ok 165 - administrator UI explains the isolated fixed webhook and accepted-not-delivered semantics + --- + duration_ms: 8.800209 + type: 'test' + ... +# Subtest: notification shows the original multiline input and omits the generated task-number field +ok 166 - notification shows the original multiline input and omits the generated task-number field + --- + duration_ms: 88.280375 + type: 'test' + ... +# Subtest: original input is available even when parsing failed or the business route is unknown +ok 167 - original input is available even when parsing failed or the business route is unknown + --- + duration_ms: 1.020292 + type: 'test' + ... +# Subtest: result-update messages retain the original input and full result +ok 168 - result-update messages retain the original input and full result + --- + duration_ms: 0.320292 + type: 'test' + ... +# Subtest: input formatting preserves punctuation and tabs, normalizes newlines and removes nonprinting controls +ok 169 - input formatting preserves punctuation and tabs, normalizes newlines and removes nonprinting controls + --- + duration_ms: 0.14225 + type: 'test' + ... +# Subtest: missing input has an explicit fallback without inventing input from a receipt +ok 170 - missing input has an explicit fallback without inventing input from a receipt + --- + duration_ms: 0.423542 + type: 'test' + ... +# Subtest: UTF-8 budget retains fitting inputs and visibly truncates only overflowing input +ok 171 - UTF-8 budget retains fitting inputs and visibly truncates only overflowing input + --- + duration_ms: 0.670667 + type: 'test' + ... +# Subtest: very long Chinese and emoji input cannot break Unicode or displace the outcome +ok 172 - very long Chinese and emoji input cannot break Unicode or displace the outcome + --- + duration_ms: 0.698042 + type: 'test' + ... +# Subtest: worker reads the same encrypted original input for manual and AgentBus tasks +ok 173 - worker reads the same encrypted original input for manual and AgentBus tasks + --- + duration_ms: 5.855541 + type: 'test' + ... +# Subtest: missing, invalid or unreadable ciphertext does not prevent a notification +ok 174 - missing, invalid or unreadable ciphertext does not prevent a notification + --- + duration_ms: 2.209917 + type: 'test' + ... +# Subtest: leader summary projects only stable outcomes +ok 175 - leader summary projects only stable outcomes + --- + duration_ms: 0.395041 + type: 'test' + ... +# Subtest: completed leader summary exposes only whitelisted business identifiers +ok 176 - completed leader summary exposes only whitelisted business identifiers + --- + duration_ms: 0.27125 + type: 'test' + ... +# Subtest: failure, uncertainty, cancellation and dry-run use stable safe wording +ok 177 - failure, uncertainty, cancellation and dry-run use stable safe wording + --- + duration_ms: 0.283375 + type: 'test' + ... +# Subtest: a stable result after needs-review produces one result-update milestone +ok 178 - a stable result after needs-review produces one result-update milestone + --- + duration_ms: 0.105541 + type: 'test' + ... +# Subtest: Shanghai timestamp formatting is deterministic and invalid-safe +ok 179 - Shanghai timestamp formatting is deterministic and invalid-safe + --- + duration_ms: 0.090417 + type: 'test' + ... +# Subtest: control plane keeps only the operation timing allowlisted shape +ok 180 - control plane keeps only the operation timing allowlisted shape + --- + duration_ms: 1.540292 + type: 'test' + ... +# Subtest: control plane rejects unknown timing contracts +ok 181 - control plane rejects unknown timing contracts + --- + duration_ms: 0.070125 + type: 'test' + ... +# Subtest: control plane accepts every plugin page-action timing code +ok 182 - control plane accepts every plugin page-action timing code + --- + duration_ms: 0.295333 + type: 'test' + ... +# Subtest: control plane keeps the privacy-safe orchestration breakdown used to locate unattributed time +ok 183 - control plane keeps the privacy-safe orchestration breakdown used to locate unattributed time + --- + duration_ms: 0.135792 + type: 'test' + ... +# Subtest: only roster routes pause at intake until a workbook arrives +ok 184 - only roster routes pause at intake until a workbook arrives + --- + duration_ms: 3.466 + type: 'test' + ... +# Subtest: attachment-only AgentBus frames are eligible inbound tasks +ok 185 - attachment-only AgentBus frames are eligible inbound tasks + --- + duration_ms: 1.869375 + type: 'test' + ... +# Subtest: roster attachment source contract gates claims and scrubs normalized plaintext +ok 186 - roster attachment source contract gates claims and scrubs normalized plaintext + --- + duration_ms: 26.341125 + type: 'test' + ... +# Subtest: a newly delivered message revalidates previously rejected attachment bytes +ok 187 - a newly delivered message revalidates previously rejected attachment bytes + --- + duration_ms: 5.463708 + type: 'test' + ... +# Subtest: durable roster replies distinguish waiting and attachment phases and select one final owner +ok 188 - durable roster replies distinguish waiting and attachment phases and select one final owner + --- + duration_ms: 12.310458 + type: 'test' + ... +# Subtest: manual API accepts exactly one bounded inline roster attachment +ok 189 - manual API accepts exactly one bounded inline roster attachment + --- + duration_ms: 1.341291 + type: 'test' + ... +# Subtest: automatic roster target query uses newest creation time and preserves all scope filters +ok 190 - automatic roster target query uses newest creation time and preserves all scope filters + --- + duration_ms: 16.786542 + type: 'test' + ... +# Subtest: explicit target still selects an older task and validates channel and conversation +ok 191 - explicit target still selects an older task and validates channel and conversation + --- + duration_ms: 3.112917 + type: 'test' + ... +# Subtest: missing conversation or eligible target never falls back to an unrelated task +ok 192 - missing conversation or eligible target never falls back to an unrelated task + --- + duration_ms: 3.08175 + type: 'test' + ... +# Subtest: attachment transaction writes only its selected task and keeps race and replay protections +ok 193 - attachment transaction writes only its selected task and keeps race and replay protections + --- + duration_ms: 2.475708 + type: 'test' + ... +# Subtest: roster tail: 28 passengers survive stale template formulas and a merged footer unchanged +ok 194 - roster tail: 28 passengers survive stale template formulas and a merged footer unchanged + --- + duration_ms: 543.743917 + type: 'test' + ... +# Subtest: roster tail: sequence-only placeholders and separated trailing notes are not passengers +ok 195 - roster tail: sequence-only placeholders and separated trailing notes are not passengers + --- + duration_ms: 350.633917 + type: 'test' + ... +# Subtest: roster tail: recognition follows semantic columns after reordering +ok 196 - roster tail: recognition follows semantic columns after reordering + --- + duration_ms: 73.57775 + type: 'test' + ... +# Subtest: roster tail: any supplied passenger field keeps a row subject to strict formula validation +ok 197 - roster tail: any supplied passenger field keeps a row subject to strict formula validation + --- + duration_ms: 422.962792 + type: 'test' + ... +# Subtest: roster tail: unrecognized formulas and notes cannot be silently discarded +ok 198 - roster tail: unrecognized formulas and notes cannot be silently discarded + --- + duration_ms: 213.318083 + type: 'test' + ... +# Subtest: roster tail: placeholders or notes inside the roster never hide later passengers +ok 199 - roster tail: placeholders or notes inside the roster never hide later passengers + --- + duration_ms: 234.332458 + type: 'test' + ... +# Subtest: roster tail: empty templates do not create phantom passengers +ok 200 - roster tail: empty templates do not create phantom passengers + --- + duration_ms: 33.9245 + type: 'test' + ... +# Subtest: roster tail: active content and hidden required data remain blocked across the whole sheet +ok 201 - roster tail: active content and hidden required data remain blocked across the whole sheet + --- + duration_ms: 128.211 + type: 'test' + ... +# Subtest: XLSX is deterministically normalized to the canonical 13-column TSV +ok 202 - XLSX is deterministically normalized to the canonical 13-column TSV + --- + duration_ms: 352.592834 + type: 'test' + ... +# Subtest: an absent phone header produces blank phones without guessing unheaded values +ok 203 - an absent phone header produces blank phones without guessing unheaded values + --- + duration_ms: 364.59075 + type: 'test' + ... +# Subtest: phone-free rosters support reordered alias headers, merged remarks and XLS conversion +ok 204 - phone-free rosters support reordered alias headers, merged remarks and XLS conversion + --- + duration_ms: 95.005917 + type: 'test' + ... +# Subtest: phone is the only optional semantic and duplicate phone headers stay blocked +ok 205 - phone is the only optional semantic and duplicate phone headers stay blocked + --- + duration_ms: 430.275 + type: 'test' + ... +# Subtest: present phone columns retain formula, value, hidden-data and row checks +ok 206 - present phone columns retain formula, value, hidden-data and row checks + --- + duration_ms: 123.926458 + type: 'test' + ... +# Subtest: a marked leader still requires a phone when the source phone column is absent +ok 207 - a marked leader still requires a phone when the source phone column is absent + --- + duration_ms: 28.100166 + type: 'test' + ... +# Subtest: a merged title error is skipped, while header and passenger errors stay blocked +ok 208 - a merged title error is skipped, while header and passenger errors stay blocked + --- + duration_ms: 134.779167 + type: 'test' + ... +# Subtest: same-row identity templates support 18 and 15 digit sources without exporting them +ok 209 - same-row identity templates support 18 and 15 digit sources without exporting them + --- + duration_ms: 83.456375 + type: 'test' + ... +# Subtest: identity references follow reordered columns, shared formulas and the workbook date system +ok 210 - identity references follow reordered columns, shared formulas and the workbook date system + --- + duration_ms: 26.96325 + type: 'test' + ... +# Subtest: identity formulas reject missing, stale or error results at the formula cell +ok 211 - identity formulas reject missing, stale or error results at the formula cell + --- + duration_ms: 71.588125 + type: 'test' + ... +# Subtest: identity dependencies must be unambiguous same-row template references +ok 212 - identity dependencies must be unambiguous same-row template references + --- + duration_ms: 210.614917 + type: 'test' + ... +# Subtest: invalid identity sources cannot validate a cached gender or birth date +ok 213 - invalid identity sources cannot validate a cached gender or birth date + --- + duration_ms: 216.447167 + type: 'test' + ... +# Subtest: populated identity formula rows are not discarded as empty trailing templates +ok 214 - populated identity formula rows are not discarded as empty trailing templates + --- + duration_ms: 39.266209 + type: 'test' + ... +# Subtest: a 22-person template passes normalization and program parsing with the last row as leader +ok 215 - a 22-person template passes normalization and program parsing with the last row as leader + --- + duration_ms: 25.953209 + type: 'test' + ... +# Subtest: the ERP field row is auto-detected and source columns may be reordered +ok 216 - the ERP field row is auto-detected and source columns may be reordered + --- + duration_ms: 135.575875 + type: 'test' + ... +# Subtest: the approved attachment aliases and reverse issue-date formula are normalized +ok 217 - the approved attachment aliases and reverse issue-date formula are normalized + --- + duration_ms: 25.658375 + type: 'test' + ... +# Subtest: birthplace and expiry aliases preserve the canonical passenger fields and values +ok 218 - birthplace and expiry aliases preserve the canonical passenger fields and values + --- + duration_ms: 33.458875 + type: 'test' + ... +# Subtest: birthplace and expiry aliases cannot silently select duplicate semantic columns +ok 219 - birthplace and expiry aliases cannot silently select duplicate semantic columns + --- + duration_ms: 52.4035 + type: 'test' + ... +# Subtest: source header order may vary, but every required label must appear exactly once +ok 220 - source header order may vary, but every required label must appear exactly once + --- + duration_ms: 41.55075 + type: 'test' + ... +# Subtest: legacy XLS is accepted only through an injected fail-closed converter +ok 221 - legacy XLS is accepted only through an injected fail-closed converter + --- + duration_ms: 22.482833 + type: 'test' + ... +# Subtest: identity cards and other non-import columns are ignored without leaking values +ok 222 - identity cards and other non-import columns are ignored without leaking values + --- + duration_ms: 12.804584 + type: 'test' + ... +# Subtest: source document type is ignored and canonical ERP document type remains passport +ok 223 - source document type is ignored and canonical ERP document type remains passport + --- + duration_ms: 13.430458 + type: 'test' + ... +# Subtest: sequence numbers must be positive and unique +ok 224 - sequence numbers must be positive and unique + --- + duration_ms: 25.985166 + type: 'test' + ... +# Subtest: unsafe formulas stay blocked while ignored columns do not affect selected fields +ok 225 - unsafe formulas stay blocked while ignored columns do not affect selected fields + --- + duration_ms: 57.482666 + type: 'test' + ... +# Subtest: macros, external relationships and ambiguous sheets fail closed +ok 226 - macros, external relationships and ambiguous sheets fail closed + --- + duration_ms: 21.46025 + type: 'test' + ... +# Subtest: hidden non-empty rows or columns and duplicate headers fail closed +ok 227 - hidden non-empty rows or columns and duplicate headers fail closed + --- + duration_ms: 23.117959 + type: 'test' + ... +# Subtest: format, MIME, conversion output and technical limits are validated before parsing +ok 228 - format, MIME, conversion output and technical limits are validated before parsing + --- + duration_ms: 797.856084 + type: 'test' + ... +# Subtest: roster, shared-child batch and four arrangement update routes are hard Program-only in the machine registry +ok 229 - roster, shared-child batch and four arrangement update routes are hard Program-only in the machine registry + --- + duration_ms: 13.805459 + type: 'test' + ... +# Subtest: hard Program-only task snapshots stay Program with missing or hostile stored settings +ok 230 - hard Program-only task snapshots stay Program with missing or hostile stored settings + --- + duration_ms: 17.6905 + type: 'test' + ... +# Subtest: the public route mutation rejects AI, Shadow, and Auto before touching settings storage +ok 231 - the public route mutation rejects AI, Shadow, and Auto before touching settings storage + --- + duration_ms: 4.279542 + type: 'test' + ... +# Subtest: TaskService exposes and enforces the registry parser policy at every AI override boundary +ok 232 - TaskService exposes and enforces the registry parser policy at every AI override boundary + --- + duration_ms: 14.574792 + type: 'test' + ... +# Subtest: the machine registry contains the 23 independent routes exactly once +ok 233 - the machine registry contains the 23 independent routes exactly once + --- + duration_ms: 1.549708 + type: 'test' + ... +# Subtest: machine routes stay synchronized with their declared Program or Agent boundary +ok 234 - machine routes stay synchronized with their declared Program or Agent boundary + --- + duration_ms: 3.892542 + type: 'test' + ... +# Subtest: versioned sanitized gold corpus replays deterministically +ok 235 - versioned sanitized gold corpus replays deterministically + --- + duration_ms: 199.326708 + type: 'test' + ... +# Subtest: all 23 official-format examples produce contract-valid operations +ok 236 - all 23 official-format examples produce contract-valid operations + --- + duration_ms: 25.763584 + type: 'test' + ... +# Subtest: shared-child batch input compiles the inclusive cross-month range without exposing an Agent action +ok 237 - shared-child batch input compiles the inclusive cross-month range without exposing an Agent action + --- + duration_ms: 0.434167 + type: 'test' + ... +# Subtest: passenger TSV preserves 13 columns when the final passenger has empty optional fields +ok 238 - passenger TSV preserves 13 columns when the final passenger has empty optional fields + --- + duration_ms: 6.60075 + type: 'test' + ... +# Subtest: passenger TSV rejects actual 12-column and 14-column data rows +ok 239 - passenger TSV rejects actual 12-column and 14-column data rows + --- + duration_ms: 0.617042 + type: 'test' + ... +# Subtest: passenger TSV promotes only an exact leader remark into structured ERP contact data +ok 240 - passenger TSV promotes only an exact leader remark into structured ERP contact data + --- + duration_ms: 0.581375 + type: 'test' + ... +# Subtest: passenger TSV rejects duplicate leaders or a leader without both name and phone +ok 241 - passenger TSV rejects duplicate leaders or a leader without both name and phone + --- + duration_ms: 0.901083 + type: 'test' + ... +# Subtest: independent room updates accept DBL shorthand without dropping other intentions +ok 242 - independent room updates accept DBL shorthand without dropping other intentions + --- + duration_ms: 7.542083 + type: 'test' + ... +# Subtest: independent headcount distributions keep occupied and non-occupied children distinct +ok 243 - independent headcount distributions keep occupied and non-occupied children distinct + --- + duration_ms: 3.108333 + type: 'test' + ... +# Subtest: named references retain original fullwidth spelling and internal whitespace in keyword +ok 244 - named references retain original fullwidth spelling and internal whitespace in keyword + --- + duration_ms: 1.952541 + type: 'test' + ... +# Subtest: registered customer typo is normalized only in name while keyword preserves source +ok 245 - registered customer typo is normalized only in name while keyword preserves source + --- + duration_ms: 1.128042 + type: 'test' + ... +# Subtest: route and field labels allow only a unique one-character correction +ok 246 - route and field labels allow only a unique one-character correction + --- + duration_ms: 0.619167 + type: 'test' + ... +# Subtest: route resolution is source-agnostic for embedded directives and complete unique field signatures +ok 247 - route resolution is source-agnostic for embedded directives and complete unique field signatures + --- + duration_ms: 14.913666 + type: 'test' + ... +# Subtest: unknown labels are eligible for auto fallback, but invalid values and conflicts are not +ok 248 - unknown labels are eligible for auto fallback, but invalid values and conflicts are not + --- + duration_ms: 2.971542 + type: 'test' + ... +# Subtest: business-value errors stay on the deterministic path instead of becoming contract fallbacks +ok 249 - business-value errors stay on the deterministic path instead of becoming contract fallbacks + --- + duration_ms: 1.889958 + type: 'test' + ... +# Subtest: independent updates require an exact registered target name +ok 250 - independent updates require an exact registered target name + --- + duration_ms: 0.499666 + type: 'test' + ... +# Subtest: later turns overwrite prior fields while an unlabeled supplement fills exactly one missing field +ok 251 - later turns overwrite prior fields while an unlabeled supplement fills exactly one missing field + --- + duration_ms: 0.470833 + type: 'test' + ... +# Subtest: a second business directive cannot be merged into the same task +ok 252 - a second business directive cannot be merged into the same task + --- + duration_ms: 0.396125 + type: 'test' + ... +# Subtest: passenger TSV rejects duplicate sequence numbers without changing any value +ok 253 - passenger TSV rejects duplicate sequence numbers without changing any value + --- + duration_ms: 0.314125 + type: 'test' + ... +# Subtest: all export expands deterministically and pickup sign requires a visitor name +ok 254 - all export expands deterministically and pickup sign requires a visitor name + --- + duration_ms: 0.496125 + type: 'test' + ... +# Subtest: whole shared-plan visitor information stays distinct from order and child visitor lists +ok 255 - whole shared-plan visitor information stays distinct from order and child visitor lists + --- + duration_ms: 4.560167 + type: 'test' + ... +# Subtest: date normalization handles next occurrence, cross-year ranges, and leap days +ok 256 - date normalization handles next occurrence, cross-year ranges, and leap days + --- + duration_ms: 1.555375 + type: 'test' + ... +# Subtest: modification dates use the next occurrence and preserve explicit years +ok 257 - modification dates use the next occurrence and preserve explicit years + --- + duration_ms: 1.662542 + type: 'test' + ... +# Subtest: a yearless modification date supplied on a later turn uses that turn date context +ok 258 - a yearless modification date supplied on a later turn uses that turn date context + --- + duration_ms: 0.380542 + type: 'test' + ... +# Subtest: cancel and restore dates use the next occurrence and preserve explicit years +ok 259 - cancel and restore dates use the next occurrence and preserve explicit years + --- + duration_ms: 0.838166 + type: 'test' + ... +# Subtest: deterministic parser meets the ordinary and large-list local P95 budgets +ok 260 - deterministic parser meets the ordinary and large-list local P95 budgets + --- + duration_ms: 343.440375 + type: 'test' + ... +# Subtest: semantic comparator ignores safe ordering but reports changed operation fields +ok 261 - semantic comparator ignores safe ordering but reports changed operation fields + --- + duration_ms: 1.381 + type: 'test' + ... +# Subtest: mode orchestration keeps AI authority in Shadow and enforces the Auto fallback allowlist +ok 262 - mode orchestration keeps AI authority in Shadow and enforces the Auto fallback allowlist + --- + duration_ms: 6.514042 + type: 'test' + ... +# Subtest: repeated hotel blocks always use their deterministic batch contract even with AI affinity +ok 263 - repeated hotel blocks always use their deterministic batch contract even with AI affinity + --- + duration_ms: 1.510834 + type: 'test' + ... +# Subtest: hotel arrangement uses the customer bilingual booking template +ok 264 - hotel arrangement uses the customer bilingual booking template + --- + duration_ms: 1.182541 + type: 'test' + ... +# Subtest: hotel clear and update replies stay business-readable when the booking template is not applicable +ok 265 - hotel clear and update replies stay business-readable when the booking template is not applicable + --- + duration_ms: 2.780125 + type: 'test' + ... +# Subtest: hotel replacement reply describes the new hotel and count while retaining the original dates +ok 266 - hotel replacement reply describes the new hotel and count while retaining the original dates + --- + duration_ms: 0.167 + type: 'test' + ... +# Subtest: batch newbooking receipt preserves every group number +ok 267 - batch newbooking receipt preserves every group number + --- + duration_ms: 0.09125 + type: 'test' + ... +# Subtest: update and file replies expose business fields without technical evidence +ok 268 - update and file replies expose business fields without technical evidence + --- + duration_ms: 3.407 + type: 'test' + ... +# Subtest: visitor export reply exposes only the mobile XLSX delivery artifact +ok 269 - visitor export reply exposes only the mobile XLSX delivery artifact + --- + duration_ms: 0.248458 + type: 'test' + ... +# Subtest: legacy ERP mojibake filenames are repaired when a stored receipt is read +ok 270 - legacy ERP mojibake filenames are repaired when a stored receipt is read + --- + duration_ms: 0.38275 + type: 'test' + ... +# Subtest: arrangement replacement receipts report the new resource and quantity with original dates +ok 271 - arrangement replacement receipts report the new resource and quantity with original dates + --- + duration_ms: 0.188708 + type: 'test' + ... +# Subtest: all business actions project accepted success without roster contents or arbitrary result fields +ok 272 - all business actions project accepted success without roster contents or arbitrary result fields + --- + duration_ms: 2.354291 + type: 'test' + ... +# Subtest: failed, uncertain, blocker and unproved results do not create completed business records +ok 273 - failed, uncertain, blocker and unproved results do not create completed business records + --- + duration_ms: 3.487417 + type: 'test' + ... +# Subtest: individual group conflicts are rejected and full suffixes remain distinct +ok 274 - individual group conflicts are rejected and full suffixes remain distinct + --- + duration_ms: 0.255334 + type: 'test' + ... +# Subtest: internal identifiers and conflicting child-parent evidence cannot become group associations +ok 275 - internal identifiers and conflicting child-parent evidence cannot become group associations + --- + duration_ms: 0.107667 + type: 'test' + ... +# Subtest: batch children are explicitly mapped to their respective parents, never zipped by array order +ok 276 - batch children are explicitly mapped to their respective parents, never zipped by array order + --- + duration_ms: 0.149 + type: 'test' + ... +# Subtest: native child-create receipts carry the verified parent; missing parents remain unlinked +ok 277 - native child-create receipts carry the verified parent; missing parents remain unlinked + --- + duration_ms: 0.077125 + type: 'test' + ... +# Subtest: roster counts use the latest import per subject and never add repeated uploads +ok 278 - roster counts use the latest import per subject and never add repeated uploads + --- + duration_ms: 28.320875 + type: 'test' + ... +# Subtest: shared-plan summaries separate each child and never claim every roster is complete +ok 279 - shared-plan summaries separate each child and never claim every roster is complete + --- + duration_ms: 0.561708 + type: 'test' + ... +# Subtest: cancel/restore updates current state without erasing arrangements or uncancelling children +ok 280 - cancel/restore updates current state without erasing arrangements or uncancelling children + --- + duration_ms: 1.166666 + type: 'test' + ... +# Subtest: verified parent cancellation propagates only proven child references +ok 281 - verified parent cancellation propagates only proven child references + --- + duration_ms: 0.479583 + type: 'test' + ... +# Subtest: all current arrangement rows render supported details; unknown legacy detail is explicit +ok 282 - all current arrangement rows render supported details; unknown legacy detail is explicit + --- + duration_ms: 0.224375 + type: 'test' + ... +# Subtest: exports are latest per file type and labelled stale after later changes without deleting records +ok 283 - exports are latest per file type and labelled stale after later changes without deleting records + --- + duration_ms: 0.608125 + type: 'test' + ... +# Subtest: receipts stay frozen and rebuilding never duplicates the progress block +ok 284 - receipts stay frozen and rebuilding never duplicates the progress block + --- + duration_ms: 0.950834 + type: 'test' + ... +# Subtest: encrypted ledger isolates accounts and organizations, deduplicates, and survives task deletion +ok 285 - encrypted ledger isolates accounts and organizations, deduplicates, and survives task deletion + --- + duration_ms: 1.38175 + type: 'test' + ... +# Subtest: unlinked child history joins only a uniquely known parent in the same account +ok 286 - unlinked child history joins only a uniquely known parent in the same account + --- + duration_ms: 0.719542 + type: 'test' + ... +# Subtest: history backfill preserves only the matching successful execution including archived tasks +ok 287 - history backfill preserves only the matching successful execution including archived tasks + --- + duration_ms: 0.687083 + type: 'test' + ... +# Subtest: migration preserves business records without task foreign keys and prevents administrator ownership +ok 288 - migration preserves business records without task foreign keys and prevents administrator ownership + --- + duration_ms: 5.519834 + type: 'test' + ... +# Subtest: partial batches retain only independently verified completed rows +ok 289 - partial batches retain only independently verified completed rows + --- + duration_ms: 2.154 + type: 'test' + ... +# Subtest: batch team dates follow their own receipt rows and never copy a date onto all groups +ok 290 - batch team dates follow their own receipt rows and never copy a date onto all groups + --- + duration_ms: 0.455208 + type: 'test' + ... +# Subtest: channel length limits clearly disclose truncation while leaving short replies unchanged +ok 291 - channel length limits clearly disclose truncation while leaving short replies unchanged + --- + duration_ms: 1.826208 + type: 'test' + ... +1..291 +# tests 299 +# suites 0 +# pass 299 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 10093.032375 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/http-tests.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/http-tests.txt new file mode 100644 index 0000000..9751a2d --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/http-tests.txt @@ -0,0 +1,12 @@ +▶ business-system HTTP boundary + ✔ returns the real AI connectivity probe from /api/status (19.389709ms) + ✔ exposes /api/parse and no longer exposes /api/agent routes (4.931792ms) +✔ business-system HTTP boundary (25.077166ms) +ℹ tests 2 +ℹ suites 1 +ℹ pass 2 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 135.24725 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/legacy-tests-sandbox.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/legacy-tests-sandbox.txt new file mode 100644 index 0000000..35f29bb --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/legacy-tests-sandbox.txt @@ -0,0 +1,2766 @@ +TAP version 13 +# Subtest: account creation accepts any non-empty password and blocks an empty password before the request +ok 1 - account creation accepts any non-empty password and blocks an empty password before the request + --- + duration_ms: 2.069291 + type: 'test' + ... +# Subtest: account creation normalizes valid form values into the server contract +ok 2 - account creation normalizes valid form values into the server contract + --- + duration_ms: 0.485208 + type: 'test' + ... +# Subtest: account creation translates backend password validation into an actionable message +ok 3 - account creation translates backend password validation into an actionable message + --- + duration_ms: 4.948791 + type: 'test' + ... +# Subtest: account forms expose no length rule or first-login forced-password flow +ok 4 - account forms expose no length rule or first-login forced-password flow + --- + duration_ms: 7.323792 + type: 'test' + ... +# Subtest: login after an unauthenticated page load starts ongoing status recovery without reload +ok 5 - login after an unauthenticated page load starts ongoing status recovery without reload + --- + duration_ms: 168.108041 + type: 'test' + ... +# Subtest: a pending task-list refresh does not stop bridge health or subsequent heartbeat recovery +ok 6 - a pending task-list refresh does not stop bridge health or subsequent heartbeat recovery + --- + duration_ms: 2.516625 + type: 'test' + ... +# Subtest: a two-second worker/ERP response stays connected and reaches the server heartbeat +ok 7 - a two-second worker/ERP response stays connected and reaches the server heartbeat + --- + duration_ms: 1.424667 + type: 'test' + ... +# Subtest: simultaneous focus and manual checks coalesce into one account-bound probe +ok 8 - simultaneous focus and manual checks coalesce into one account-bound probe + --- + duration_ms: 1.698625 + type: 'test' + ... +# Subtest: late status replies after logout cannot publish a heartbeat or restore connected status +ok 9 - late status replies after logout cannot publish a heartbeat or restore connected status + --- + duration_ms: 1.1595 + type: 'test' + ... +# Subtest: bridge-ready announcement refreshes account-bound state and never accepts an unbound snapshot +ok 10 - bridge-ready announcement refreshes account-bound state and never accepts an unbound snapshot + --- + duration_ms: 1.705709 + type: 'test' + ... +# Subtest: an admin page never sends a plugin probe or worker heartbeat +ok 11 - an admin page never sends a plugin probe or worker heartbeat + --- + duration_ms: 3.099208 + type: 'test' + ... +# Subtest: repeated login retains one timer and one focus listener; logout makes polling inert +ok 12 - repeated login retains one timer and one focus listener; logout makes polling inert + --- + duration_ms: 6.111875 + type: 'test' + ... +# Subtest: server worker rejection remains a warning until a later verified heartbeat recovers +ok 13 - server worker rejection remains a warning until a later verified heartbeat recovers + --- + duration_ms: 3.893542 + type: 'test' + ... +# Subtest: an old session response cannot overwrite a newer session check or heartbeat identity +ok 14 - an old session response cannot overwrite a newer session check or heartbeat identity + --- + duration_ms: 1.598125 + type: 'test' + ... +# Subtest: five-second plugin acceptance no longer triggers the old four-second false timeout +ok 15 - five-second plugin acceptance no longer triggers the old four-second false timeout + --- + duration_ms: 3.295917 + type: 'test' + ... +# Subtest: a genuine acceptance timeout records uncertainty and never dispatches twice +ok 16 - a genuine acceptance timeout records uncertainty and never dispatches twice + --- + duration_ms: 66.99375 + type: 'test' + ... +# Subtest: dispatch uncertainty reads stored late blocked results with no ERP action or new claim +ok 17 - dispatch uncertainty reads stored late blocked results with no ERP action or new claim + --- + duration_ms: 84.239084 + type: 'test' + ... +# Subtest: late progress does not replace dispatch uncertainty or post another API result +ok 18 - late progress does not replace dispatch uncertainty or post another API result + --- + duration_ms: 3.660333 + type: 'test' + ... +# Subtest: a rejected stored result preserves the platform uncertainty state +ok 19 - a rejected stored result preserves the platform uncertainty state + --- + duration_ms: 12.707416 + type: 'test' + ... +# Subtest: post-write uncertainty keeps its existing manual reconciliation boundary +ok 20 - post-write uncertainty keeps its existing manual reconciliation boundary + --- + duration_ms: 1.398333 + type: 'test' + ... +# Subtest: maintenance-expired dispatch tasks can manually sync local plugin results without ERP reconciliation +ok 21 - maintenance-expired dispatch tasks can manually sync local plugin results without ERP reconciliation + --- + duration_ms: 1.509625 + type: 'test' + ... +# Subtest: other-account tasks cannot read, persist or dispatch plugin tasks +ok 22 - other-account tasks cannot read, persist or dispatch plugin tasks + --- + duration_ms: 1.234291 + type: 'test' + ... +# Subtest: dashboard summary cards are uniform display-only totals and leave filtering to the explicit controls +ok 23 - dashboard summary cards are uniform display-only totals and leave filtering to the explicit controls + --- + duration_ms: 1.291042 + type: 'test' + ... +# Subtest: waiting-for-input work is folded into in-progress instead of exposing a follow-up state +ok 24 - waiting-for-input work is folded into in-progress instead of exposing a follow-up state + --- + duration_ms: 0.230458 + type: 'test' + ... +# Subtest: dashboard route has a focused leadership header and phone-safe navigation shell +ok 25 - dashboard route has a focused leadership header and phone-safe navigation shell + --- + duration_ms: 0.213959 + type: 'test' + ... +# Subtest: phone dashboard turns metrics and task rows into touch-friendly cards +ok 26 - phone dashboard turns metrics and task rows into touch-friendly cards + --- + duration_ms: 0.539125 + type: 'test' + ... +# Subtest: table filters use a bounded single-connection read and default to 20 rows +ok 27 - table filters use a bounded single-connection read and default to 20 rows + --- + duration_ms: 0.619708 + type: 'test' + ... +# Subtest: workbench exposes one XLS/XLSX roster attachment without turning it into persistent state +ok 28 - workbench exposes one XLS/XLSX roster attachment without turning it into persistent state + --- + duration_ms: 3.222958 + type: 'test' + ... +# Subtest: new and awaiting roster tasks send a single in-memory base64 JSON attachment +ok 29 - new and awaiting roster tasks send a single in-memory base64 JSON attachment + --- + duration_ms: 0.340625 + type: 'test' + ... +# Subtest: awaiting_attachment has a dedicated attachment-only continuation UI +ok 30 - awaiting_attachment has a dedicated attachment-only continuation UI + --- + duration_ms: 0.163333 + type: 'test' + ... +# Subtest: parser routing visibly locks Program-only routes and keeps emergency wording accurate +ok 31 - parser routing visibly locks Program-only routes and keeps emergency wording accurate + --- + duration_ms: 0.092292 + type: 'test' + ... +# Subtest: external parser contract + # Subtest: validates canonical operation JSON locally without opening an Agent session + ok 1 - validates canonical operation JSON locally without opening an Agent session + --- + duration_ms: 14.966792 + type: 'test' + ... + # Subtest: rejects invalid canonical operation JSON locally without Agent repair + ok 2 - rejects invalid canonical operation JSON locally without Agent repair + --- + duration_ms: 1.074667 + type: 'test' + ... + # Subtest: creates a task-isolated session and sends the raw input through SSE + ok 3 - creates a task-isolated session and sends the raw input through SSE + --- + duration_ms: 25.022959 + type: 'test' + ... + # Subtest: repairs one contract-invalid response in the same session without dropping unknown fields + ok 4 - repairs one contract-invalid response in the same session without dropping unknown fields + --- + duration_ms: 1.870333 + type: 'test' + ... + # Subtest: repairs a stale other/filing item question in the same session + ok 5 - repairs a stale other/filing item question in the same session + --- + duration_ms: 5.905917 + type: 'test' + ... + # Subtest: repairs a stale modification year question in the same session + ok 6 - repairs a stale modification year question in the same session + --- + duration_ms: 54.04875 + type: 'test' + ... + # Subtest: repairs the reported stale restore year question in the same session + ok 7 - repairs the reported stale restore year question in the same session + --- + duration_ms: 1.913834 + type: 'test' + ... + # Subtest: reports the concrete unknown operation.data keys + ok 8 - reports the concrete unknown operation.data keys + --- + duration_ms: 0.214166 + type: 'test' + ... + # Subtest: returns NEED_INPUT without an operation and continues the same session on the next turn + ok 9 - returns NEED_INPUT without an operation and continues the same session on the next turn + --- + duration_ms: 103.340917 + type: 'test' + ... + # Subtest: rebuilds an expired session once and replays stored turns before the current turn + ok 10 - rebuilds an expired session once and replays stored turns before the current turn + --- + duration_ms: 2.542833 + type: 'test' + ... + # Subtest: returns a blocked result without making a request when the server key is absent + ok 11 - returns a blocked result without making a request when the server key is absent + --- + duration_ms: 0.199167 + type: 'test' + ... + # Subtest: probes the provider health endpoint without creating a session + ok 12 - probes the provider health endpoint without creating a session + --- + duration_ms: 0.440292 + type: 'test' + ... + # Subtest: reports an unhealthy provider endpoint as disconnected + ok 13 - reports an unhealthy provider endpoint as disconnected + --- + duration_ms: 0.166416 + type: 'test' + ... + # Subtest: maps external authorization and active-run errors without exposing the key + ok 14 - maps external authorization and active-run errors without exposing the key + --- + duration_ms: 0.229375 + type: 'test' + ... + # Subtest: rejects unsafe provider URLs and non-raw API keys + ok 15 - rejects unsafe provider URLs and non-raw API keys + --- + duration_ms: 0.074291 + type: 'test' + ... + # Subtest: retries one rate-limited request with the same stable idempotency key + ok 16 - retries one rate-limited request with the same stable idempotency key + --- + duration_ms: 0.71575 + type: 'test' + ... + # Subtest: uses one parse-wide rate-limit budget across session and stream + ok 17 - uses one parse-wide rate-limit budget across session and stream + --- + duration_ms: 0.376584 + type: 'test' + ... + # Subtest: redacts arbitrary provider errors, API keys and raw input + ok 18 - redacts arbitrary provider errors, API keys and raw input + --- + duration_ms: 0.196333 + type: 'test' + ... + # Subtest: returns a bounded cancellation result when an SSE body ignores cancel() + ok 19 - returns a bounded cancellation result when an SSE body ignores cancel() + --- + duration_ms: 1199.605375 + type: 'test' + ... + 1..19 +ok 32 - external parser contract + --- + duration_ms: 1414.237083 + type: 'suite' + ... +# Subtest: SSE and result helpers + # Subtest: parses CRLF SSE blocks and JSON objects wrapped in markdown + ok 1 - parses CRLF SSE blocks and JSON objects wrapped in markdown + --- + duration_ms: 0.391125 + type: 'test' + ... + # Subtest: returns after a terminal SSE event even if the provider keeps the stream open + ok 2 - returns after a terminal SSE event even if the provider keeps the stream open + --- + duration_ms: 0.599 + type: 'test' + ... + # Subtest: accepts a structured final event and preserves the operation contract + ok 3 - accepts a structured final event and preserves the operation contract + --- + duration_ms: 0.303125 + type: 'test' + ... + # Subtest: rejects provider-supplied runtime metadata from natural-language results + ok 4 - rejects provider-supplied runtime metadata from natural-language results + --- + duration_ms: 0.184834 + type: 'test' + ... + # Subtest: collects assistant chunks from the documented messages event shape + ok 5 - collects assistant chunks from the documented messages event shape + --- + duration_ms: 0.26925 + type: 'test' + ... + # Subtest: handles UTF-8 byte boundaries and CRLF while requiring a terminal event + ok 6 - handles UTF-8 byte boundaries and CRLF while requiring a terminal event + --- + duration_ms: 0.738625 + type: 'test' + ... + # Subtest: fails closed on oversized, incomplete and conflicting SSE output + # Subtest: oversized event + ok 1 - oversized event + --- + duration_ms: 0.970042 + type: 'test' + ... + # Subtest: event count limit + ok 2 - event count limit + --- + duration_ms: 0.42875 + type: 'test' + ... + # Subtest: missing terminal event + ok 3 - missing terminal event + --- + duration_ms: 0.347542 + type: 'test' + ... + # Subtest: conflicting candidates + ok 4 - conflicting candidates + --- + duration_ms: 0.336584 + type: 'test' + ... + # Subtest: wrong session content type + ok 5 - wrong session content type + --- + duration_ms: 0.2435 + type: 'test' + ... + 1..5 + ok 7 - fails closed on oversized, incomplete and conflicting SSE output + --- + duration_ms: 2.655583 + type: 'test' + ... + # Subtest: blocks the currently published flat parser shape instead of adapting it + ok 8 - blocks the currently published flat parser shape instead of adapting it + --- + duration_ms: 0.074666 + type: 'test' + ... + # Subtest: blocks camelCase flat fields emitted by the external Profile + ok 9 - blocks camelCase flat fields emitted by the external Profile + --- + duration_ms: 0.059084 + type: 'test' + ... + # Subtest: blocks the malformed formal batch payload that previously reached execution + ok 10 - blocks the malformed formal batch payload that previously reached execution + --- + duration_ms: 0.166125 + type: 'test' + ... + # Subtest: rolls yearless newbooking dates to the next occurrence using the task date + ok 11 - rolls yearless newbooking dates to the next occurrence using the task date + --- + duration_ms: 0.316417 + type: 'test' + ... + # Subtest: uses the current year for a future yearless newbooking date + ok 12 - uses the current year for a future yearless newbooking date + --- + duration_ms: 0.2705 + type: 'test' + ... + # Subtest: does not rewrite explicitly year-qualified newbooking dates + ok 13 - does not rewrite explicitly year-qualified newbooking dates + --- + duration_ms: 0.077917 + type: 'test' + ... + # Subtest: rolls yearless modification lookup dates to the next occurrence + ok 14 - rolls yearless modification lookup dates to the next occurrence + --- + duration_ms: 0.166875 + type: 'test' + ... + # Subtest: normalizes the reported shared-child 11-15 lookup without asking for a year + ok 15 - normalizes the reported shared-child 11-15 lookup without asking for a year + --- + duration_ms: 0.226 + type: 'test' + ... + # Subtest: normalizes modification target dates and preserves explicit years + ok 16 - normalizes modification target dates and preserves explicit years + --- + duration_ms: 0.229083 + type: 'test' + ... + # Subtest: normalizes a yearless hotel-change end date + ok 17 - normalizes a yearless hotel-change end date + --- + duration_ms: 0.138375 + type: 'test' + ... + # Subtest: normalizes cancel and restore lookup dates and preserves explicit years + ok 18 - normalizes cancel and restore lookup dates and preserves explicit years + --- + duration_ms: 0.28575 + type: 'test' + ... + # Subtest: rejects a stale year-only restore question so the client performs one contract repair + ok 19 - rejects a stale year-only restore question so the client performs one contract repair + --- + duration_ms: 0.075208 + type: 'test' + ... + # Subtest: rejects a stale year-only modification question so the client performs one contract repair + ok 20 - rejects a stale year-only modification question so the client performs one contract repair + --- + duration_ms: 0.099042 + type: 'test' + ... + # Subtest: uses original task history when a continuation only supplies a missing field + ok 21 - uses original task history when a continuation only supplies a missing field + --- + duration_ms: 0.1385 + type: 'test' + ... + # Subtest: preserves product/customer source-region context without semantic validation + ok 22 - preserves product/customer source-region context without semantic validation + --- + duration_ms: 0.083 + type: 'test' + ... + # Subtest: accepts missing source-region metadata without blocking + ok 23 - accepts missing source-region metadata without blocking + --- + duration_ms: 0.072334 + type: 'test' + ... + # Subtest: keeps shared-child guidance at user-visible business fields + ok 24 - keeps shared-child guidance at user-visible business fields + --- + duration_ms: 0.169584 + type: 'test' + ... + # Subtest: keeps the versioned router in the profile and the per-task message minimal + ok 25 - keeps the versioned router in the profile and the per-task message minimal + --- + duration_ms: 0.157541 + type: 'test' + ... + # Subtest: keeps shared-child batch creation Program-only and outside the external Agent router + ok 26 - keeps shared-child batch creation Program-only and outside the external Agent router + --- + duration_ms: 0.244292 + type: 'test' + ... + # Subtest: pins the optional other/filing fields in the per-task guidance + ok 27 - pins the optional other/filing fields in the per-task guidance + --- + duration_ms: 0.081958 + type: 'test' + ... + # Subtest: accepts a shared-child operation with only the visible parent reference + ok 28 - accepts a shared-child operation with only the visible parent reference + --- + duration_ms: 0.09425 + type: 'test' + ... + # Subtest: rejects internal parent identifiers in Agent output + ok 29 - rejects internal parent identifiers in Agent output + --- + duration_ms: 0.088625 + type: 'test' + ... + # Subtest: accepts multi-date shared-plan child facts without execution metadata + ok 30 - accepts multi-date shared-plan child facts without execution metadata + --- + duration_ms: 0.130958 + type: 'test' + ... + # Subtest: normalizes legacy flat shared-plan child fields into split_order + ok 31 - normalizes legacy flat shared-plan child fields into split_order + --- + duration_ms: 0.128375 + type: 'test' + ... + # Subtest: accepts parser-state lifecycle facts without requiring execution-state fields + ok 32 - accepts parser-state lifecycle facts without requiring execution-state fields + --- + duration_ms: 0.078 + type: 'test' + ... + # Subtest: treats ERP passenger rows as an initial baseline while retaining a 5000-row technical bound + ok 33 - treats ERP passenger rows as an initial baseline while retaining a 5000-row technical bound + --- + duration_ms: 0.862333 + type: 'test' + ... + # Subtest: accepts hotel arrangement input without a room type and leaves that field for ERP resolution + ok 34 - accepts hotel arrangement input without a room type and leaves that field for ERP resolution + --- + duration_ms: 0.533625 + type: 'test' + ... + # Subtest: accepts customer/date business lookup while keeping visible identifiers optional + ok 35 - accepts customer/date business lookup while keeping visible identifiers optional + --- + duration_ms: 2.36225 + type: 'test' + ... + # Subtest: accepts only visitor-list for a shared mother-plan export scope + ok 36 - accepts only visitor-list for a shared mother-plan export scope + --- + duration_ms: 0.910625 + type: 'test' + ... + # Subtest: allows a no-customer shared mother-plan capacity update when the departure date is present + ok 37 - allows a no-customer shared mother-plan capacity update when the departure date is present + --- + duration_ms: 1.947041 + type: 'test' + ... + # Subtest: preserves a complete independent passenger and room distribution as multiple update actions + ok 38 - preserves a complete independent passenger and room distribution as multiple update actions + --- + duration_ms: 0.588916 + type: 'test' + ... + # Subtest: passes Agent and plugin front-gate validation for every supported directive route + ok 39 - passes Agent and plugin front-gate validation for every supported directive route + --- + duration_ms: 2.249083 + type: 'test' + ... + # Subtest: blocks a generic Profile response instead of inventing an operation + ok 40 - blocks a generic Profile response instead of inventing an operation + --- + duration_ms: 0.092583 + type: 'test' + ... + # Subtest: turns a stale other/filing item question into a contract repair instead of asking the user + ok 41 - turns a stale other/filing item question into a contract repair instead of asking the user + --- + duration_ms: 0.093083 + type: 'test' + ... + # Subtest: derives a NEED_INPUT reply from validated question prompts when the Agent omitted the top-level reply + ok 42 - derives a NEED_INPUT reply from validated question prompts when the Agent omitted the top-level reply + --- + duration_ms: 0.115417 + type: 'test' + ... + # Subtest: still blocks NEED_INPUT when only internal missing fields exist without a displayable question + ok 43 - still blocks NEED_INPUT when only internal missing fields exist without a displayable question + --- + duration_ms: 0.084583 + type: 'test' + ... + 1..43 +ok 33 - SSE and result helpers + --- + duration_ms: 19.188542 + type: 'suite' + ... +# Subtest: business-system HTTP boundary + # Subtest: returns the real AI connectivity probe from /api/status + not ok 1 - returns the real AI connectivity probe from /api/status + --- + duration_ms: 11.730666 + type: 'test' + location: '/private/var/folders/8j/8xy_jbfj44n3_25rf409sklw0000gn/T/lwlt-hotel-remark-check-kto8y_b5/LianSyn-platform/external-agent-client.test.mjs:1934:3' + failureType: 'uncaughtException' + error: 'listen EPERM: operation not permitted 127.0.0.1' + code: 'EPERM' + stack: |- + Server.setupListenHandle [as _listen2] (node:net:1918:21) + listenInCluster (node:net:1997:12) + node:net:2206:7 + process.processTicksAndRejections (node:internal/process/task_queues:89:21) + ... + # Subtest: exposes /api/parse and no longer exposes /api/agent routes + not ok 2 - exposes /api/parse and no longer exposes /api/agent routes + --- + duration_ms: 2.061084 + type: 'test' + location: '/private/var/folders/8j/8xy_jbfj44n3_25rf409sklw0000gn/T/lwlt-hotel-remark-check-kto8y_b5/LianSyn-platform/external-agent-client.test.mjs:1966:3' + failureType: 'uncaughtException' + error: 'listen EPERM: operation not permitted 127.0.0.1' + code: 'EPERM' + stack: |- + Server.setupListenHandle [as _listen2] (node:net:1918:21) + listenInCluster (node:net:1997:12) + node:net:2206:7 + process.processTicksAndRejections (node:internal/process/task_queues:89:21) + ... + 1..2 +not ok 34 - business-system HTTP boundary + --- + duration_ms: 13.875583 + type: 'suite' + location: '/private/var/folders/8j/8xy_jbfj44n3_25rf409sklw0000gn/T/lwlt-hotel-remark-check-kto8y_b5/LianSyn-platform/external-agent-client.test.mjs:1933:1' + failureType: 'subtestsFailed' + error: '2 subtests failed' + code: 'ERR_TEST_FAILURE' + ... +# Subtest: vehicle create recovers from a delayed linkage sample but never saves while sampling stays delayed +ok 35 - vehicle create recovers from a delayed linkage sample but never saves while sampling stays delayed + --- + duration_ms: 303.396083 + type: 'test' + ... +# Subtest: vehicle create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 +ok 36 - vehicle create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 + --- + duration_ms: 437.450167 + type: 'test' + ... +# Subtest: vehicle requery follows the new record id after sorting, including stored reconciliation evidence +ok 37 - vehicle requery follows the new record id after sorting, including stored reconciliation evidence + --- + duration_ms: 94.001333 + type: 'test' + ... +# Subtest: vehicle rejects no free row, drafts, financial state, missing controls and forced targets before POST +ok 38 - vehicle rejects no free row, drafts, financial state, missing controls and forced targets before POST + --- + duration_ms: 30.460208 + type: 'test' + ... +# Subtest: vehicle checks existing rows and new values after native linkage and again after validation +ok 39 - vehicle checks existing rows and new values after native linkage and again after validation + --- + duration_ms: 439.492333 + type: 'test' + ... +# Subtest: vehicle cannot claim completion if ERP changes an old row, misses or duplicates the new row +ok 40 - vehicle cannot claim completion if ERP changes an old row, misses or duplicates the new row + --- + duration_ms: 258.111875 + type: 'test' + ... +# Subtest: transport create recovers from a delayed linkage sample but never saves while sampling stays delayed +ok 41 - transport create recovers from a delayed linkage sample but never saves while sampling stays delayed + --- + duration_ms: 33.452667 + type: 'test' + ... +# Subtest: transport create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 +ok 42 - transport create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 + --- + duration_ms: 526.476375 + type: 'test' + ... +# Subtest: transport requery follows the new record id after sorting, including stored reconciliation evidence +ok 43 - transport requery follows the new record id after sorting, including stored reconciliation evidence + --- + duration_ms: 47.026417 + type: 'test' + ... +# Subtest: transport rejects no free row, drafts, financial state, missing controls and forced targets before POST +ok 44 - transport rejects no free row, drafts, financial state, missing controls and forced targets before POST + --- + duration_ms: 170.098334 + type: 'test' + ... +# Subtest: transport checks existing rows and new values after native linkage and again after validation +ok 45 - transport checks existing rows and new values after native linkage and again after validation + --- + duration_ms: 210.190292 + type: 'test' + ... +# Subtest: transport cannot claim completion if ERP changes an old row, misses or duplicates the new row +ok 46 - transport cannot claim completion if ERP changes an old row, misses or duplicates the new row + --- + duration_ms: 55.521042 + type: 'test' + ... +# Subtest: other create recovers from a delayed linkage sample but never saves while sampling stays delayed +ok 47 - other create recovers from a delayed linkage sample but never saves while sampling stays delayed + --- + duration_ms: 57.835792 + type: 'test' + ... +# Subtest: other create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 +ok 48 - other create preserves old rows and binds native selection, dates and quantity to empty rows 0/1/10 + --- + duration_ms: 341.014417 + type: 'test' + ... +# Subtest: other requery follows the new record id after sorting, including stored reconciliation evidence +ok 49 - other requery follows the new record id after sorting, including stored reconciliation evidence + --- + duration_ms: 58.231834 + type: 'test' + ... +# Subtest: other rejects no free row, drafts, financial state, missing controls and forced targets before POST +ok 50 - other rejects no free row, drafts, financial state, missing controls and forced targets before POST + --- + duration_ms: 135.5475 + type: 'test' + ... +# Subtest: other checks existing rows and new values after native linkage and again after validation +ok 51 - other checks existing rows and new values after native linkage and again after validation + --- + duration_ms: 338.914875 + type: 'test' + ... +# Subtest: other cannot claim completion if ERP changes an old row, misses or duplicates the new row +ok 52 - other cannot claim completion if ERP changes an old row, misses or duplicates the new row + --- + duration_ms: 111.721125 + type: 'test' + ... +# Subtest: transport creates in a departure-default row and preserves existing rows, spare rows and filing +ok 53 - transport creates in a departure-default row and preserves existing rows, spare rows and filing + --- + duration_ms: 1372.179 + type: 'test' + ... +# Subtest: transport rejects drafts and unverified dates even with other default-date rows available +ok 54 - transport rejects drafts and unverified dates even with other default-date rows available + --- + duration_ms: 425.272 + type: 'test' + ... +# Subtest: transport guards other default dates through native selection, validation and preflight changes +ok 55 - transport guards other default dates through native selection, validation and preflight changes + --- + duration_ms: 83.163458 + type: 'test' + ... +# Subtest: other creates in a departure-default row and preserves existing rows, spare rows and filing +ok 56 - other creates in a departure-default row and preserves existing rows, spare rows and filing + --- + duration_ms: 1025.139167 + type: 'test' + ... +# Subtest: other rejects drafts and unverified dates even with other default-date rows available +ok 57 - other rejects drafts and unverified dates even with other default-date rows available + --- + duration_ms: 207.524042 + type: 'test' + ... +# Subtest: other guards other default dates through native selection, validation and preflight changes +ok 58 - other guards other default dates through native selection, validation and preflight changes + --- + duration_ms: 30.735959 + type: 'test' + ... +# Subtest: vehicle still rejects an unsaved date equal to departure +ok 59 - vehicle still rejects an unsaved date equal to departure + --- + duration_ms: 2.684042 + type: 'test' + ... +# Subtest: other create keeps omitted quantity and shared filing, and verifies them after sorted requery +ok 60 - other create keeps omitted quantity and shared filing, and verifies them after sorted requery + --- + duration_ms: 17.762916 + type: 'test' + ... +# Subtest: other preserves omitted zero quantity in a default-date row +ok 61 - other preserves omitted zero quantity in a default-date row + --- + duration_ms: 15.912417 + type: 'test' + ... +# Subtest: other create may fill blank filing fields, blocks conflicting filing and preserves realized state +ok 62 - other create may fill blank filing fields, blocks conflicting filing and preserves realized state + --- + duration_ms: 98.47 + type: 'test' + ... +# Subtest: other native callbacks cannot alter omitted shared filing or the realized flag +ok 63 - other native callbacks cannot alter omitted shared filing or the realized flag + --- + duration_ms: 103.505958 + type: 'test' + ... +# Subtest: guide remains single-person: an occupied guide gives the change-command message without selecting or saving +ok 64 - guide remains single-person: an occupied guide gives the change-command message without selecting or saving + --- + duration_ms: 1.316833 + type: 'test' + ... +# Subtest: guide empty-slot guard still accepts the native single-row form +ok 65 - guide empty-slot guard still accepts the native single-row form + --- + duration_ms: 2.866333 + type: 'test' + ... +# Subtest: background preserves both create evidence types and maps the guide business error +ok 66 - background preserves both create evidence types and maps the guide business error + --- + duration_ms: 3.536125 + type: 'test' + ... +# Subtest: ordinary linkage requires multiple observations over 1.5 seconds and redacts values +ok 67 - ordinary linkage requires multiple observations over 1.5 seconds and redacts values + --- + duration_ms: 4.283041 + type: 'test' + ... +# Subtest: one delayed callback restarts observation instead of failing or counting the blind interval +ok 68 - one delayed callback restarts observation instead of failing or counting the blind interval + --- + duration_ms: 0.631292 + type: 'test' + ... +# Subtest: one-second sampling still proves stability; persistent long gaps fail boundedly +ok 69 - one-second sampling still proves stability; persistent long gaps fail boundedly + --- + duration_ms: 0.833708 + type: 'test' + ... +# Subtest: continuous value changes fail and report field names rather than their values +ok 70 - continuous value changes fail and report field names rather than their values + --- + duration_ms: 1.549625 + type: 'test' + ... +# Subtest: the last allowed sample is checked; a late change restarts stability +ok 71 - the last allowed sample is checked; a late change restarts stability + --- + duration_ms: 1.104334 + type: 'test' + ... +# Subtest: detached form, missing/replaced controls and pending native Ajax cannot pass +ok 72 - detached form, missing/replaced controls and pending native Ajax cannot pass + --- + duration_ms: 5.5975 + type: 'test' + ... +# Subtest: background reports the observed failure reason without classifying all failures as changing fields +ok 73 - background reports the observed failure reason without classifying all failures as changing fields + --- + duration_ms: 0.561 + type: 'test' + ... +# Subtest: dated updates report missing MAIN-world dependency without changing native fields; guide stays independent +ok 74 - dated updates report missing MAIN-world dependency without changing native fields; guide stays independent + --- + duration_ms: 86.066917 + type: 'test' + ... +# Subtest: guide update resolves the original record and preserves dates and unspecified fields +ok 75 - guide update resolves the original record and preserves dates and unspecified fields + --- + duration_ms: 138.767458 + type: 'test' + ... +# Subtest: vehicle update resolves the original record and preserves dates and unspecified fields +ok 76 - vehicle update resolves the original record and preserves dates and unspecified fields + --- + duration_ms: 64.637167 + type: 'test' + ... +# Subtest: transport update resolves the original record and preserves dates and unspecified fields +ok 77 - transport update resolves the original record and preserves dates and unspecified fields + --- + duration_ms: 24.959125 + type: 'test' + ... +# Subtest: other update resolves the original record and preserves dates and unspecified fields +ok 78 - other update resolves the original record and preserves dates and unspecified fields + --- + duration_ms: 187.557459 + type: 'test' + ... +# Subtest: missing or ambiguous original records never trigger a native selection +ok 79 - missing or ambiguous original records never trigger a native selection + --- + duration_ms: 30.675375 + type: 'test' + ... +# Subtest: old row identity, audit, payment and realized flags stop the update before mutation +ok 80 - old row identity, audit, payment and realized flags stop the update before mutation + --- + duration_ms: 93.465583 + type: 'test' + ... +# Subtest: other update merges filing changes, preserves filing date and omitted zero quantity +ok 81 - other update merges filing changes, preserves filing date and omitted zero quantity + --- + duration_ms: 23.04925 + type: 'test' + ... +# Subtest: date changes are rejected and native callbacks cannot change dates, IDs or other rows +ok 82 - date changes are rejected and native callbacks cannot change dates, IDs or other rows + --- + duration_ms: 290.018125 + type: 'test' + ... +# Subtest: vehicle create AND-filters type and supplier, preserves native description and original dates +ok 83 - vehicle create AND-filters type and supplier, preserves native description and original dates + --- + duration_ms: 7.429875 + type: 'test' + ... +# Subtest: vehicle update AND-filters type and supplier, preserves native description and original dates +ok 84 - vehicle update AND-filters type and supplier, preserves native description and original dates + --- + duration_ms: 4.057042 + type: 'test' + ... +# Subtest: vehicle filter never drops an unmatched type, picks an ambiguous row, or selects a different supplier +ok 85 - vehicle filter never drops an unmatched type, picks an ambiguous row, or selects a different supplier + --- + duration_ms: 220.749041 + type: 'test' + ... +# Subtest: changed vehicle candidates or type cannot reach form mutation after resolution +ok 86 - changed vehicle candidates or type cannot reach form mutation after resolution + --- + duration_ms: 46.383125 + type: 'test' + ... +# Subtest: vehicle filter is nonempty, vehicle-only and outside date selectors or direct changes in every contract +ok 87 - vehicle filter is nonempty, vehicle-only and outside date selectors or direct changes in every contract + --- + duration_ms: 40.716625 + type: 'test' + ... +# Subtest: transport create selects the unique supplier+ticket row through native linkage +ok 88 - transport create selects the unique supplier+ticket row through native linkage + --- + duration_ms: 10.85975 + type: 'test' + ... +# Subtest: transport update selects the unique supplier+ticket row through native linkage +ok 89 - transport update selects the unique supplier+ticket row through native linkage + --- + duration_ms: 5.407667 + type: 'test' + ... +# Subtest: explicit ticket filter never drops a keyword or defaults to the first ambiguous result +ok 90 - explicit ticket filter never drops a keyword or defaults to the first ambiguous result + --- + duration_ms: 22.723833 + type: 'test' + ... +# Subtest: transport create distinguishes route and train before an adjacent timetable +ok 91 - transport create distinguishes route and train before an adjacent timetable + --- + duration_ms: 180.239708 + type: 'test' + ... +# Subtest: transport update distinguishes route and train before an adjacent timetable +ok 92 - transport update distinguishes route and train before an adjacent timetable + --- + duration_ms: 85.413042 + type: 'test' + ... +# Subtest: description normalization preserves original numeric boundaries and existing formatting compatibility +ok 93 - description normalization preserves original numeric boundaries and existing formatting compatibility + --- + duration_ms: 1.78025 + type: 'test' + ... +# Subtest: route-only or train-only filters block with only the matching supplier candidates and no mutation +ok 94 - route-only or train-only filters block with only the matching supplier candidates and no mutation + --- + duration_ms: 50.274667 + type: 'test' + ... +# Subtest: ambiguous timetable candidates stay bounded and cannot default to an identical first row +ok 95 - ambiguous timetable candidates stay bounded and cannot default to an identical first row + --- + duration_ms: 3.795041 + type: 'test' + ... +# Subtest: transport route failures explain zero matches, unavailable data and bounded ambiguous candidates +ok 96 - transport route failures explain zero matches, unavailable data and bounded ambiguous candidates + --- + duration_ms: 30.901375 + type: 'test' + ... +# Subtest: changed ticket description or candidates block before any native call or mutation +ok 97 - changed ticket description or candidates block before any native call or mutation + --- + duration_ms: 116.262792 + type: 'test' + ... +# Subtest: ticket filter is nonempty, transport-only, and never a date selector or direct item update +ok 98 - ticket filter is nonempty, transport-only, and never a date selector or direct item update + --- + duration_ms: 19.095875 + type: 'test' + ... +# Subtest: native transport selection rechecks a filter even after preflight and never falls back to a different ID +ok 99 - native transport selection rechecks a filter even after preflight and never falls back to a different ID + --- + duration_ms: 66.5355 + type: 'test' + ... +# Subtest: vehicle month/day dates pass parsed contracts and resolve to a full-year execution snapshot +ok 100 - vehicle month/day dates pass parsed contracts and resolve to a full-year execution snapshot + --- + duration_ms: 8.7065 + type: 'test' + ... +# Subtest: transport month/day dates pass parsed contracts and resolve to a full-year execution snapshot +ok 101 - transport month/day dates pass parsed contracts and resolve to a full-year execution snapshot + --- + duration_ms: 5.205084 + type: 'test' + ... +# Subtest: other month/day dates pass parsed contracts and resolve to a full-year execution snapshot +ok 102 - other month/day dates pass parsed contracts and resolve to a full-year execution snapshot + --- + duration_ms: 14.15275 + type: 'test' + ... +# Subtest: parsed date-selector validators agree on invalid calendars while execution still requires a full year +ok 103 - parsed date-selector validators agree on invalid calendars while execution still requires a full year + --- + duration_ms: 55.765167 + type: 'test' + ... +# Subtest: ambiguous original dates are surfaced in the route failure message without native ids +ok 104 - ambiguous original dates are surfaced in the route failure message without native ids + --- + duration_ms: 5.031541 + type: 'test' + ... +# Subtest: fresh replay output creates missing parents and refuses to overwrite a run +ok 105 - fresh replay output creates missing parents and refuses to overwrite a run + --- + duration_ms: 10.157959 + type: 'test' + ... +# Subtest: template generates the four creation routes and all contracts agree +ok 106 - template generates the four creation routes and all contracts agree + --- + duration_ms: 1303.843292 + type: 'test' + ... +# Subtest: dedicated third-run shared batch probe carries customer and 15+1 facts through all three contracts +ok 107 - dedicated third-run shared batch probe carries customer and 15+1 facts through all three contracts + --- + duration_ms: 412.446959 + type: 'test' + ... +# Subtest: resolved state generates passenger, supported narrow updates, arrangement and source phases +ok 108 - resolved state generates passenger, supported narrow updates, arrangement and source phases + --- + duration_ms: 471.469333 + type: 'test' + ... +# Subtest: clear, transition and delete phases require progressively stronger evidence gates +ok 109 - clear, transition and delete phases require progressively stronger evidence gates + --- + duration_ms: 521.395042 + type: 'test' + ... +# Subtest: dynamic C04 children are deleted before every parent and every parent needs an explicit child-free proof +ok 110 - dynamic C04 children are deleted before every parent and every parent needs an explicit child-free proof + --- + duration_ms: 114.426417 + type: 'test' + ... +# Subtest: state validation rejects wrong owners, non-September targets and premature delete authorization +ok 111 - state validation rejects wrong owners, non-September targets and premature delete authorization + --- + duration_ms: 23.13475 + type: 'test' + ... +# Subtest: schema permits ERP-derived group prefix with an explicit suffix-only order number +ok 112 - schema permits ERP-derived group prefix with an explicit suffix-only order number + --- + duration_ms: 333.31675 + type: 'test' + ... +# Subtest: catalog has exactly 19 ordered operations with adjacent template and example blocks +ok 113 - catalog has exactly 19 ordered operations with adjacent template and example blocks + --- + duration_ms: 2.522083 + type: 'test' + ... +# Subtest: main prompt remains a compact Skill router +ok 114 - main prompt remains a compact Skill router + --- + duration_ms: 0.463375 + type: 'test' + ... +# Subtest: all packaged Skill sources contain only parsing knowledge +ok 115 - all packaged Skill sources contain only parsing knowledge + --- + duration_ms: 0.5595 + type: 'test' + ... +# Subtest: Agent parse Schema accepts business facts and rejects execution metadata +ok 116 - Agent parse Schema accepts business facts and rejects execution metadata + --- + duration_ms: 777.311625 + type: 'test' + ... +# Subtest: template fields are marked and examples contain only concrete values +ok 117 - template fields are marked and examples contain only concrete values + --- + duration_ms: 0.658708 + type: 'test' + ... +# Subtest: user templates never request ERP internal identifiers and use canonical customer label +ok 118 - user templates never request ERP internal identifiers and use canonical customer label + --- + duration_ms: 0.444959 + type: 'test' + ... +# Subtest: all Agent directives are routed to their Skill contract in the same two-block format +ok 119 - all Agent directives are routed to their Skill contract in the same two-block format + --- + duration_ms: 18.041458 + type: 'test' + ... +# Subtest: shared-child batch stays Program-only while remaining copyable from the operator catalog +ok 120 - shared-child batch stays Program-only while remaining copyable from the operator catalog + --- + duration_ms: 0.144875 + type: 'test' + ... +# Subtest: the four detailed business pages use adjacent template and example blocks +ok 121 - the four detailed business pages use adjacent template and example blocks + --- + duration_ms: 1.555708 + type: 'test' + ... +# Subtest: the two desktop-approved examples remain exactly copyable +ok 122 - the two desktop-approved examples remain exactly copyable + --- + duration_ms: 0.380333 + type: 'test' + ... +# Subtest: every operation preserves its explicit minimum-required field set +ok 123 - every operation preserves its explicit minimum-required field set + --- + duration_ms: 0.428084 + type: 'test' + ... +# Subtest: modification input asks only for targets and export stays minimal +ok 124 - modification input asks only for targets and export stays minimal + --- + duration_ms: 1.064083 + type: 'test' + ... +# Subtest: team-file export uses the business name while keeping the internal action stable +ok 125 - team-file export uses the business name while keeping the internal action stable + --- + duration_ms: 1.322125 + type: 'test' + ... +# Subtest: independent-order updates preserve broad parser targets while arrangement changes stay narrow +ok 126 - independent-order updates preserve broad parser targets while arrangement changes stay narrow + --- + duration_ms: 0.66225 + type: 'test' + ... +# Subtest: deferred items 20 to 22 are absent from current user and Skill input contracts +ok 127 - deferred items 20 to 22 are absent from current user and Skill input contracts + --- + duration_ms: 0.317584 + type: 'test' + ... +# Subtest: new business adaptation template enforces the two-block writing convention +ok 128 - new business adaptation template enforces the two-block writing convention + --- + duration_ms: 0.297542 + type: 'test' + ... +# Subtest: ERP account identity comparison accepts only normalized exact equality +ok 129 - ERP account identity comparison accepts only normalized exact equality + --- + duration_ms: 1.283666 + type: 'test' + ... +# Subtest: ERP account identity comparison rejects substrings and blank identities +ok 130 - ERP account identity comparison rejects substrings and blank identities + --- + duration_ms: 0.075 + type: 'test' + ... +# Subtest: ERP session probe reads the unique login label and never matches against whole-page text +ok 131 - ERP session probe reads the unique login label and never matches against whole-page text + --- + duration_ms: 0.676375 + type: 'test' + ... +# Subtest: normal lookup does not wait; business no-match and ambiguous results never retry +ok 132 - normal lookup does not wait; business no-match and ambiguous results never retry + --- + duration_ms: 3.180042 + type: 'test' + ... +# Subtest: removed query frame waits for a stable current document then reinjects and queries once +ok 133 - removed query frame waits for a stable current document then reinjects and queries once + --- + duration_ms: 4.645583 + type: 'test' + ... +# Subtest: frame removal during injection also safely recovers and identifies injection as failed step +ok 134 - frame removal during injection also safely recovers and identifies injection as failed step + --- + duration_ms: 1.913375 + type: 'test' + ... +# Subtest: repeated frame removal stops after two lookups with actual resolution failure stage and no-write evidence +ok 135 - repeated frame removal stops after two lookups with actual resolution failure stage and no-write evidence + --- + duration_ms: 4.496959 + type: 'test' + ... +# Subtest: moving/loading/missing-identity documents cannot pass readiness and the wait is bounded +ok 136 - moving/loading/missing-identity documents cannot pass readiness and the wait is bounded + --- + duration_ms: 9.925833 + type: 'test' + ... +# Subtest: permanent errors, closed tabs, and disallowed navigation do not rerun queries +ok 137 - permanent errors, closed tabs, and disallowed navigation do not rerun queries + --- + duration_ms: 3.919125 + type: 'test' + ... +# Subtest: retry requires the same running execution without a prior write boundary; cancellation propagates +ok 138 - retry requires the same running execution without a prior write boundary; cancellation propagates + --- + duration_ms: 6.922667 + type: 'test' + ... +# Subtest: exceptions before route, during route and during preflight retain the actual failure phase +ok 139 - exceptions before route, during route and during preflight retain the actual failure phase + --- + duration_ms: 2.189333 + type: 'test' + ... +# Subtest: frame removal at live submit is uncertain and never retried +ok 140 - frame removal at live submit is uncertain and never retried + --- + duration_ms: 1.013416 + type: 'test' + ... +# Subtest: production control-plane origin is recognized and bridge injection is permitted +ok 141 - production control-plane origin is recognized and bridge injection is permitted + --- + duration_ms: 34.743375 + type: 'test' + ... +# Subtest: ERP session keepalive is scheduled through alarms with a conservative default +ok 142 - ERP session keepalive is scheduled through alarms with a conservative default + --- + duration_ms: 10.855208 + type: 'test' + ... +# Subtest: ERP keepalive is an existing-tab read-only request and never a page reload or task write +ok 143 - ERP keepalive is an existing-tab read-only request and never a page reload or task write + --- + duration_ms: 4.108833 + type: 'test' + ... +# Subtest: ERP exception recovery refreshes the existing ERP tab once, then performs a read-only probe +ok 144 - ERP exception recovery refreshes the existing ERP tab once, then performs a read-only probe + --- + duration_ms: 5.556208 + type: 'test' + ... +# Subtest: an interrupted service worker recovery cannot leave ERP dispatch permanently blocked +ok 145 - an interrupted service worker recovery cannot leave ERP dispatch permanently blocked + --- + duration_ms: 3.542584 + type: 'test' + ... +# Subtest: keepalive setting and last probe state are visible without changing the business operation contract +ok 146 - keepalive setting and last probe state are visible without changing the business operation contract + --- + duration_ms: 2.60475 + type: 'test' + ... +# Subtest: a new ERP execution is accepted exactly once +ok 147 - a new ERP execution is accepted exactly once + --- + duration_ms: 16.923 + type: 'test' + ... +# Subtest: a different execution id for the same task is blocked +ok 148 - a different execution id for the same task is blocked + --- + duration_ms: 1.323209 + type: 'test' + ... +# Subtest: failures after the write boundary become uncertain +ok 149 - failures after the write boundary become uncertain + --- + duration_ms: 3.189875 + type: 'test' + ... +# Subtest: an explicit network-before-submit block is safe to classify as no ERP write +ok 150 - an explicit network-before-submit block is safe to classify as no ERP write + --- + duration_ms: 10.316417 + type: 'test' + ... +# Subtest: local extension history stays bounded without pruning active or uncertain roots +ok 151 - local extension history stays bounded without pruning active or uncertain roots + --- + duration_ms: 32.310792 + type: 'test' + ... +# Subtest: dispatch and schema accept only create batches with all ordinary per-row fields valid +ok 152 - dispatch and schema accept only create batches with all ordinary per-row fields valid + --- + duration_ms: 640.712959 + type: 'test' + ... +# Subtest: successful rows execute serially without prematurely finalizing the root task +ok 153 - successful rows execute serially without prematurely finalizing the root task + --- + duration_ms: 42.3245 + type: 'test' + ... +# Subtest: prewrite failure stops subsequent rows, retains saved prefix and stays known partial failure +ok 154 - prewrite failure stops subsequent rows, retains saved prefix and stays known partial failure + --- + duration_ms: 3.161708 + type: 'test' + ... +# Subtest: uncertain or missing response stops without retry and preserves both prefix and pending tail +ok 155 - uncertain or missing response stops without retry and preserves both prefix and pending tail + --- + duration_ms: 12.002 + type: 'test' + ... +# Subtest: read-only reconciliation resolves only the uncertain row and never starts the pending tail +ok 156 - read-only reconciliation resolves only the uncertain row and never starts the pending tail + --- + duration_ms: 2.828708 + type: 'test' + ... +# Subtest: timeout preserves an already-saved child and classifies a missing child as uncertain without replay +ok 157 - timeout preserves an already-saved child and classifies a missing child as uncertain without replay + --- + duration_ms: 2.447666 + type: 'test' + ... +# Subtest: production Docker runtime includes the shared batch evidence validator +ok 158 - production Docker runtime includes the shared batch evidence validator + --- + duration_ms: 0.324791 + type: 'test' + ... +# Subtest: a proven prewrite failure on the first row reports zero writes and leaves the rest untouched +ok 159 - a proven prewrite failure on the first row reports zero writes and leaves the rest untouched + --- + duration_ms: 2.15025 + type: 'test' + ... +# Subtest: hotel create binds the first empty row through preflight, native linkage, POST and fresh requery +ok 160 - hotel create binds the first empty row through preflight, native linkage, POST and fresh requery + --- + duration_ms: 385.8625 + type: 'test' + ... +# Subtest: 6/12-room hotel create recovers after delayed sampling, with only one native selection and POST +ok 161 - 6/12-room hotel create recovers after delayed sampling, with only one native selection and POST + --- + duration_ms: 116.465333 + type: 'test' + ... +# Subtest: unstable or persistently delayed hotel linkage records diagnostics and never saves +ok 162 - unstable or persistently delayed hotel linkage records diagnostics and never saves + --- + duration_ms: 55.040583 + type: 'test' + ... +# Subtest: hotel create matches the new record after ERP sorts rows and uses persisted evidence on read-only reconciliation +ok 163 - hotel create matches the new record after ERP sorts rows and uses persisted evidence on read-only reconciliation + --- + duration_ms: 108.536 + type: 'test' + ... +# Subtest: no free row, unsaved drafts, financial state and incomplete rows fail before any POST +ok 164 - no free row, unsaved drafts, financial state and incomplete rows fail before any POST + --- + duration_ms: 183.133375 + type: 'test' + ... +# Subtest: a caller cannot force a create target, and a changed preflight cannot silently choose another row +ok 165 - a caller cannot force a create target, and a changed preflight cannot silently choose another row + --- + duration_ms: 42.134167 + type: 'test' + ... +# Subtest: native callbacks cannot modify other rows, selected record id, or financial state +ok 166 - native callbacks cannot modify other rows, selected record id, or financial state + --- + duration_ms: 316.393167 + type: 'test' + ... +# Subtest: requery cannot report an old row, duplicate new rows, changed existing rows or wrong quantities as success +ok 167 - requery cannot report an old row, duplicate new rows, changed existing rows or wrong quantities as success + --- + duration_ms: 159.710333 + type: 'test' + ... +# Subtest: omitted hotel remarks survive selection/date callbacks, save and read-only requery +ok 168 - omitted hotel remarks survive selection/date callbacks, save and read-only requery + --- + duration_ms: 164.085125 + type: 'test' + ... +# Subtest: explicit hotel remark overrides the native default, while missing native notes remain empty +ok 169 - explicit hotel remark overrides the native default, while missing native notes remain empty + --- + duration_ms: 25.852 + type: 'test' + ... +# Subtest: native remark changes at validation block POST; missing or changed saved evidence cannot report success +ok 170 - native remark changes at validation block POST; missing or changed saved evidence cannot report success + --- + duration_ms: 208.374917 + type: 'test' + ... +# Subtest: batch orchestration preserves each hotel native or explicit remark through actual lifecycle execution +ok 171 - batch orchestration preserves each hotel native or explicit remark through actual lifecycle execution + --- + duration_ms: 163.960334 + type: 'test' + ... +# Subtest: hotel create accepts a complete two-row 76-field form after one stable second +ok 172 - hotel create accepts a complete two-row 76-field form after one stable second + --- + duration_ms: 62.213458 + type: 'test' + ... +# Subtest: hotel create fails closed without a form +ok 173 - hotel create fails closed without a form + --- + duration_ms: 0.805209 + type: 'test' + ... +# Subtest: hotel create accepts complete variable-size forms without a serialized count threshold +ok 174 - hotel create accepts complete variable-size forms without a serialized count threshold + --- + duration_ms: 101.325541 + type: 'test' + ... +# Subtest: hotel create rejects every missing required field even with more than 195 fields +ok 175 - hotel create rejects every missing required field even with more than 195 fields + --- + duration_ms: 945.1135 + type: 'test' + ... +# Subtest: hotel create waits for visible loading to disappear and then stabilize +ok 176 - hotel create waits for visible loading to disappear and then stabilize + --- + duration_ms: 8.207459 + type: 'test' + ... +# Subtest: hotel create requires a full observed stable second, including the final timeout sample +ok 177 - hotel create requires a full observed stable second, including the final timeout sample + --- + duration_ms: 33.343458 + type: 'test' + ... +# Subtest: hotel update/clear and unrelated lifecycle actions retain their current count gates +ok 178 - hotel update/clear and unrelated lifecycle actions retain their current count gates + --- + duration_ms: 28.275166 + type: 'test' + ... +# Subtest: 76-field readiness still leaves occupied slots and payment/audit state blocked +ok 179 - 76-field readiness still leaves occupied slots and payment/audit state blocked + --- + duration_ms: 24.183334 + type: 'test' + ... +# Subtest: full hotel preflight preserves identity, resource and ownership gates after structural readiness +ok 180 - full hotel preflight preserves identity, resource and ownership gates after structural readiness + --- + duration_ms: 145.854208 + type: 'test' + ... +# Subtest: hotel create rejects missing controls in later rows even on a large form +ok 181 - hotel create rejects missing controls in later rows even on a large form + --- + duration_ms: 519.647208 + type: 'test' + ... +# Subtest: hotel create rejects invalid row markers, omitted rows and gaps +ok 182 - hotel create rejects invalid row markers, omitted rows and gaps + --- + duration_ms: 193.859583 + type: 'test' + ... +# Subtest: hotel create rejects disabled, duplicate and id-only required data controls +ok 183 - hotel create rejects disabled, duplicate and id-only required data controls + --- + duration_ms: 101.23175 + type: 'test' + ... +# Subtest: hotel create rejects detached or replaced forms and unfinished documents +ok 184 - hotel create rejects detached or replaced forms and unfinished documents + --- + duration_ms: 32.107333 + type: 'test' + ... +# Subtest: same-count control replacement and select-option changes restart stability +ok 185 - same-count control replacement and select-option changes restart stability + --- + duration_ms: 233.723 + type: 'test' + ... +# Subtest: native pending ajax blocks hotel readiness even without a visible overlay +ok 186 - native pending ajax blocks hotel readiness even without a visible overlay + --- + duration_ms: 11.404416 + type: 'test' + ... +# Subtest: hotel replacement resolves a dated existing row and uses native linked selection on that row only +ok 187 - hotel replacement resolves a dated existing row and uses native linked selection on that row only + --- + duration_ms: 202.207042 + type: 'test' + ... +# Subtest: fresh ERP MAIN world resolves the reported 2027 hotel update using the actual injection list +ok 188 - fresh ERP MAIN world resolves the reported 2027 hotel update using the actual injection list + --- + duration_ms: 15.101541 + type: 'test' + ... +# Subtest: hotel replacement preserves the existing note unless the user supplies a new one +ok 189 - hotel replacement preserves the existing note unless the user supplies a new one + --- + duration_ms: 14.368833 + type: 'test' + ... +# Subtest: missing page date dependency is diagnosed before matching and never reported as zero ERP records +ok 190 - missing page date dependency is diagnosed before matching and never reported as zero ERP records + --- + duration_ms: 2.435583 + type: 'test' + ... +# Subtest: hotel replacement stops on ambiguous or missing dated rows before selecting a hotel +ok 191 - hotel replacement stops on ambiguous or missing dated rows before selecting a hotel + --- + duration_ms: 132.775708 + type: 'test' + ... +# Subtest: hotel replacement blocks stale row identity, payment, audit and confirmed status +ok 192 - hotel replacement blocks stale row identity, payment, audit and confirmed status + --- + duration_ms: 48.721959 + type: 'test' + ... +# Subtest: hotel replacement rejects native callbacks that change another row or change the record id +ok 193 - hotel replacement rejects native callbacks that change another row or change the record id + --- + duration_ms: 37.139042 + type: 'test' + ... +# Subtest: month/day hotel selector freezes the unique actual ERP year and preserves native dates on replacement +ok 194 - month/day hotel selector freezes the unique actual ERP year and preserves native dates on replacement + --- + duration_ms: 18.530958 + type: 'test' + ... +# Subtest: cross-year duplicate month/day rows remain ambiguous and report original dates before any mutation +ok 195 - cross-year duplicate month/day rows remain ambiguous and report original dates before any mutation + --- + duration_ms: 16.931292 + type: 'test' + ... +# Subtest: mixed TWN/DBL updates serialize both fields, preserve other rooms and verify a fresh GET +ok 196 - mixed TWN/DBL updates serialize both fields, preserve other rooms and verify a fresh GET + --- + duration_ms: 201.024417 + type: 'test' + ... +# Subtest: DBL zero is an explicit reset and identical room targets never resubmit +ok 197 - DBL zero is an explicit reset and identical room targets never resubmit + --- + duration_ms: 14.761416 + type: 'test' + ... +# Subtest: a successful POST cannot hide a missing or stale DBL value or total in fresh ERP data +ok 198 - a successful POST cannot hide a missing or stale DBL value or total in fresh ERP data + --- + duration_ms: 21.459166 + type: 'test' + ... +# Subtest: missing controls, invalid existing rooms and incorrect native totals stop before saving +ok 199 - missing controls, invalid existing rooms and incorrect native totals stop before saving + --- + duration_ms: 10.987042 + type: 'test' + ... +# Subtest: invalid DBL targets and unimplemented fields block the whole mixed operation +ok 200 - invalid DBL targets and unimplemented fields block the whole mixed operation + --- + duration_ms: 127.306541 + type: 'test' + ... +# Subtest: read-only reconciliation verifies the requested DBL field and never posts +ok 201 - read-only reconciliation verifies the requested DBL field and never posts + --- + duration_ms: 6.630875 + type: 'test' + ... +# Subtest: fixture uses the exact ERP TSV headers and 16 synthetic rows +ok 202 - fixture uses the exact ERP TSV headers and 16 synthetic rows + --- + duration_ms: 149.618375 + type: 'test' + ... +# Subtest: extension execution guard exposes the two queue maintenance deadlines +ok 203 - extension execution guard exposes the two queue maintenance deadlines + --- + duration_ms: 0.247375 + type: 'test' + ... +# Subtest: shared-child adapter waits for the async parent row and cross-checks the exact tid +ok 204 - shared-child adapter waits for the async parent row and cross-checks the exact tid + --- + duration_ms: 11.593958 + type: 'test' + ... +# Subtest: team-order customer restore accepts exact final values and rejects any protected-field drift +ok 205 - team-order customer restore accepts exact final values and rejects any protected-field drift + --- + duration_ms: 29.093333 + type: 'test' + ... +# Subtest: team-order protected-field drift matches the 0.5.156 core-field scope +ok 206 - team-order protected-field drift matches the 0.5.156 core-field scope + --- + duration_ms: 12.593875 + type: 'test' + ... +# Subtest: team-order live prewrite blocker exposes only changed protected field names +ok 207 - team-order live prewrite blocker exposes only changed protected field names + --- + duration_ms: 202.944083 + type: 'test' + ... +# Subtest: team-order live gate allows numbered receivable drift like 0.5.156 +ok 208 - team-order live gate allows numbered receivable drift like 0.5.156 + --- + duration_ms: 6.372209 + type: 'test' + ... +# Subtest: split-parent entry waits adaptively for the current iframe add button before clicking +ok 209 - split-parent entry waits adaptively for the current iframe add button before clicking + --- + duration_ms: 3.710167 + type: 'test' + ... +# Subtest: split-parent post-write verification retries read-only and falls back after any missed response group +ok 210 - split-parent post-write verification retries read-only and falls back after any missed response group + --- + duration_ms: 2.491292 + type: 'test' + ... +# Subtest: identifier-only native list searches receive a calendar-safe plus/minus one-year window +ok 211 - identifier-only native list searches receive a calendar-safe plus/minus one-year window + --- + duration_ms: 7.411041 + type: 'test' + ... +# Subtest: shared-child batch resolver expands the inclusive range and hard-matches concrete parent entry rows by product +ok 212 - shared-child batch resolver expands the inclusive range and hard-matches concrete parent entry rows by product + --- + duration_ms: 10.092625 + type: 'test' + ... +# Subtest: business lookup uses customer/date as the native primary lookup and keeps optional facts supplemental +ok 213 - business lookup uses customer/date as the native primary lookup and keeps optional facts supplemental + --- + duration_ms: 5.305667 + type: 'test' + ... +# Subtest: restore lookup explicitly visits the canceled native status tab +ok 214 - restore lookup explicitly visits the canceled native status tab + --- + duration_ms: 4.243125 + type: 'test' + ... +# Subtest: resolved cancellation uses verified list routes and derives one exact current status +ok 215 - resolved cancellation uses verified list routes and derives one exact current status + --- + duration_ms: 4.345334 + type: 'test' + ... +# Subtest: exact lifecycle edit identity accepts authoritative form refs and query-key variants +ok 216 - exact lifecycle edit identity accepts authoritative form refs and query-key variants + --- + duration_ms: 4.218458 + type: 'test' + ... +# Subtest: route preparation binds one opaque token only to the exact selected lifecycle document +ok 217 - route preparation binds one opaque token only to the exact selected lifecycle document + --- + duration_ms: 3.744 + type: 'test' + ... +# Subtest: shared-child leader uses the ERP transfer SelectBox, not the mother-plan filter +ok 218 - shared-child leader uses the ERP transfer SelectBox, not the mother-plan filter + --- + duration_ms: 4.924459 + type: 'test' + ... +# Subtest: team arrangement list search accepts the native PrintGridLists request +ok 219 - team arrangement list search accepts the native PrintGridLists request + --- + duration_ms: 8.074 + type: 'test' + ... +# Subtest: guide arrangement waits for async guide linkage and coordinator lookup hydration +ok 220 - guide arrangement waits for async guide linkage and coordinator lookup hydration + --- + duration_ms: 40.227375 + type: 'test' + ... +# Subtest: guide arrangement derives daoguan from the selected guide candidate, not the current operator +ok 221 - guide arrangement derives daoguan from the selected guide candidate, not the current operator + --- + duration_ms: 263.292084 + type: 'test' + ... +# Subtest: guide arrangement blocks when the selected guide has no linked daoguan +ok 222 - guide arrangement blocks when the selected guide has no linked daoguan + --- + duration_ms: 3.758583 + type: 'test' + ... +# Subtest: shared-child passenger lookup keeps a visible customer result when ERP nests child rows +ok 223 - shared-child passenger lookup keeps a visible customer result when ERP nests child rows + --- + duration_ms: 30.422333 + type: 'test' + ... +# Subtest: independent lookup keeps ERP rows whose update action is attached to the row +ok 224 - independent lookup keeps ERP rows whose update action is attached to the row + --- + duration_ms: 31.80375 + type: 'test' + ... +# Subtest: customer lifecycle lookup matches non-contiguous Chinese keyword tokens +ok 225 - customer lifecycle lookup matches non-contiguous Chinese keyword tokens + --- + duration_ms: 73.235875 + type: 'test' + ... +# Subtest: shared-child passenger lookup does not attach a parent customer to every nested child +ok 226 - shared-child passenger lookup does not attach a parent customer to every nested child + --- + duration_ms: 6.901209 + type: 'test' + ... +# Subtest: optional lookup facts narrow visible candidates without hard-filtering sparse rows +ok 227 - optional lookup facts narrow visible candidates without hard-filtering sparse rows + --- + duration_ms: 48.834875 + type: 'test' + ... +# Subtest: extension reload reconnects the current platform port and missing ERP identifiers return an actionable error +ok 228 - extension reload reconnects the current platform port and missing ERP identifiers return an actionable error + --- + duration_ms: 1.799208 + type: 'test' + ... +# Subtest: passenger lifecycle prepares the exact native import route before adapter preflight +ok 229 - passenger lifecycle prepares the exact native import route before adapter preflight + --- + duration_ms: 7.44775 + type: 'test' + ... +# Subtest: passenger rows normalize to canonical TSV and treat current ERP rows as an initial baseline, not an import limit +ok 230 - passenger rows normalize to canonical TSV and treat current ERP rows as an initial baseline, not an import limit + --- + duration_ms: 5.074375 + type: 'test' + ... +# Subtest: passenger merge fills explicit blank rows, preserves others, and protects occupied rows +ok 231 - passenger merge fills explicit blank rows, preserves others, and protects occupied rows + --- + duration_ms: 9.871708 + type: 'test' + ... +# Subtest: passenger adapter mirrors only native persisted fields and reports implicit passport semantics +ok 232 - passenger adapter mirrors only native persisted fields and reports implicit passport semantics + --- + duration_ms: 9.003958 + type: 'test' + ... +# Subtest: passenger explicit server success is terminal without a post-save row requery +ok 233 - passenger explicit server success is terminal without a post-save row requery + --- + duration_ms: 3.303166 + type: 'test' + ... +# Subtest: uncertain lifecycle writes can only converge through a read-only plugin requery +ok 234 - uncertain lifecycle writes can only converge through a read-only plugin requery + --- + duration_ms: 3.7855 + type: 'test' + ... +# Subtest: ERP business-rule rejections return the native message and stay out of reconciliation +ok 235 - ERP business-rule rejections return the native message and stay out of reconciliation + --- + duration_ms: 3.337334 + type: 'test' + ... +# Subtest: childless shared plans receive a precise hotel-arrangement ERP blocker +ok 236 - childless shared plans receive a precise hotel-arrangement ERP blocker + --- + duration_ms: 4.706333 + type: 'test' + ... +# Subtest: passenger native row capacity failures receive a precise business-facing ERP limit message +ok 237 - passenger native row capacity failures receive a precise business-facing ERP limit message + --- + duration_ms: 4.509125 + type: 'test' + ... +# Subtest: lifecycle execution keeps the MV3 worker alive until the durable task settles +ok 238 - lifecycle execution keeps the MV3 worker alive until the durable task settles + --- + duration_ms: 1.933875 + type: 'test' + ... +# Subtest: extension 0.5.191 keeps reload dormant unless its durable execution state is fully idle +ok 239 - extension 0.5.191 keeps reload dormant unless its durable execution state is fully idle + --- + duration_ms: 2.595291 + type: 'test' + ... +# Subtest: ERP browser injection is host-permission gated and fail-closed with diagnostics +ok 240 - ERP browser injection is host-permission gated and fail-closed with diagnostics + --- + duration_ms: 134.654541 + type: 'test' + ... +# Subtest: five arrangement actions require exact hidden-id references and action-specific fields +ok 241 - five arrangement actions require exact hidden-id references and action-specific fields + --- + duration_ms: 42.1265 + type: 'test' + ... +# Subtest: arrangement browser safety uses real form completeness and exact business-page candidate tuples +ok 242 - arrangement browser safety uses real form completeness and exact business-page candidate tuples + --- + duration_ms: 23.234792 + type: 'test' + ... +# Subtest: arrangement clear reuses the five native actions but requires an exact current-run row target +ok 243 - arrangement clear reuses the five native actions but requires an exact current-run row target + --- + duration_ms: 36.185166 + type: 'test' + ... +# Subtest: update actions expose validated writes and preserve unvalidated fields for manual review +ok 244 - update actions expose validated writes and preserve unvalidated fields for manual review + --- + duration_ms: 23.97775 + type: 'test' + ... +# Subtest: update adapters stop target-equals-current operations before native submit +ok 245 - update adapters stop target-equals-current operations before native submit + --- + duration_ms: 73.087792 + type: 'test' + ... +# Subtest: receivable fixture is restricted to the verified shared-child 0.01 add/clear contract +ok 246 - receivable fixture is restricted to the verified shared-child 0.01 add/clear contract + --- + duration_ms: 4.57525 + type: 'test' + ... +# Subtest: cancel requires cleared receivables and arrangements +ok 247 - cancel requires cleared receivables and arrangements + --- + duration_ms: 0.305666 + type: 'test' + ... +# Subtest: list restore is disabled and shared-plan edit restore requires 收客中 +ok 248 - list restore is disabled and shared-plan edit restore requires 收客中 + --- + duration_ms: 0.222209 + type: 'test' + ... +# Subtest: restore route reports no-op status before the ERP write gate +ok 249 - restore route reports no-op status before the ERP write gate + --- + duration_ms: 9.612125 + type: 'test' + ... +# Subtest: edit-mode transitions select one native radio option without mutating its value +ok 250 - edit-mode transitions select one native radio option without mutating its value + --- + duration_ms: 1.353042 + type: 'test' + ... +# Subtest: live write uses target September dates and does not depend on the current calendar month +ok 251 - live write uses target September dates and does not depend on the current calendar month + --- + duration_ms: 0.491917 + type: 'test' + ... +# Subtest: delete guard distinguishes independent, shared child, and shared parent routes +ok 252 - delete guard distinguishes independent, shared child, and shared parent routes + --- + duration_ms: 1.228459 + type: 'test' + ... +# Subtest: lifecycle ownership, transition boundary, and duplicate update rules fail closed +ok 253 - lifecycle ownership, transition boundary, and duplicate update rules fail closed + --- + duration_ms: 0.138209 + type: 'test' + ... +# Subtest: external parser validator accepts recognized lifecycle targets for later capability review +ok 254 - external parser validator accepts recognized lifecycle targets for later capability review + --- + duration_ms: 0.085292 + type: 'test' + ... +# Subtest: planner and external validator share the dedicated multi-date split-order probe gate +ok 255 - planner and external validator share the dedicated multi-date split-order probe gate + --- + duration_ms: 1.326667 + type: 'test' + ... +# Subtest: platform runner independently blocks a tampered multi-date split-order probe before browser access +ok 256 - platform runner independently blocks a tampered multi-date split-order probe before browser access + --- + duration_ms: 442.345625 + type: 'test' + ... +# Subtest: confirmation export is backend-attached and route-aware for child and narrow shared-parent visitor sources +ok 257 - confirmation export is backend-attached and route-aware for child and narrow shared-parent visitor sources + --- + duration_ms: 1.622 + type: 'test' + ... +# Subtest: confirmation export keeps shared-child source lookup independent of lifecycle status +ok 258 - confirmation export keeps shared-child source lookup independent of lifecycle status + --- + duration_ms: 2.264458 + type: 'test' + ... +# Subtest: unified lifecycle evidence requires explicit response and matching requery +ok 259 - unified lifecycle evidence requires explicit response and matching requery + --- + duration_ms: 0.768542 + type: 'test' + ... +# Subtest: schema and browser adapters contain the v2 safety fields and no confirm override +ok 260 - schema and browser adapters contain the v2 safety fields and no confirm override + --- + duration_ms: 34.345958 + type: 'test' + ... +# Subtest: JSON Schema compiles and separates production ERP resolution from historical test context +ok 261 - JSON Schema compiles and separates production ERP resolution from historical test context + --- + duration_ms: 616.075208 + type: 'test' + ... +# Subtest: ready native list searches once and retains exact request evidence +ok 262 - ready native list searches once and retains exact request evidence + --- + duration_ms: 33.837833 + type: 'test' + ... +# Subtest: a loading same-path Document replacement is reacquired before searching +ok 263 - a loading same-path Document replacement is reacquired before searching + --- + duration_ms: 2.398667 + type: 'test' + ... +# Subtest: replaced same-path document can finish loading later without using its predecessor +ok 264 - replaced same-path document can finish loading later without using its predecessor + --- + duration_ms: 1.85975 + type: 'test' + ... +# Subtest: native readiness stops without searching: unfinished page +ok 265 - native readiness stops without searching: unfinished page + --- + duration_ms: 1.258792 + type: 'test' + ... +# Subtest: native readiness stops without searching: missing loader +ok 266 - native readiness stops without searching: missing loader + --- + duration_ms: 3.934583 + type: 'test' + ... +# Subtest: native readiness stops without searching: disabled button +ok 267 - native readiness stops without searching: disabled button + --- + duration_ms: 1.497625 + type: 'test' + ... +# Subtest: native readiness stops without searching: detached button +ok 268 - native readiness stops without searching: detached button + --- + duration_ms: 8.131583 + type: 'test' + ... +# Subtest: native readiness stops without searching: wrong page +ok 269 - native readiness stops without searching: wrong page + --- + duration_ms: 1.170792 + type: 'test' + ... +# Subtest: native readiness stops without searching: missing document +ok 270 - native readiness stops without searching: missing document + --- + duration_ms: 70.4 + type: 'test' + ... +# Subtest: native readiness stops without searching: removed frame +ok 271 - native readiness stops without searching: removed frame + --- + duration_ms: 1.20575 + type: 'test' + ... +# Subtest: native readiness stops without searching: inaccessible frame +ok 272 - native readiness stops without searching: inaccessible frame + --- + duration_ms: 1.6935 + type: 'test' + ... +# Subtest: document replacement during prior Ajax wait fails closed without searching either page +ok 273 - document replacement during prior Ajax wait fails closed without searching either page + --- + duration_ms: 0.554417 + type: 'test' + ... +# Subtest: missing button is diagnosed separately from a ready document and loader +ok 274 - missing button is diagnosed separately from a ready document and loader + --- + duration_ms: 0.885708 + type: 'test' + ... +# Subtest: a page change during the native search is rejected instead of using stale result rows +ok 275 - a page change during the native search is rejected instead of using stale result rows + --- + duration_ms: 0.536625 + type: 'test' + ... +# Subtest: the real resolution failure carries explicit no-write proof and value-free readiness details +ok 276 - the real resolution failure carries explicit no-write proof and value-free readiness details + --- + duration_ms: 1.314083 + type: 'test' + ... +# Subtest: the worker describes readiness failures accurately while preserving not-found errors +ok 277 - the worker describes readiness failures accurately while preserving not-found errors + --- + duration_ms: 1.172333 + type: 'test' + ... +# Subtest: team-single remains the guarded production team-order path +ok 278 - team-single remains the guarded production team-order path + --- + duration_ms: 3.702375 + type: 'test' + ... +# Subtest: accepts product/customer source-region context without semantic validation +ok 279 - accepts product/customer source-region context without semantic validation + --- + duration_ms: 0.282708 + type: 'test' + ... +# Subtest: accepts a team-single operation without source-region metadata +ok 280 - accepts a team-single operation without source-region metadata + --- + duration_ms: 0.090167 + type: 'test' + ... +# Subtest: formal team-batch uses the validated native batch submit path +ok 281 - formal team-batch uses the validated native batch submit path + --- + duration_ms: 0.913625 + type: 'test' + ... +# Subtest: order updates require an identifier and only run a no-write browser preview +ok 282 - order updates require an identifier and only run a no-write browser preview + --- + duration_ms: 0.216125 + type: 'test' + ... +# Subtest: untyped parent confirmation export is blocked before any browser operation +ok 283 - untyped parent confirmation export is blocked before any browser operation + --- + duration_ms: 0.156667 + type: 'test' + ... +# Subtest: confirmation export accepts canonical types and blocks unknown artifacts +ok 284 - confirmation export accepts canonical types and blocks unknown artifacts + --- + duration_ms: 0.70875 + type: 'test' + ... +# Subtest: unknown operations fail closed +ok 285 - unknown operations fail closed + --- + duration_ms: 0.062709 + type: 'test' + ... +# Subtest: rejects legacy create envelopes instead of normalizing them +ok 286 - rejects legacy create envelopes instead of normalizing them + --- + duration_ms: 0.266875 + type: 'test' + ... +# Subtest: routes the canonical split-parent operation without child information into the guarded production browser adapter +ok 287 - routes the canonical split-parent operation without child information into the guarded production browser adapter + --- + duration_ms: 0.434834 + type: 'test' + ... +# Subtest: accepts a canonical split-child parent reference without fabricating a product +ok 288 - accepts a canonical split-child parent reference without fabricating a product + --- + duration_ms: 0.409792 + type: 'test' + ... +# Subtest: shared-child leader lookup survives the strict execution gate +ok 289 - shared-child leader lookup survives the strict execution gate + --- + duration_ms: 0.640042 + type: 'test' + ... +# Subtest: shared-child batch dispatch is Program-only, resolves all parents, and enters the guarded batch adapter +ok 290 - shared-child batch dispatch is Program-only, resolves all parents, and enters the guarded batch adapter + --- + duration_ms: 0.455708 + type: 'test' + ... +# Subtest: shared-child batch execution rejects duplicate or out-of-range resolved parents +ok 291 - shared-child batch execution rejects duplicate or out-of-range resolved parents + --- + duration_ms: 0.095833 + type: 'test' + ... +# Subtest: blocks a marked split-child parent when the child remark loses the test marker +ok 292 - blocks a marked split-child parent when the child remark loses the test marker + --- + duration_ms: 0.075584 + type: 'test' + ... +# Subtest: routes a traveler-only handoff update into the traveler import business action +ok 293 - routes a traveler-only handoff update into the traveler import business action + --- + duration_ms: 0.807417 + type: 'test' + ... +# Subtest: applies room and remark updates to a browser-read snapshot without writing ERP +ok 294 - applies room and remark updates to a browser-read snapshot without writing ERP + --- + duration_ms: 0.561667 + type: 'test' + ... +# Subtest: builds export-only source paths and never emits a save action +ok 295 - builds export-only source paths and never emits a save action + --- + duration_ms: 0.680667 + type: 'test' + ... +# Subtest: accepts the production team-single output without manual prices or staff fields +ok 296 - accepts the production team-single output without manual prices or staff fields + --- + duration_ms: 0.250042 + type: 'test' + ... +# Subtest: requires the booking customer for independent-team single orders +ok 297 - requires the booking customer for independent-team single orders + --- + duration_ms: 0.382792 + type: 'test' + ... +# Subtest: blocks scalar named references, unsupported room keys, and manual staff/price overrides +ok 298 - blocks scalar named references, unsupported room keys, and manual staff/price overrides + --- + duration_ms: 0.417292 + type: 'test' + ... +# Subtest: accepts the corrected formal native batch contract used by the reported task +ok 299 - accepts the corrected formal native batch contract used by the reported task + --- + duration_ms: 0.252083 + type: 'test' + ... +# Subtest: keeps the formal native batch operation free of test markers +ok 300 - keeps the formal native batch operation free of test markers + --- + duration_ms: 0.305375 + type: 'test' + ... +# Subtest: accepts a split-parent recurrence without child customer or passenger fields +ok 301 - accepts a split-parent recurrence without child customer or passenger fields + --- + duration_ms: 0.187792 + type: 'test' + ... +# Subtest: accepts independently supplied optional split-parent customer and passenger fields +ok 302 - accepts independently supplied optional split-parent customer and passenger fields + --- + duration_ms: 0.218375 + type: 'test' + ... +# Subtest: accepts either optional split-parent field without requiring the other +ok 303 - accepts either optional split-parent field without requiring the other + --- + duration_ms: 0.183917 + type: 'test' + ... +# Subtest: blocks multi-date split facts outside the dedicated live test probe +ok 304 - blocks multi-date split facts outside the dedicated live test probe + --- + duration_ms: 0.205708 + type: 'test' + ... +# Subtest: allows multi-date split facts only inside the dedicated TEST-202609 probe +ok 305 - allows multi-date split facts only inside the dedicated TEST-202609 probe + --- + duration_ms: 0.376791 + type: 'test' + ... +# Subtest: blocks invalid values for an optional split-parent field +ok 306 - blocks invalid values for an optional split-parent field + --- + duration_ms: 0.190917 + type: 'test' + ... +# Subtest: normalizes legacy flat split-parent fields into the canonical optional envelope +ok 307 - normalizes legacy flat split-parent fields into the canonical optional envelope + --- + duration_ms: 0.534208 + type: 'test' + ... +# Subtest: accepts canonical confirmation types and snake-case recovery flags +ok 308 - accepts canonical confirmation types and snake-case recovery flags + --- + duration_ms: 0.246041 + type: 'test' + ... +# Subtest: accepts canonical confirmation export types without alias normalization +ok 309 - accepts canonical confirmation export types without alias normalization + --- + duration_ms: 0.304 + type: 'test' + ... +# Subtest: shared-plan visitor export uses tid only and rejects child-scoped or mixed sources +ok 310 - shared-plan visitor export uses tid only and rejects child-scoped or mixed sources + --- + duration_ms: 0.642 + type: 'test' + ... +# Subtest: rejects requested confirmation formats because platform processing is separate +ok 311 - rejects requested confirmation formats because platform processing is separate + --- + duration_ms: 0.268458 + type: 'test' + ... +# Subtest: rejects unverified confirmation language variants +ok 312 - rejects unverified confirmation language variants + --- + duration_ms: 0.632583 + type: 'test' + ... +# Subtest: dispatch gate accepts parse-state lifecycle input but strict gate waits for ERP refs +ok 313 - dispatch gate accepts parse-state lifecycle input but strict gate waits for ERP refs + --- + duration_ms: 0.337709 + type: 'test' + ... +# Subtest: dispatch gate accepts business-field lookup without changing action routing +ok 314 - dispatch gate accepts business-field lookup without changing action routing + --- + duration_ms: 1.080708 + type: 'test' + ... +# Subtest: strict lifecycle gate accepts only ERP-enriched production operation +ok 315 - strict lifecycle gate accepts only ERP-enriched production operation + --- + duration_ms: 0.2085 + type: 'test' + ... +# Subtest: execution operation rejects platform task, session, receipt and batch metadata +ok 316 - execution operation rejects platform task, session, receipt and batch metadata + --- + duration_ms: 94.011459 + type: 'test' + ... +# Subtest: dispatch gate keeps internal ids, status defaults, and side-effect policy out of user input +ok 317 - dispatch gate keeps internal ids, status defaults, and side-effect policy out of user input + --- + duration_ms: 8.126708 + type: 'test' + ... +# Subtest: dispatch export needs only a visible identifier and file type +ok 318 - dispatch export needs only a visible identifier and file type + --- + duration_ms: 0.198416 + type: 'test' + ... +# Subtest: dispatch keeps an explicit historical export fixture on its strict test-context path +ok 319 - dispatch keeps an explicit historical export fixture on its strict test-context path + --- + duration_ms: 0.095166 + type: 'test' + ... +# Subtest: strict gate accepts the ERP-enriched production lifecycle matrix without test metadata +ok 320 - strict gate accepts the ERP-enriched production lifecycle matrix without test metadata + --- + duration_ms: 2.141625 + type: 'test' + ... +# Subtest: operation timing closes the previous stage and attributes buffered page work to it +ok 321 - operation timing closes the previous stage and attributes buffered page work to it + --- + duration_ms: 3.327917 + type: 'test' + ... +# Subtest: operation timing survives state loss without exposing absolute timestamps +ok 322 - operation timing survives state loss without exposing absolute timestamps + --- + duration_ms: 0.281625 + type: 'test' + ... +# Subtest: operation timing terminal snapshot is bounded and strips arbitrary values +ok 323 - operation timing terminal snapshot is bounded and strips arbitrary values + --- + duration_ms: 0.263375 + type: 'test' + ... +# Subtest: a later reconciliation continuation does not count the human idle gap +ok 324 - a later reconciliation continuation does not count the human idle gap + --- + duration_ms: 0.219209 + type: 'test' + ... +# Subtest: background timing hook covers every executor through the shared result and page-action boundaries +ok 325 - background timing hook covers every executor through the shared result and page-action boundaries + --- + duration_ms: 59.365875 + type: 'test' + ... +# Subtest: team-order preflight waits on ERP completion events without page-timer polling +ok 326 - team-order preflight waits on ERP completion events without page-timer polling + --- + duration_ms: 2.319291 + type: 'test' + ... +# Subtest: team-order frame discovery targets the exact ERP iframe instead of injecting into every frame +ok 327 - team-order frame discovery targets the exact ERP iframe instead of injecting into every frame + --- + duration_ms: 2.204042 + type: 'test' + ... +# Subtest: team-order frame waits for native customer and staff lookup data before preflight +ok 328 - team-order frame waits for native customer and staff lookup data before preflight + --- + duration_ms: 4.8705 + type: 'test' + ... +# Subtest: team-order preflight waits for the native jQuery Ajax completion event +ok 329 - team-order preflight waits for the native jQuery Ajax completion event + --- + duration_ms: 19.267291 + type: 'test' + ... +# Subtest: extension result changes push immediately while polling remains as a fallback +ok 330 - extension result changes push immediately while polling remains as a fallback + --- + duration_ms: 6.110042 + type: 'test' + ... +# Subtest: platform exposes the sanitized timing breakdown without rendering raw network data +ok 331 - platform exposes the sanitized timing breakdown without rendering raw network data + --- + duration_ms: 5.220417 + type: 'test' + ... +# Subtest: passenger TSV keeps trailing empty columns through server and plugin dispatch +ok 332 - passenger TSV keeps trailing empty columns through server and plugin dispatch + --- + duration_ms: 66.793 + type: 'test' + ... +# Subtest: passenger TSV still rejects missing or surplus columns and keeps leader validation +ok 333 - passenger TSV still rejects missing or surplus columns and keeps leader validation + --- + duration_ms: 2.584042 + type: 'test' + ... +# Subtest: passenger merge accepts empty final fields without repairing malformed column counts +ok 334 - passenger merge accepts empty final fields without repairing malformed column counts + --- + duration_ms: 30.619792 + type: 'test' + ... +# Subtest: matches the ERP product name and duration as separate fields +ok 335 - matches the ERP product name and duration as separate fields + --- + duration_ms: 211.1915 + type: 'test' + ... +# Subtest: does not confuse a reversed route fragment with the 江西 product +ok 336 - does not confuse a reversed route fragment with the 江西 product + --- + duration_ms: 89.073167 + type: 'test' + ... +# Subtest: matches punctuation-separated Chinese fragments and Chinese duration aliases +ok 337 - matches punctuation-separated Chinese fragments and Chinese duration aliases + --- + duration_ms: 0.17625 + type: 'test' + ... +# Subtest: preserves numeric product names while matching a duration suffix +ok 338 - preserves numeric product names while matching a duration suffix + --- + duration_ms: 0.134 + type: 'test' + ... +# Subtest: uses the complete ERP product name as the first native search query +ok 339 - uses the complete ERP product name as the first native search query + --- + duration_ms: 1.674708 + type: 'test' + ... +# Subtest: removes only a trailing numeric duration from the native name query +ok 340 - removes only a trailing numeric duration from the native name query + --- + duration_ms: 0.174833 + type: 'test' + ... +# Subtest: both S_chanpinming order adapters execute the planned native queries +ok 341 - both S_chanpinming order adapters execute the planned native queries + --- + duration_ms: 1.245542 + type: 'test' + ... +# Subtest: keeps unique-match safety when multiple candidates satisfy a shorthand +ok 342 - keeps unique-match safety when multiple candidates satisfy a shorthand + --- + duration_ms: 0.100042 + type: 'test' + ... +# Subtest: keeps source-region tokens as a customer-only fallback, not a product/customer gate +ok 343 - keeps source-region tokens as a customer-only fallback, not a product/customer gate + --- + duration_ms: 0.874917 + type: 'test' + ... +# Subtest: resolves a non-canonical customer phrase by all source-region tokens only when unique +ok 344 - resolves a non-canonical customer phrase by all source-region tokens only when unique + --- + duration_ms: 0.386167 + type: 'test' + ... +# Subtest: does not guess when source-region keywords match multiple customer masters +ok 345 - does not guess when source-region keywords match multiple customer masters + --- + duration_ms: 0.153333 + type: 'test' + ... +# Subtest: records every C04 parent and concrete child into state and canonical allowlist refs +ok 346 - records every C04 parent and concrete child into state and canonical allowlist refs + --- + duration_ms: 4.486417 + type: 'test' + ... +# Subtest: records parent-only facts for cleanup without declaring batch child creation successful +ok 347 - records parent-only facts for cleanup without declaring batch child creation successful + --- + duration_ms: 1.200959 + type: 'test' + ... +# Subtest: refuses to record partial facts or a mismatched independent run id +ok 348 - refuses to record partial facts or a mismatched independent run id + --- + duration_ms: 0.39375 + type: 'test' + ... +# Subtest: root contains only governed long-lived entries +ok 349 - root contains only governed long-lived entries + --- + duration_ms: 5.162417 + type: 'test' + ... +# Subtest: project docs are the sole active project memory +ok 350 - project docs are the sole active project memory + --- + duration_ms: 40.517542 + type: 'test' + ... +# Subtest: temporary residue and report outputs do not pollute the repository +ok 351 - temporary residue and report outputs do not pollute the repository + --- + duration_ms: 568.790291 + type: 'test' + ... +# Subtest: dist is an exact versioned release set with valid hashes +ok 352 - dist is an exact versioned release set with valid hashes + --- + duration_ms: 14.315541 + type: 'test' + ... +# Subtest: extension and release baselines agree +ok 353 - extension and release baselines agree + --- + duration_ms: 6.868333 + type: 'test' + ... +# Subtest: packaged Skills and extension runtime match their project sources +ok 354 - packaged Skills and extension runtime match their project sources + --- + duration_ms: 759.383333 + type: 'test' + ... +# Subtest: active Markdown links resolve and current docs do not depend on rolling history +ok 355 - active Markdown links resolve and current docs do not depend on rolling history + --- + duration_ms: 262.277792 + type: 'test' + ... +# Subtest: archive README indexes remain navigable +ok 356 - archive README indexes remain navigable + --- + duration_ms: 187.306834 + type: 'test' + ... +# Subtest: single-source and generated-output boundaries remain explicit +ok 357 - single-source and generated-output boundaries remain explicit + --- + duration_ms: 6.419083 + type: 'test' + ... +# Subtest: runtime image includes both LibreOffice document converters +ok 358 - runtime image includes both LibreOffice document converters + --- + duration_ms: 1.684667 + type: 'test' + ... +# Subtest: single-order preflight normalizes both sides and uses the exact ERP spelling through native linkage and intercepted submission +ok 359 - single-order preflight normalizes both sides and uses the exact ERP spelling through native linkage and intercepted submission + --- + duration_ms: 779.496542 + type: 'test' + ... +# Subtest: normalized exact match takes precedence over longer containing product names +ok 360 - normalized exact match takes precedence over longer containing product names + --- + duration_ms: 68.692459 + type: 'test' + ... +# Subtest: a unique shortened keyword still selects the ERP product +ok 361 - a unique shortened keyword still selects the ERP product + --- + duration_ms: 88.038583 + type: 'test' + ... +# Subtest: normalization collisions block even when one raw spelling matches exactly +ok 362 - normalization collisions block even when one raw spelling matches exactly + --- + duration_ms: 11.684125 + type: 'test' + ... +# Subtest: multiple shortened-keyword matches block instead of selecting the first +ok 363 - multiple shortened-keyword matches block instead of selecting the first + --- + duration_ms: 6.873375 + type: 'test' + ... +# Subtest: unmatched product stops with one useful error and preserves punctuation and qualifiers +ok 364 - unmatched product stops with one useful error and preserves punctuation and qualifiers + --- + duration_ms: 41.819708 + type: 'test' + ... +# Subtest: failed lookup transport or customer selection never advances into product linkage +ok 365 - failed lookup transport or customer selection never advances into product linkage + --- + duration_ms: 32.276292 + type: 'test' + ... +# Subtest: successful name resolution still requires complete native linkage before submission +ok 366 - successful name resolution still requires complete native linkage before submission + --- + duration_ms: 141.506542 + type: 'test' + ... +# Subtest: matches a persisted split parent row after an ERP error response +ok 367 - matches a persisted split parent row after an ERP error response + --- + duration_ms: 2.546209 + type: 'test' + ... +# Subtest: does not match a row from a missing requested date +ok 368 - does not match a row from a missing requested date + --- + duration_ms: 0.297666 + type: 'test' + ... +# Subtest: matches a mother-plan row without child customer or passenger criteria +ok 369 - matches a mother-plan row without child customer or passenger criteria + --- + duration_ms: 6.004708 + type: 'test' + ... +# Subtest: prefers a unique customer match when generic row criteria are ambiguous +ok 370 - prefers a unique customer match when generic row criteria are ambiguous + --- + duration_ms: 0.157792 + type: 'test' + ... +# Subtest: extracts the concrete child ddid instead of the parent tid +ok 371 - extracts the concrete child ddid instead of the parent tid + --- + duration_ms: 0.331416 + type: 'test' + ... +# Subtest: extracts only concrete shared children for the exact parent tid +ok 372 - extracts only concrete shared children for the exact parent tid + --- + duration_ms: 0.373625 + type: 'test' + ... +# Subtest: classifies a per-date split-order fact with a concrete child +ok 373 - classifies a per-date split-order fact with a concrete child + --- + duration_ms: 0.240083 + type: 'test' + ... +# Subtest: keeps a parent-only split-order result explicit instead of inventing a child +ok 374 - keeps a parent-only split-order result explicit instead of inventing a child + --- + duration_ms: 0.092209 + type: 'test' + ... +# Subtest: does not call a split-order fact determined without a parent tid or complete child scan +ok 375 - does not call a split-order fact determined without a parent tid or complete child scan + --- + duration_ms: 11.718916 + type: 'test' + ... +# Subtest: builds split-parent requery filters without retaining unrelated list state +ok 376 - builds split-parent requery filters without retaining unrelated list state + --- + duration_ms: 21.004916 + type: 'test' + ... +# Subtest: retries returned group-number queries without resubmitting and converges on visible rows +ok 377 - retries returned group-number queries without resubmitting and converges on visible rows + --- + duration_ms: 0.415208 + type: 'test' + ... +# Subtest: keeps a persistently missing returned group incomplete after the bounded retry budget +ok 378 - keeps a persistently missing returned group incomplete after the bounded retry budget + --- + duration_ms: 7.472875 + type: 'test' + ... +# Subtest: requires date reconciliation when any complete ERP response group remains unverified +ok 379 - requires date reconciliation when any complete ERP response group remains unverified + --- + duration_ms: 0.117333 + type: 'test' + ... +# Subtest: prefers a successful date fallback row over an earlier exact-query miss +ok 380 - prefers a successful date fallback row over an earlier exact-query miss + --- + duration_ms: 0.132458 + type: 'test' + ... +# Subtest: resolves a Chinese shorthand customer across multiple SelectBox columns +ok 381 - resolves a Chinese shorthand customer across multiple SelectBox columns + --- + duration_ms: 2.85925 + type: 'test' + ... +# Subtest: blocks ambiguous fuzzy customer matches instead of choosing the first row +ok 382 - blocks ambiguous fuzzy customer matches instead of choosing the first row + --- + duration_ms: 0.208291 + type: 'test' + ... +# Subtest: maps native weekday and odd/even shortcuts without changing business dates +ok 383 - maps native weekday and odd/even shortcuts without changing business dates + --- + duration_ms: 0.8495 + type: 'test' + ... +# Subtest: uses the same cycle selection plan for explicit dates and ERP shortcuts +ok 384 - uses the same cycle selection plan for explicit dates and ERP shortcuts + --- + duration_ms: 0.749917 + type: 'test' + ... +# Subtest: expands odd and even cycles by calendar day instead of weekday number +ok 385 - expands odd and even cycles by calendar day instead of weekday number + --- + duration_ms: 0.638292 + type: 'test' + ... +# Subtest: normalizes dates for the ERP range and keeps range containment deterministic +ok 386 - normalizes dates for the ERP range and keeps range containment deterministic + --- + duration_ms: 0.299459 + type: 'test' + ... +1..386 +# tests 452 +# suites 3 +# pass 450 +# fail 2 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 7484.330042 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-clean-tests.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-clean-tests.txt new file mode 100644 index 0000000..72b0ae2 --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-clean-tests.txt @@ -0,0 +1,70 @@ +TAP version 13 +# Subtest: root contains only governed long-lived entries +ok 1 - root contains only governed long-lived entries + --- + duration_ms: 92.746625 + type: 'test' + ... +# Subtest: project docs are the sole active project memory +ok 2 - project docs are the sole active project memory + --- + duration_ms: 19.769834 + type: 'test' + ... +# Subtest: temporary residue and report outputs do not pollute the repository +ok 3 - temporary residue and report outputs do not pollute the repository + --- + duration_ms: 338.834166 + type: 'test' + ... +# Subtest: dist is an exact versioned release set with valid hashes +ok 4 - dist is an exact versioned release set with valid hashes + --- + duration_ms: 21.956 + type: 'test' + ... +# Subtest: extension and release baselines agree +ok 5 - extension and release baselines agree + --- + duration_ms: 5.963541 + type: 'test' + ... +# Subtest: packaged Skills and extension runtime match their project sources +ok 6 - packaged Skills and extension runtime match their project sources + --- + duration_ms: 1081.545417 + type: 'test' + ... +# Subtest: active Markdown links resolve and current docs do not depend on rolling history +ok 7 - active Markdown links resolve and current docs do not depend on rolling history + --- + duration_ms: 347.337041 + type: 'test' + ... +# Subtest: archive README indexes remain navigable +ok 8 - archive README indexes remain navigable + --- + duration_ms: 145.497375 + type: 'test' + ... +# Subtest: single-source and generated-output boundaries remain explicit +ok 9 - single-source and generated-output boundaries remain explicit + --- + duration_ms: 39.299333 + type: 'test' + ... +# Subtest: runtime image includes both LibreOffice document converters +ok 10 - runtime image includes both LibreOffice document converters + --- + duration_ms: 1.320125 + type: 'test' + ... +1..10 +# tests 10 +# suites 0 +# pass 10 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 2460.424584 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-local-residue.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-local-residue.txt new file mode 100644 index 0000000..438b4d6 --- /dev/null +++ b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/repository-local-residue.txt @@ -0,0 +1,132 @@ +TAP version 13 +# Subtest: root contains only governed long-lived entries +not ok 1 - root contains only governed long-lived entries + --- + duration_ms: 5.146542 + type: 'test' + location: '/Users/andy/IdeaProjects/LWLT-AIBOT/tools/repository-hygiene.test.mjs:111:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly deep-equal: + + actual - expected + + + [ + + '.DS_Store', + + '.idea' + + ] + - [] + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: + actual: + 0: '.DS_Store' + 1: '.idea' + operator: 'deepStrictEqual' + stack: |- + TestContext. (file:///Users/andy/IdeaProjects/LWLT-AIBOT/tools/repository-hygiene.test.mjs:114:10) + async Test.run (node:internal/test_runner/test:1054:7) + async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) + ... +# Subtest: project docs are the sole active project memory +ok 2 - project docs are the sole active project memory + --- + duration_ms: 3.319083 + type: 'test' + ... +# Subtest: temporary residue and report outputs do not pollute the repository +not ok 3 - temporary residue and report outputs do not pollute the repository + --- + duration_ms: 45.544084 + type: 'test' + location: '/Users/andy/IdeaProjects/LWLT-AIBOT/tools/repository-hygiene.test.mjs:149:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly deep-equal: + + actual - expected + + + [ + + '.DS_Store', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/build.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/control-plane-tests.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/focused-tests.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/legacy-tests.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/repository-clean.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/repository-local-metadata.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/runtime-layout-smoke.log', + + 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/typecheck.log', + + 'chrome-extension/.DS_Store' + + ] + - [] + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: + actual: + 0: '.DS_Store' + 1: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/build.log' + 2: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/control-plane-tests.log' + 3: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/focused-tests.log' + 4: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/legacy-tests.log' + 5: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/repository-clean.log' + 6: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/repository-local-metadata.log' + 7: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/runtime-layout-smoke.log' + 8: 'archive/evidence/2026-09-14/arrangement-original-date-year-01a0858b/typecheck.log' + 9: 'chrome-extension/.DS_Store' + operator: 'deepStrictEqual' + stack: |- + TestContext. (file:///Users/andy/IdeaProjects/LWLT-AIBOT/tools/repository-hygiene.test.mjs:153:10) + async Test.run (node:internal/test_runner/test:1054:7) + async Test.processPendingSubtests (node:internal/test_runner/test:744:7) + ... +# Subtest: dist is an exact versioned release set with valid hashes +ok 4 - dist is an exact versioned release set with valid hashes + --- + duration_ms: 5.366667 + type: 'test' + ... +# Subtest: extension and release baselines agree +ok 5 - extension and release baselines agree + --- + duration_ms: 2.476417 + type: 'test' + ... +# Subtest: packaged Skills and extension runtime match their project sources +ok 6 - packaged Skills and extension runtime match their project sources + --- + duration_ms: 137.733208 + type: 'test' + ... +# Subtest: active Markdown links resolve and current docs do not depend on rolling history +ok 7 - active Markdown links resolve and current docs do not depend on rolling history + --- + duration_ms: 48.791875 + type: 'test' + ... +# Subtest: archive README indexes remain navigable +ok 8 - archive README indexes remain navigable + --- + duration_ms: 27.249208 + type: 'test' + ... +# Subtest: single-source and generated-output boundaries remain explicit +ok 9 - single-source and generated-output boundaries remain explicit + --- + duration_ms: 2.113625 + type: 'test' + ... +# Subtest: runtime image includes both LibreOffice document converters +ok 10 - runtime image includes both LibreOffice document converters + --- + duration_ms: 0.471583 + type: 'test' + ... +1..10 +# tests 10 +# suites 0 +# pass 8 +# fail 2 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 377.6575 diff --git a/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/typecheck.txt b/archive/evidence/2026-09-29/hotel-native-remark-01a0858b/typecheck.txt new file mode 100644 index 0000000..e69de29 diff --git a/archive/releases/2026-09-29/README.md b/archive/releases/2026-09-29/README.md new file mode 100644 index 0000000..218eff4 --- /dev/null +++ b/archive/releases/2026-09-29/README.md @@ -0,0 +1,5 @@ +# 2026-09-29 发布归档 + +此处为历史资料,不定义当前业务规则。 + +- [酒店默认备注修复前发布物](hotel-native-remark-01a0858b/README.md) diff --git a/archive/releases/2026-09-29/hotel-native-remark-01a0858b/README.md b/archive/releases/2026-09-29/hotel-native-remark-01a0858b/README.md new file mode 100644 index 0000000..501cde1 --- /dev/null +++ b/archive/releases/2026-09-29/hotel-native-remark-01a0858b/README.md @@ -0,0 +1,3 @@ +# 酒店备注修复前发布物 + +只读历史发布物,不定义当前业务规则。0.5.190 ZIP 在归档前核对原发布清单哈希,原字节保留。当前版本与哈希以 [发布清单](../../../../dist/release-manifest.json) 为准。 diff --git a/dist/ltjt-order-assistant-0.5.190.zip b/archive/releases/2026-09-29/hotel-native-remark-01a0858b/ltjt-order-assistant-0.5.190.zip similarity index 100% rename from dist/ltjt-order-assistant-0.5.190.zip rename to archive/releases/2026-09-29/hotel-native-remark-01a0858b/ltjt-order-assistant-0.5.190.zip diff --git a/chrome-extension/ltjt-order-assistant/README.md b/chrome-extension/ltjt-order-assistant/README.md index 2918a40..1433e31 100644 --- a/chrome-extension/ltjt-order-assistant/README.md +++ b/chrome-extension/ltjt-order-assistant/README.md @@ -11,9 +11,14 @@ Chrome Manifest V3 扩展,在用户已登录的 LTJT ERP 页面内执行经过 ## 当前版本 -当前源码版本为 `0.5.190`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 +当前源码版本为 `0.5.191`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 -0.5.190 当前重点: +0.5.191 当前重点: + +- 酒店新增未填备注时保留选中酒店原生联动备注,明确填写时使用用户备注;在资源选择后、日期/数量回调前冻结,保存前校验及写后回查均验证。默认备注回查使用 v2 证据,旧 v1 回查保持兼容。单条与批量逐条适用;变更未填备注仍保留原记录。仅本地合成验证,真实 ERP 验收待部署方完成。 +- 需更新插件和平台最低版本至 0.5.191 并刷新平台/ERP 页面;无新增数据库迁移。 + +继续保留 0.5.190 的同团批量酒店新增: - 同团 2—10 条酒店新增由程序解析为批量信封,插件按输入顺序复用单条原生保存/回查;首次失败或不确定即停止,逐条保存成功前缀、失败/待核验项与未执行项。每条确认成功才进入账号隔离的安排账本和团队进度;整批成功回执包含逐条结果及当前安排。只读回查只核验不确定项,不自动继续剩余安排。禁止跨团、混合动作、批量变更、整批自动重试。 - 需同步更新控制面、平台和插件 0.5.190,无新增数据库迁移。单条输入及原生资源匹配规则保持;本地合成验证通过,真实 ERP 验收待部署方完成。 diff --git a/chrome-extension/ltjt-order-assistant/inpage.js b/chrome-extension/ltjt-order-assistant/inpage.js index cb1d667..600642e 100644 --- a/chrome-extension/ltjt-order-assistant/inpage.js +++ b/chrome-extension/ltjt-order-assistant/inpage.js @@ -6677,7 +6677,7 @@ } window.LTJTOrderAssistant = { - version: '0.5.190', + version: '0.5.191', resolveNativeListSearchValues, lookupKeywordMatchesText, inspectLifecycleSearchCriteria: lifecycleSearchCriteria, diff --git a/chrome-extension/ltjt-order-assistant/lifecycle-adapters.js b/chrome-extension/ltjt-order-assistant/lifecycle-adapters.js index 824ec0a..988219c 100644 --- a/chrome-extension/ltjt-order-assistant/lifecycle-adapters.js +++ b/chrome-extension/ltjt-order-assistant/lifecycle-adapters.js @@ -651,6 +651,13 @@ return sha256(JSON.stringify([operation.action, operation.data.existing_refs, arrangement])); } + function usesNativeHotelRemark(operation) { + // Public input only permits a nonempty explicit remark. Resolution also + // normalizes an omitted remark to '', so both forms mean inherit here. + return operation.action === 'arrangement_hotel' && operation.data?.arrangement?.mode === 'create' + && !normalize(operation.data.arrangement.remark); + } + async function arrangementCreateEvidence(form, operation) { const rows = []; for (const index of arrangementRowIndexes(form)) { @@ -660,7 +667,7 @@ const preserved = createPreservedFields(form, operation); const preservedProof = await Promise.all(preserved.map(async (field) => ({ name: field.name, date: Boolean(field.date), sha256: await sha256(field.date ? dateYyyyMD(field.expected) : normalize(field.expected)) }))); - return { version: 1, slot_index: operation.data.arrangement.target.slot_index, + return { version: usesNativeHotelRemark(operation) ? 2 : 1, slot_index: operation.data.arrangement.target.slot_index, operation_key: await arrangementCreateOperationKey(operation), existing_rows: rows, ...(operation.action === 'arrangement_other' ? { preserved_fields: preservedProof } : {}), value_redacted: true }; } @@ -2318,11 +2325,13 @@ } const linkedFields = ['danwei0', 'danweiid0', 'fangxing0', 'diqu0', 'dianhua0', 'bizhong0', 'danjia0', 'fangshi0'].map((name) => arrangementFieldName(operation, name)); const before = Object.fromEntries(linkedFields.map((name) => [name, controlValue(getControl(form, name))])); + let nativeRemark; try { // SetValToObj is the same ERP-native mapping used by a real hotel-row // click. It fills the read-only room type and all linked fields. selectBox.SetVal = setVal; selectBox.SetValToObj(selected.candidate.raw || selected.candidate.row.join('◆')); + nativeRemark = controlValue(getArrangementControl(form, operation, 'beizhu0')); dispatchNativeFieldEvents(control); } catch (error) { blockers.push(`arrangement_hotel_native_selectbox_failed:${error?.message || String(error)}`); @@ -2340,7 +2349,7 @@ linked_fields_changed: linkedFields.filter((name) => before[name] !== after[name]), value_redacted: true }); - return selected; + return { ...selected, nativeRemark }; } function applyNativeSettlementSelection(form, supplier, changes, blockers, action = 'arrangement_transport', operation = {}) { @@ -2793,9 +2802,18 @@ const preserved = createPreservedFields(form, operation); const field = (name) => arrangementFieldName(operation, name); const action = operation.action; - if (action === 'arrangement_hotel') applyNativeHotelSelection(form, value.resource, changes, blockers, operation); + let hotelSelection; + if (action === 'arrangement_hotel') hotelSelection = applyNativeHotelSelection(form, value.resource, changes, blockers, operation); else applyNativeSettlementSelection(form, value.supplier, changes, blockers, action, operation); if (blockers.length) return { changes, blockers, arrangementSlot: slot }; + // Freeze the selected resource's note before date/quantity callbacks can + // clear it. Never inherit another existing row or read it back after save. + const nativeRemark = usesNativeHotelRemark(operation) + ? hotelSelection.nativeRemark : undefined; + const effectiveRemark = nativeRemark ?? value.remark; + const projectionOperation = nativeRemark === undefined ? operation : { + ...operation, data: { ...operation.data, arrangement: { ...value, remark: effectiveRemark } } + }; if (action === 'arrangement_hotel' || action === 'arrangement_vehicle') { applyExact(form, field('riqi0'), 'set', value.start_date, changes, blockers); applyExact(form, field('riqis0'), 'set', value.end_date, changes, blockers); @@ -2820,15 +2838,16 @@ // Native date/room callbacks may reset status and remark. Set and assert // the requested final values only after those callbacks have settled. applyExact(form, field('zt0'), 'set', value.status, changes, blockers, { optional: action === 'arrangement_other' }); - applyExact(form, field('beizhu0'), 'set', value.remark, changes, blockers); + applyExact(form, field('beizhu0'), 'set', effectiveRemark, changes, blockers); if (action === 'arrangement_other') { for (const [key, name] of Object.entries({ number: 'beianhao', date: 'beianri', entry_port: 'rujingkou', exit_port: 'chujingkou' })) { if (value.filing?.[key] !== undefined) applyExact(form, name, 'set', value.filing[key], changes, blockers); } } - const writeGuard = () => arrangementCreateWriteGuard(form, operation, signature, controls, preserved); + const writeGuard = () => arrangementCreateWriteGuard(form, projectionOperation, signature, controls, preserved); blockers.push(...writeGuard()); - return { changes, blockers, arrangementSlot: slot, writeGuard, linkageWait }; + return { changes, blockers, arrangementSlot: slot, writeGuard, linkageWait, + ...(nativeRemark !== undefined ? { nativeRemarkSha256: await sha256(normalize(nativeRemark)) } : {}) }; } async function applyArrangement(form, operation) { @@ -4077,7 +4096,7 @@ async function indexedCreateRequeryProjection(form, operation, proof) { const blockers = []; - if (!proof || proof.version !== 1 || !Array.isArray(proof.existing_rows) + if (!proof || ![1, 2].includes(proof.version) || !Array.isArray(proof.existing_rows) || !Number.isInteger(proof.slot_index) || proof.slot_index < 0 || proof.operation_key !== await arrangementCreateOperationKey(operation)) { return { fields: [], blockers: ['arrangement_create_before_evidence_missing_or_mismatched'], operation }; @@ -4097,6 +4116,16 @@ if (newRows.length !== 1) blockers.push(`arrangement_create_new_row_count:${newRows.length}`); if (blockers.length) return { fields: [], blockers: [...new Set(blockers)], operation }; const projectedOperation = arrangementCreateAtSlot(operation, newRows[0]); + if (proof.version === 2) { + if (!usesNativeHotelRemark(operation) || !/^(?:[a-f0-9]{64}|fallback-[a-f0-9]{1,8})$/.test(proof.native_remark_sha256 || '')) { + return { fields: [], blockers: ['arrangement_create_native_remark_evidence_missing'], operation }; + } + const nativeRemark = controlValue(getArrangementControl(form, projectedOperation, 'beizhu0')); + if (await sha256(normalize(nativeRemark)) !== proof.native_remark_sha256) { + return { fields: [], blockers: ['arrangement_create_native_remark_changed_after_save'], operation }; + } + projectedOperation.data.arrangement.remark = nativeRemark; + } const projection = arrangementExpectedFields(form, projectedOperation); if (operation.action === 'arrangement_other') { const expectedNames = createPreservedFields(form, projectedOperation).map((field) => field.name); @@ -4526,6 +4555,9 @@ applyBlockers = applied.blockers; writeGuard = applied.writeGuard || null; if (applied.linkageWait) preflight.preflight.arrangement_linkage = applied.linkageWait; + if (applied.nativeRemarkSha256 && preflight.preflight.hotel_create?.version === 2) { + preflight.preflight.hotel_create.native_remark_sha256 = applied.nativeRemarkSha256; + } } else if (operation.action.startsWith('order_update_')) { const applied = applyUpdates(form, operation); const receivable = applyReceivableFixture(form, operation); diff --git a/chrome-extension/ltjt-order-assistant/manifest.json b/chrome-extension/ltjt-order-assistant/manifest.json index c73d27e..ea70d44 100644 --- a/chrome-extension/ltjt-order-assistant/manifest.json +++ b/chrome-extension/ltjt-order-assistant/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "联泰下单助手", - "version": "0.5.190", + "version": "0.5.191", "description": "在已登录 LTJT ERP 页面内规划并受控执行联泰 ERP 业务操作。", "permissions": [ "activeTab", diff --git a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js index 7845cbe..9d76146 100644 --- a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js +++ b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js @@ -944,7 +944,7 @@ window.LTJTOrderAssistant = { ...(window.LTJTOrderAssistant || {}), - version: '0.5.190', + version: '0.5.191', openTeamBatchForm, pingTeamBatchFrame, preflightTeamBatchNative, diff --git a/dist/ltjt-order-assistant-0.5.191.zip b/dist/ltjt-order-assistant-0.5.191.zip new file mode 100644 index 0000000..7e30a10 Binary files /dev/null and b/dist/ltjt-order-assistant-0.5.191.zip differ diff --git a/dist/release-manifest.json b/dist/release-manifest.json index 801d043..5b079db 100644 --- a/dist/release-manifest.json +++ b/dist/release-manifest.json @@ -1,8 +1,8 @@ { "manifest_version": 1, - "generated_on": "2026-09-24", + "generated_on": "2026-09-29", "baselines": { - "chrome_extension": "0.5.190", + "chrome_extension": "0.5.191", "skills": "0.5.129", "business_instruction_docx": "0.5.137", "agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories" @@ -10,10 +10,10 @@ "artifacts": [ { "kind": "chrome_extension", - "version": "0.5.190", - "path": "dist/ltjt-order-assistant-0.5.190.zip", + "version": "0.5.191", + "path": "dist/ltjt-order-assistant-0.5.191.zip", "source": "chrome-extension/ltjt-order-assistant", - "sha256": "092838d79cf5864ec3894035b60b6dde5bbeb979c6bf9bce0ad656dc9b7c7f69" + "sha256": "97ea457b40c164b5f015a051b450aed8e3617da950608eb293f18e3ae5e41d69" }, { "kind": "skill", diff --git a/mappings/lifecycle.mapping.json b/mappings/lifecycle.mapping.json index 5f67c3c..b6c3dbe 100644 --- a/mappings/lifecycle.mapping.json +++ b/mappings/lifecycle.mapping.json @@ -1,7 +1,7 @@ { "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.190", + "current_extension_version": "0.5.191", "original_arrangement_date_selection": "Hotel, vehicle, transport and other/filing update selection accepts MM-DD or YYYY-MM-DD; omitted year matches original ERP month/day within the exact group only. Require exactly one persisted row, then freeze its actual full dates and id. Full year is exact; mixed/cross-year endpoints are matched independently with actual range order checked. No match or ambiguity blocks before mutation; show up to five original candidates and ask to resubmit complete dates. Creation and legacy target-date changes retain existing semantics.", "historical_test_marker": "TEST-202609", "scope": "/System/Business/", @@ -333,6 +333,7 @@ } }, "arrangement_hotel": { + "create_remark_policy": "0.5.191: omitted/normalized-empty remark inherits the selected native hotel note captured before field callbacks; explicit nonempty remark overrides. Freeze final note for the pre-POST guard. Hotel create proof v2 binds the inherited note hash before POST and verifies it on fresh requery/reconciliation; missing/mismatched proof cannot complete. Historical v1 and existing-row updates retain prior semantics. Applies independently to each batch item.", "page": "/System/Business/teams_jiudian.asp", "action": "DoInfo_jiudian", "create_form_readiness": { diff --git a/tools/hotel-create-empty-slot.test.mjs b/tools/hotel-create-empty-slot.test.mjs index 141dd71..33281ad 100644 --- a/tools/hotel-create-empty-slot.test.mjs +++ b/tools/hotel-create-empty-slot.test.mjs @@ -2,6 +2,12 @@ import assert from 'node:assert/strict'; import test from 'node:test'; import vm from 'node:vm'; import { readFileSync } from 'node:fs'; +import { webcrypto } from 'node:crypto'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); +const plans = require('../chrome-extension/ltjt-order-assistant/operation-plans.js'); +const hotelBatch = require('../chrome-extension/ltjt-order-assistant/hotel-batch.js'); const inpage = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8'); const adapter = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/lifecycle-adapters.js', import.meta.url), 'utf8') @@ -15,7 +21,7 @@ const adapter = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/l teamSummaryRequery = async (operation, subpage) => subpage; assistant.preflightLifecycleOperation = preflightLifecycleOperation;`); -function fixture({ occupied = 1, rows = occupied + 2, onSelection = () => {}, onValidate = () => {}, sort = false, onPost = () => {}, linkageDelays = [], onLinkageTick = () => {} } = {}) { +function fixture({ occupied = 1, rows = occupied + 2, onSelection = () => {}, onValidate = () => {}, sort = false, onPost = () => {}, linkageDelays = [], onLinkageTick = () => {}, onFieldEvent = () => {}, crypto = webcrypto } = {}) { let now = 10000; let posts = 0; let selections = 0; @@ -25,13 +31,13 @@ function fixture({ occupied = 1, rows = occupied + 2, onSelection = () => {}, on const fields = new Map(); const document = { querySelector: () => form, querySelectorAll: () => [], readyState: 'complete', body: { innerText: '' } }; const location = { href: 'https://erp.invalid/System/Business/teams_jiudian.asp?tdID=123', pathname: '/System/Business/teams_jiudian.asp' }; - const window = { document, Event: class {}, location, testValidate: () => onValidate(fields), getComputedStyle: () => ({ display: 'block', visibility: 'visible', opacity: '1' }) }; + const window = { document, crypto, Event: class {}, location, testValidate: () => onValidate(fields), getComputedStyle: () => ({ display: 'block', visibility: 'visible', opacity: '1' }) }; window.parent = window; document.defaultView = window; form.ownerDocument = document; const add = (name, value) => { const control = { name, id: name, value: String(value), type: name === 'SubmitButton' ? 'submit' : 'text', tagName: 'INPUT', disabled: false, - ownerDocument: document, dispatchEvent() {}, + ownerDocument: document, dispatchEvent() { onFieldEvent(fields, name); }, getAttribute: (key) => key.toLowerCase() === 'data' ? '270◆测试新酒店◆TWN H◆CNY◆120' : key.toLowerCase() === 'setval' ? name : null }; fields.set(name, control); form.elements.push(control); }; @@ -204,3 +210,100 @@ test('requery cannot report an old row, duplicate new rows, changed existing row assert.equal(f.posts(), 1); } }); + +test('omitted hotel remarks survive selection/date callbacks, save and read-only requery', async () => { + for (const omitted of [undefined, '']) for (const crypto of [webcrypto, null]) { + const f = fixture({ sort: true, crypto, + onSelection(fields, index) { fields.get(`beizhu${index}`).value = '6月21号起 按照包房12间\n有房损另计'; }, + onFieldEvent(fields, name) { if (/^(danwei|riqi|riqis|jianshu)1$/.test(name)) fields.get('beizhu1').value = ''; } + }); + if (omitted === undefined) delete f.operation.data.arrangement.remark; + const before = JSON.stringify(f.operation); + const result = await f.api.liveSubmitLifecycleOperation(f.operation); + assert.equal(result.status, 'lifecycle_completed', JSON.stringify(result)); + assert.equal(f.fields.get('beizhu1').value, '6月21号起 按照包房12间\n有房损另计'); + assert.equal(f.fields.get('beizhu0').value, '保留备注0'); + assert.equal(JSON.stringify(f.operation), before); + assert.equal(result.preflight.hotel_create.version, 2); + const checked = result.requery.checks.find(check => check.field === 'beizhu0'); + assert.equal(checked.actual, f.fields.get('beizhu1').value); + assert.equal(checked.matched, true); + const verified = await f.api.verifyLifecycleOperation(f.operation, { hotel_create: result.preflight.hotel_create }); + assert.equal(verified.status, 'lifecycle_requery_matched', JSON.stringify(verified)); + assert.equal(f.posts(), 1); + } +}); + +test('explicit hotel remark overrides the native default, while missing native notes remain empty', async () => { + const f = fixture({ onSelection(fields, index) { fields.get(`beizhu${index}`).value = '酒店默认备注'; } }); + f.operation.data.arrangement.remark = '用户备注:晚到保留'; + const result = await f.api.liveSubmitLifecycleOperation(f.operation); + assert.equal(result.status, 'lifecycle_completed', JSON.stringify(result)); + assert.equal(f.fields.get('beizhu1').value, '用户备注:晚到保留'); + assert.equal(result.preflight.hotel_create.version, 1); + const empty = fixture(); + const blank = await empty.api.liveSubmitLifecycleOperation(empty.operation); + assert.equal(blank.status, 'lifecycle_completed', JSON.stringify(blank)); + assert.equal(empty.fields.get('beizhu1').value, ''); + // Old executions stored v1 and intentionally wrote the omitted note as ''. + const oldProof = { ...blank.preflight.hotel_create, version: 1 }; + delete oldProof.native_remark_sha256; + assert.equal((await empty.api.verifyLifecycleOperation(empty.operation, { hotel_create: oldProof })).status, 'lifecycle_requery_matched'); +}); + +test('native remark changes at validation block POST; missing or changed saved evidence cannot report success', async () => { + const selection = (fields, index) => { fields.get(`beizhu${index}`).value = '酒店默认备注'; }; + const f = fixture({ onSelection: selection, onValidate(fields) { fields.get('beizhu1').value = ''; } }); + const blocked = await f.api.liveSubmitLifecycleOperation(f.operation); + assert.equal(blocked.status, 'lifecycle_apply_blocked', JSON.stringify(blocked)); + assert.equal(f.posts(), 0); + const changed = fixture({ onSelection: selection, onPost(form) { form.elements.find(control => control.name === 'beizhu1').value = ''; } }); + const uncertain = await changed.api.liveSubmitLifecycleOperation(changed.operation); + assert.equal(uncertain.status, 'lifecycle_execution_uncertain'); + assert.ok(uncertain.requery.blockers.includes('arrangement_create_native_remark_changed_after_save')); + const good = fixture({ onSelection: selection }); + const result = await good.api.liveSubmitLifecycleOperation(good.operation); + const proof = structuredClone(result.preflight.hotel_create); + delete proof.native_remark_sha256; + assert.equal((await good.api.verifyLifecycleOperation(good.operation, { hotel_create: proof })).status, 'lifecycle_requery_not_matched'); + good.savedForm().elements.find(control => control.name === 'beizhu1').value = 'ERP后续变动'; + assert.equal((await good.api.verifyLifecycleOperation(good.operation, { hotel_create: result.preflight.hotel_create })).status, 'lifecycle_requery_not_matched'); + assert.equal(good.posts(), 1); +}); + +test('batch orchestration preserves each hotel native or explicit remark through actual lifecycle execution', async () => { + const base = fixture().operation; + const arrangements = [5, 6, 7].map(day => ({ mode: 'create', resource: { name: '测试新酒店TWN', keyword: '测试新酒店TWN' }, + start_date: `2026-09-0${day}`, end_date: `2026-09-0${day + 1}`, room_count: 12, + ...(day === 6 ? { remark: '用户独立备注' } : {}) })); + const operation = { action: 'arrangement_hotel', order_nature: 'formal', submit_mode: 'dry_run', + data: { existing_refs: { identifier: 'LW-TEST-HOTEL' }, arrangements } }; + const before = JSON.stringify(operation); + const results = {}, reports = []; + let final; + const context = { operationPlans: plans, hotelBatch, throwIfTaskCancelled() {}, + publishHotelBatch: async (_id, _op, batch) => { final = batch; }, + chrome: { storage: { local: { get: async () => ({ businessTaskResults: results }) } } }, + executeLifecycleOperation: async (id, child) => { + const index = reports.length; + const f = fixture({ onSelection(fields, slot) { fields.get(`beizhu${slot}`).value = `酒店备注${index}`; }, + onFieldEvent(fields, name) { if (/^(riqi|riqis|jianshu)1$/.test(name)) fields.get('beizhu1').value = ''; }, + onPost(form) { form.elements.find(control => control.name === 'id1').value = String(999 + index); } + }); + f.operation.data.arrangement = { ...base.data.arrangement, ...child.data.arrangement, resource: base.data.arrangement.resource }; + const report = await f.api.liveSubmitLifecycleOperation(f.operation); + assert.equal(report.status, 'lifecycle_completed', JSON.stringify(report)); + report.requery = { matched: report.requery.matched, subpage: report.requery }; + reports.push(report); + results[id] = { status: 'completed', report, write_attempted: true, no_erp_write: false }; + } + }; + const background = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), 'utf8'); + vm.createContext(context); + vm.runInContext(background.slice(background.indexOf('async function executeHotelBatch('), background.indexOf('async function runAutoTask(')), context); + await context.executeHotelBatch('TASK', operation); + assert.equal(hotelBatch.inspect(final).allCompleted, true); + assert.deepEqual(reports.map(report => report.requery.subpage.checks.find(check => /^beizhu\d+$/.test(check.field)).actual), + ['酒店备注0', '用户独立备注', '酒店备注2']); + assert.equal(JSON.stringify(operation), before); +}); diff --git a/tools/hotel-update-selection.test.mjs b/tools/hotel-update-selection.test.mjs index cf5f8f7..3f42a8a 100644 --- a/tools/hotel-update-selection.test.mjs +++ b/tools/hotel-update-selection.test.mjs @@ -123,6 +123,19 @@ test('fresh ERP MAIN world resolves the reported 2027 hotel update using the act assert.equal(f.fields.get('riqis1').value, '2027-9-13'); }); +test('hotel replacement preserves the existing note unless the user supplies a new one', async () => { + for (const remark of [undefined, '明确的新备注']) { + const f = fixture({ onSelection(fields, slot) { fields.get(`beizhu${slot}`).value = '新酒店默认备注'; } }); + if (remark !== undefined) f.input.data.arrangement.changes.remark = remark; + const resolved = f.api.testResolveHotel(f.form, f.input); + assert.equal(resolved.ok, true, JSON.stringify(resolved)); + const applied = await f.api.testApply(f.form, resolved.operation); + assert.equal(applied.blockers.length, 0, JSON.stringify(applied)); + assert.equal(f.fields.get('beizhu1').value, remark ?? '保留备注1'); + assert.equal(f.fields.get('beizhu0').value, '保留备注0'); + } +}); + test('missing page date dependency is diagnosed before matching and never reported as zero ERP records', () => { const f = fixture({ omitDateMatcher: true }); const before = [...f.fields].map(([key, control]) => [key, control.value]); diff --git a/tools/lifecycle-contract.test.mjs b/tools/lifecycle-contract.test.mjs index 180746d..2b30272 100644 --- a/tools/lifecycle-contract.test.mjs +++ b/tools/lifecycle-contract.test.mjs @@ -1374,7 +1374,7 @@ test('passenger explicit server success is terminal without a post-save row requ assert.doesNotMatch(passengerBranch, /passengerRequery|verifyLifecycleOperation/); assert.doesNotMatch(background, /attemptAutomaticPassengerReconciliation/); assert.match(background, /名单已取得 ERP 明确成功响应,按业务规则确认录入成功/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.190'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.191'/); }); test('uncertain lifecycle writes can only converge through a read-only plugin requery', async () => { @@ -1584,7 +1584,7 @@ test('lifecycle execution keeps the MV3 worker alive until the durable task sett assert.match(background, /arrangement_resource_candidate_data_missing/); }); -test('extension 0.5.190 keeps reload dormant unless its durable execution state is fully idle', async () => { +test('extension 0.5.191 keeps reload dormant unless its durable execution state is fully idle', async () => { const [background, bridge] = await Promise.all([ readFile(new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), 'utf8'), readFile(new URL('../chrome-extension/ltjt-order-assistant/business-bridge.js', import.meta.url), 'utf8') @@ -2037,7 +2037,7 @@ test('delete guard distinguishes independent, shared child, and shared parent ro for (const operation of operations) assert.equal(plans.validateOperation(operation).ok, true, plans.validateOperation(operation).blockers.join('; ')); const mapping = JSON.parse(await readFile(new URL('../mappings/lifecycle.mapping.json', import.meta.url), 'utf8')); - assert.equal(mapping.current_extension_version, '0.5.190'); + assert.equal(mapping.current_extension_version, '0.5.191'); assert.equal( mapping.updates.order_update_independent.field_mapped_pending_live_validation['pax.child_no_bed'], 'ertrenshu' @@ -2421,10 +2421,10 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov assert.match(inpage, /`ys_danweiid\$\{index\}`, resolvedCustomerId/); assert.doesNotMatch(inpage, /product_customer_source_region|sourceRegionCheck|source_reference/); assert.doesNotMatch(teamBatchInpage, /product_customer_source_region|sourceRegionCheck/); - assert.equal(extensionManifest.version, '0.5.190'); - assert.match(inpage, /version: '0\.5\.190'/); - assert.match(teamBatchInpage, /version: '0\.5\.190'/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.190'/); + assert.equal(extensionManifest.version, '0.5.191'); + assert.match(inpage, /version: '0\.5\.191'/); + assert.match(teamBatchInpage, /version: '0\.5\.191'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.191'/); assert.match(inpage, /function strictIsoDate\(value\)/); assert.match(inpage, /const startDate = strictIsoDate\(current\('riqi'\)\)/); assert.match(inpage, /const endDate = strictIsoDate\(current\('riqis'\)\)/);