Jelajahi Sumber

feat(mode_workflow): 新增完整工作流与工具提取系统

- 重构搜索评估流水线,将结果拆分存入 search_process/search_tools 两张表
- 新增支持大模型的工具/工序提取完整工作流
- 添加 Cloudflare 隧道一键公网分享脚本
- 更新配置模板与项目文档
- 新增批量 Claude 工序提取工具
- 规范并修复工具提取的提示词与数据格式
- 完善 gitignore 忽略临时文件与环境配置
刘文武 1 hari lalu
induk
melakukan
6e63988e77
73 mengubah file dengan 29947 tambahan dan 720 penghapusan
  1. 48 1
      .claude/settings.local.json
  2. 3 0
      .env.template
  3. 1 0
      .gitignore
  4. 5 0
      examples/mode_workflow/.gitignore
  5. 0 0
      examples/mode_workflow/.server_8772.out
  6. 7 7
      examples/mode_workflow/README.md
  7. 133 46
      examples/mode_workflow/db.py
  8. 9 6
      examples/mode_workflow/import_history.py
  9. 564 139
      examples/mode_workflow/index.html
  10. 30 6
      examples/mode_workflow/pipeline/procedure_extract.py
  11. 8 7
      examples/mode_workflow/pipeline/search_eval.py
  12. 8 8
      examples/mode_workflow/pipeline/tool_extract.py
  13. 1200 0
      examples/mode_workflow/search.html
  14. 50 9
      examples/mode_workflow/server.py
  15. 113 0
      examples/mode_workflow/shell/README.md
  16. 131 0
      examples/mode_workflow/shell/share.sh
  17. 4370 47
      examples/process_pipeline/script/search_eval/fixed_query_eval/.cloudflared.log
  18. 1 1
      examples/process_pipeline/script/search_eval/fixed_query_eval/.cloudflared.pid
  19. 0 0
      examples/process_pipeline/script/search_eval/fixed_query_eval/.server.out
  20. 1 1
      examples/process_pipeline/script/search_eval/fixed_query_eval/.server.pid
  21. 57 3
      examples/process_pipeline/script/search_eval/fixed_query_eval/index.html
  22. 23 23
      examples/process_pipeline/script/search_eval/fixed_query_eval/prompts/tool_extract_system.md
  23. 8 4
      examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/_extract.log
  24. 75 97
      examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/gzh_3c1c86d58786df826985b34cd6cda29d.json
  25. 9 16
      examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/xhs_69ee8e140000000220033107.json
  26. 9 0
      examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0003/tools/_extract.log
  27. 43 30
      examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0003/tools/xhs_6954f03f000000001e034538.json
  28. 28 2
      examples/process_pipeline/script/search_eval/fixed_query_eval/server.py
  29. 5884 0
      examples/process_pipeline/script/search_eval/mode_procedure/.cloudflared.log
  30. 1 0
      examples/process_pipeline/script/search_eval/mode_procedure/.cloudflared.pid
  31. 132 0
      examples/process_pipeline/script/search_eval/mode_procedure/README.md
  32. 191 0
      examples/process_pipeline/script/search_eval/mode_procedure/db.py
  33. 138 0
      examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/batch_model_extract.py
  34. 211 0
      examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/procedure_model_extract.py
  35. 236 0
      examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/prompts/procedure_extract_system.md
  36. 215 0
      examples/process_pipeline/script/search_eval/mode_procedure/mode_procedure_分析.md
  37. 2818 0
      examples/process_pipeline/script/search_eval/mode_procedure/new_query.html
  38. 4 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/.gitignore
  39. 341 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/plan_tool.py
  40. 231 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/SKILL.md
  41. 78 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/render.py
  42. 393 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/validate.py
  43. 109 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/vocab.py
  44. 957 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/wf-patch.py
  45. 1302 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/run_cyber.py
  46. 797 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/run_procedure_dsl.py
  47. 294 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/README.md
  48. 268 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/format/case-data.schema.json
  49. 402 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/action.json
  50. 69 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/effect.json
  51. 21 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/feature.json
  52. 562 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/type.json
  53. 297 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/type_suggestions.md
  54. 246 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools.md
  55. 802 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/lint-case.py
  56. 239 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/quote-source.py
  57. 373 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/render-case.py
  58. 712 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/renderer.py
  59. 194 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/script.js
  60. 308 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/styles.css
  61. 278 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/verify-io.py
  62. 982 0
      examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/wf-patch.py
  63. 74 0
      examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/claude_report_batch.py
  64. 57 0
      examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/export_claude.py
  65. 215 0
      examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/info_graphic_job.py
  66. 1447 0
      examples/process_pipeline/script/search_eval/mode_procedure/server.py
  67. 113 0
      examples/process_pipeline/script/search_eval/mode_procedure/shell/README.md
  68. 131 0
      examples/process_pipeline/script/search_eval/mode_procedure/shell/share.sh
  69. 182 0
      examples/process_pipeline/script/search_eval/workflows/AI 人像 图片 生成 怎么做_A_xhs_684a5748.json
  70. 171 0
      examples/process_pipeline/script/search_eval/workflows/AI 人像 真实感 图片 获取 程序控制类型_A_xhs_692ebcb3.json
  71. 8 0
      examples/process_pipeline/script/search_eval/workflows/AI 人像 真实感 图片 获取 程序控制类型_A_xhs_69d51b97.json
  72. 465 98
      examples/process_pipeline/script/search_eval/workflows/AI 信息 版面设计 图片 怎么做_A_gzh_34767dfb.json
  73. 65 169
      examples/process_pipeline/script/search_eval/workflows/人像 真实感 图片 生成 怎么做_A_xhs_69d51b97.json

+ 48 - 1
.claude/settings.local.json

@@ -60,7 +60,54 @@
       "Bash(lsof -nP -tiTCP:8770 -sTCP:LISTEN)",
       "Bash(xargs kill)",
       "Bash(rm -f /tmp/cf_tunnel.log /tmp/server8770.log)",
-      "Bash(./share.sh start *)"
+      "Bash(./share.sh start *)",
+      "Bash(mkdir -p mode_procedure/runs_new)",
+      "Bash(cp server.py mode_procedure/server.py)",
+      "Bash(cp new_query.html mode_procedure/new_query.html)",
+      "Bash(mkdir -p mode_procedure/procedure-dsl)",
+      "Bash(cp procedure-dsl/run_cyber.py procedure-dsl/run_procedure_dsl.py procedure-dsl/plan_tool.py mode_procedure/procedure-dsl/)",
+      "Bash(cp -r procedure-dsl/procedure mode_procedure/procedure-dsl/procedure)",
+      "Bash(cp procedure-dsl/.gitignore mode_procedure/procedure-dsl/.gitignore)",
+      "Bash(cp procedure-dsl/procedure/SKILL.md mode_procedure/procedure-dsl/procedure/SKILL.md)",
+      "Bash(pkill -f \"run_cyber.py.*测试本地引擎\")",
+      "Bash(cp -r procedure-dsl/spec mode_procedure/procedure-dsl/spec)",
+      "Bash(rm -rf mode_procedure/procedure-dsl/spec/__pycache__ mode_procedure/procedure-dsl/spec/tools/__pycache__)",
+      "Bash(/Users/max_liu/max_liu/company/Agent/.venv/bin/python -m py_compile server.py)",
+      "Bash(python3 -c 'import urllib.parse;print\\(urllib.parse.quote\\('\\\\''__TRACKED_VAR__'\\\\''\\)\\)')",
+      "Bash(python3 -c \"import sys,json;d=json.load\\(sys.stdin\\);log=d.get\\('log',''\\);print\\('日志首行:', log.split\\(chr\\(10\\)\\)[0][:70] if log else '空'\\)\")",
+      "Bash(grep -cE '✅|❌' /tmp/batch_model.log)",
+      "Bash(tail -5 /tmp/batch_model.log)",
+      "Bash(grep -v \"^runs_new$\")",
+      "Bash(ls -la mode-dsl/)",
+      "Bash(ls -la shell/)",
+      "Bash(mv procedure_model_extract.py mode-dsl/)",
+      "Bash(mv batch_model_extract.py mode-dsl/)",
+      "Bash(mv prompts/procedure_extract_system.md mode-dsl/prompts/)",
+      "Bash(rmdir prompts *)",
+      "Bash(rm -rf __pycache__ mode-dsl/__pycache__)",
+      "Bash(grep -vE \"^\\\\.$\")",
+      "Bash(grep -vE \"^\\\\.|^shell$|^runs_new$\")",
+      "Bash(/Users/max_liu/max_liu/company/Agent/.venv/bin/python -m py_compile server.py db.py mode-dsl/procedure_model_extract.py mode-dsl/batch_model_extract.py)",
+      "Bash(grep -nA30 \"def scan_runs\" server.py)",
+      "Bash(cat)",
+      "Read(//tmp/**)",
+      "Bash(grep -E \"\\\\.\\(md|json\\)$\")",
+      "Bash(python3 *)",
+      "Bash(git add *)",
+      "Bash(git commit -m 'docs: mode_workflow 设计文档\\(三表入库+三tab单页\\) *)",
+      "Bash(git commit -m 'docs: mode_workflow 实施计划\\(9 任务,含完整代码\\) *)",
+      "Bash(git commit -m 'feat\\(mode_workflow\\): 脚手架与 prompt/内容树资产同步 *)",
+      "Bash(kill %1)",
+      "Skill(agent-browser)",
+      "Bash(npx playwright *)",
+      "Bash(git commit -m 'feat\\(mode_workflow\\): 三tab单页前端\\(Dashboard/Dataset/聚类库\\) *)",
+      "Bash(git commit -m 'docs\\(mode_workflow\\): README 与启动说明 *)",
+      "Bash(pkill -f \"server.py 8772\")",
+      "Bash(agent-browser eval *)",
+      "Bash(agent-browser wait *)",
+      "Bash(agent-browser screenshot *)",
+      "Bash(agent-browser close *)",
+      "Bash(agent-browser open *)"
     ],
     "deny": [],
     "ask": []

+ 3 - 0
.env.template

@@ -13,3 +13,6 @@ KNOWHUB_PORT=5432
 KNOWHUB_USER=aiddit_aigc
 KNOWHUB_PASSWORD=%a&&yqNxg^V1$toJ*WOa^-b^X=QJ
 KNOWHUB_DB_NAME=knowhub
+
+# 知识检索 API(mode_workflow 聚类库 / search.html 调用,server.py 注入到页面)
+KNOWLEDGE_API_BASE=http://47.236.83.130:8001

+ 1 - 0
.gitignore

@@ -115,3 +115,4 @@ runs_new/
 .ocr_cache
 fixed_query_eval/docs/
 fixed_query_eval/runs_full/
+.env

+ 5 - 0
examples/mode_workflow/.gitignore

@@ -2,3 +2,8 @@ runs/
 .cache/
 __pycache__/
 *.pyc
+.server.log
+.server.out
+.server.pid
+.cloudflared.log
+.cloudflared.pid

+ 0 - 0
examples/mode_workflow/.server_8772.out


+ 7 - 7
examples/mode_workflow/README.md

@@ -1,6 +1,6 @@
 # mode_workflow · 搜索评估 + 工序/工具解构工作台
 
-MySQL 三表(search_data / mode_process / mode_tools)为唯一事实源的单页工作台:
+MySQL 四表(search_process / search_tools / mode_process / mode_tools)为唯一事实源的单页工作台:
 Dashboard(结果/过程指标可视化)、Dataset(query → 帖子 → 工序/工具解构)、聚类库(占位)。
 
 设计文档:`docs/superpowers/specs/2026-06-12-mode-workflow-design.md`
@@ -9,7 +9,7 @@ Dashboard(结果/过程指标可视化)、Dataset(query → 帖子 → 工序/
 
 ```bash
 # 0. 前置:.env 配 MYSQL_* 与 OPEN_ROUTER_API_KEY;pip install -e .
-python db.py init             # 建三张表(幂等)
+python db.py init             # 建四张表(幂等);db.py clear 清空数据
 python import_history.py      # (可选)导入 fixed_query_eval 历史搜索结果
 python server.py              # http://localhost:8772
 ```
@@ -18,15 +18,15 @@ python server.py              # http://localhost:8772
 
 | 文件 | 职责 |
 |---|---|
-| `db.py` | 表 DDL + 全部读写(读 .env MYSQL_*) |
+| `db.py` | 表 DDL + 全部读写(读 .env MYSQL_*) |
 | `server.py` | 页面 + API + 解构任务子进程管理(端口 8772) |
 | `index.html` | 单文件前端:Dashboard / Dataset / 聚类库 |
-| `pipeline/search_eval.py` | 任意 query 搜索+评估 → search_data |
+| `pipeline/search_eval.py` | 任意 query 搜索+评估 → search_process / search_tools(按解构方向分表) |
 | `pipeline/procedure_extract.py` | 工序解构(LLM 直出)→ mode_process |
 | `pipeline/tool_extract.py` | 工具解构 → mode_tools |
 | `prompts/` | 工序/工具解构 system prompt(可单独迭代) |
 | `reference/judged_matrix.json` | 内容树(27 动作×50 类型),Dashboard 覆盖度用 |
-| `runs/` | 运行日志与调试副本(gitignore) |
+| `runs/` | 运行日志与调试副本(gitignore):search_process / search_tools / mode_process / mode_tools / logs |
 
 搜索/评估/转写引擎函数只读复用
 `examples/process_pipeline/script/search_eval/search_and_evaluate.py`,本目录不复制引擎代码。
@@ -34,9 +34,9 @@ python server.py              # http://localhost:8772
 ## 数据流
 
 ```
-新建搜索(UI) → server 子进程 pipeline/search_eval.py → search_data
+新建搜索(UI) → server 子进程 pipeline/search_eval.py → search_process / search_tools(方向分表)
 选帖解构(UI) → server 子进程 pipeline/{procedure,tool}_extract.py → mode_process / mode_tools
-Dashboard    → /api/dashboard 实时聚合表(内容树覆盖按 steps 的 action×type 命中有效节点)
+Dashboard    → /api/dashboard 实时聚合表(内容树覆盖按 steps 的 action×type 命中有效节点)
 ```
 
 解构按版本(`v_MMDDHHMM`)保留历史:同版本重跑幂等覆盖,跨版本共存,前端版本下拉可回看。

+ 133 - 46
examples/mode_workflow/db.py

@@ -1,21 +1,24 @@
 # -*- coding: utf-8 -*-
 """mode_workflow · MySQL 持久化(DB 为唯一事实源)
 ================================================================================
-读 .env 的 MYSQL_* 连接 MySQL。三张表:
-  search_data  —— 每行一个 (query, 帖子):搜索 + llm 评估结果
-  mode_process —— 每行一个解构出的工序(steps 等嵌套结构存 JSON 列)
-  mode_tools   —— 每行一个解构出的工具
+读 .env 的 MYSQL_* 连接 MySQL。四张表:
+  search_process —— 每行一个 (query, 帖子):工序方向的搜索 + llm 评估结果
+  search_tools   —— 同结构,工具方向的搜索结果(方向由表区分,不再用 mode_type 列)
+  mode_process   —— 每行一个解构出的工序(steps 等嵌套结构存 JSON 列)
+  mode_tools     —— 每行一个解构出的工具
 
 与旧 fixed_query_eval/db.py 的关键差异:本系统 DB 是主存储,写入失败直接 raise,
 不做"失败不阻断"。读侧保留防御(返回空/None)。
 
 用法:
   python db.py init    # 建表(幂等)
-  python db.py check   # 打印三表行数
+  python db.py check   # 打印四表行数
+  python db.py clear   # 清空四表数据(TRUNCATE)
 """
 import json
 import os
 import sys
+from datetime import datetime
 from pathlib import Path
 
 PROJECT_ROOT = Path(__file__).resolve().parents[2]
@@ -44,8 +47,20 @@ def _conn():
 
 # ── DDL ──────────────────────────────────────────────────────────────────────
 
-DDL_SEARCH = """
-CREATE TABLE IF NOT EXISTS search_data (
+SEARCH_TABLES = {"process": "search_process", "tools": "search_tools"}
+
+
+def _search_table(mode_or_table):
+    """mode(process/tools)或表名 → 合法搜索表名(白名单,防 SQL 注入)。"""
+    t = SEARCH_TABLES.get(mode_or_table, mode_or_table)
+    if t not in SEARCH_TABLES.values():
+        raise ValueError(f"未知搜索表/模式: {mode_or_table!r}")
+    return t
+
+
+def _ddl_search(table, direction):
+    return f"""
+CREATE TABLE IF NOT EXISTS {table} (
   id            BIGINT AUTO_INCREMENT PRIMARY KEY,
   query_id      VARCHAR(32)   NOT NULL COMMENT 'q0000',
   query_text    VARCHAR(512)  NULL,
@@ -64,14 +79,13 @@ CREATE TABLE IF NOT EXISTS search_data (
   quality_grade VARCHAR(8)    NULL,
   found_by      JSON          NULL COMMENT '命中的措辞数组',
   knowledge_type JSON         NULL COMMENT '["能力","工序","工具"] 子集',
-  mode_type     VARCHAR(16)   NULL COMMENT '该 query 的解构方向:工序/工具(空=通用)',
   overall_score FLOAT         NULL COMMENT '(相关均值+质量均值)/2',
   llm_evaluation JSON         NULL COMMENT '评估全量 blob',
   created_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
   updated_at    TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   UNIQUE KEY uk_qid_case (query_id, case_id),
   KEY idx_platform (platform)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='搜索+评估结果';
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='搜索+评估结果({direction})';
 """
 
 DDL_PROCESS = """
@@ -135,16 +149,23 @@ def init_tables():
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            cur.execute(DDL_SEARCH)
+            cur.execute(_ddl_search("search_process", "工序方向"))
+            cur.execute(_ddl_search("search_tools", "工具方向"))
             cur.execute(DDL_PROCESS)
             cur.execute(DDL_TOOLS)
-            # 迁移:旧表补 mode_type 列(CREATE IF NOT EXISTS 不会改已有表)
-            cur.execute("SHOW COLUMNS FROM search_data LIKE 'mode_type'")
-            if not cur.fetchone():
-                cur.execute("ALTER TABLE search_data ADD COLUMN mode_type VARCHAR(16) NULL "
-                            "COMMENT '该 query 的解构方向:工序/工具(空=通用)' AFTER knowledge_type")
-                print("🔧 迁移:search_data 已补 mode_type 列")
-        print("✅ 建表完成:search_data, mode_process, mode_tools")
+        print("✅ 建表完成:search_process, search_tools, mode_process, mode_tools")
+    finally:
+        conn.close()
+
+
+def clear_tables():
+    """清空四张表的数据(TRUNCATE,表结构保留)。"""
+    conn = _conn()
+    try:
+        with conn.cursor() as cur:
+            for t in ("search_process", "search_tools", "mode_process", "mode_tools"):
+                cur.execute(f"TRUNCATE TABLE {t}")
+                print(f"🧹 已清空 {t}")
     finally:
         conn.close()
 
@@ -169,12 +190,16 @@ def _j(v):
 
 
 def _collect_scores(node):
-    """递归收集嵌套评估里所有数值「得分」。"""
+    """递归收集嵌套评估里所有「得分」。LLM 直出的得分多为字符串("1"/"4"),
+    个别为数字(如 时效性 10),统一按 float 解析;非数值(如 "N/A")跳过不计入。"""
     out = []
     if isinstance(node, dict):
         for k, v in node.items():
-            if k == "得分" and isinstance(v, (int, float)):
-                out.append(float(v))
+            if k == "得分":
+                try:
+                    out.append(float(v))
+                except (TypeError, ValueError):
+                    pass
             else:
                 out.extend(_collect_scores(v))
     elif isinstance(node, list):
@@ -193,11 +218,48 @@ def overall_score(e):
     return round(sum(parts) / len(parts), 2) if parts else None
 
 
-# ── search_data ──────────────────────────────────────────────────────────────
-
-def upsert_search_posts(query_id, query_text, results, mode_type=None):
-    """一组搜索结果写入 search_data(按 (query_id, case_id) upsert)。返回写入条数。
-    mode_type:该 query 的解构方向(工序/工具),None 不覆盖已有值。"""
+def _recency_hard(date_str):
+    """硬时效(同 mode_procedure/server.py:_recency_hard):半年内=3 / 两年内=2 / 更早=1。
+    publish_time 头 10 字符按 YYYY-MM-DD 解析,失败返回 None(不参与判定)。"""
+    try:
+        d = datetime.strptime(str(date_str or "")[:10], "%Y-%m-%d")
+    except (ValueError, TypeError):
+        return None
+    days = (datetime.now() - d).days
+    if days <= 180:
+        return 3
+    if days <= 730:
+        return 2
+    return 1
+
+
+def is_adopted(overall, evaluation, publish_time):
+    """采纳/命中判定,口径对齐 mode_procedure 的 decision=="report":
+    制作相关性<4、发布超两年、综合分<6 —— 任一命中即不采纳;指标缺失不参与判定。"""
+    rel = None
+    v = ((evaluation or {}).get("相关性") or {}).get("和内容制作知识相关")
+    if isinstance(v, dict):
+        v = v.get("得分")
+    try:
+        rel = float(v) if v is not None else None
+    except (TypeError, ValueError):
+        rel = None
+    if rel is not None and rel < 4:
+        return False
+    rh = _recency_hard(publish_time)
+    if rh is not None and rh < 2:
+        return False
+    if overall is not None and float(overall) < 6:
+        return False
+    return True
+
+
+# ── search_process / search_tools ────────────────────────────────────────────
+
+def upsert_search_posts(query_id, query_text, results, table="search_process"):
+    """一组搜索结果写入指定搜索表(按 (query_id, case_id) upsert)。返回写入条数。
+    table:search_process(工序方向) / search_tools(工具方向)。"""
+    table = _search_table(table)
     if not results:
         return 0
     rows = []
@@ -216,17 +278,16 @@ def upsert_search_posts(query_id, query_text, results, mode_type=None):
             post.get("_quality_score"), post.get("_quality_grade"),
             _j(r.get("found_by_queries") or []),
             _j(e.get("知识类型") or []),
-            mode_type,
             overall_score(e),
             _j(e),
         ))
-    sql = """
-    INSERT INTO search_data
+    sql = f"""
+    INSERT INTO {table}
       (query_id, query_text, case_id, platform, channel_content_id, title, url,
        content_type, body, images, videos, like_count, publish_time,
-       quality_score, quality_grade, found_by, knowledge_type, mode_type,
+       quality_score, quality_grade, found_by, knowledge_type,
        overall_score, llm_evaluation)
-    VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
+    VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
     ON DUPLICATE KEY UPDATE
       query_text=VALUES(query_text), platform=VALUES(platform),
       channel_content_id=VALUES(channel_content_id), title=VALUES(title), url=VALUES(url),
@@ -234,7 +295,6 @@ def upsert_search_posts(query_id, query_text, results, mode_type=None):
       videos=VALUES(videos), like_count=VALUES(like_count), publish_time=VALUES(publish_time),
       quality_score=VALUES(quality_score), quality_grade=VALUES(quality_grade),
       found_by=VALUES(found_by), knowledge_type=VALUES(knowledge_type),
-      mode_type=COALESCE(VALUES(mode_type), mode_type),
       overall_score=VALUES(overall_score), llm_evaluation=VALUES(llm_evaluation);
     """
     conn = _conn()
@@ -246,15 +306,22 @@ def upsert_search_posts(query_id, query_text, results, mode_type=None):
         conn.close()
 
 
-def fetch_queries():
-    """query 列表 + 帖子数 + 解构进度。"""
+def fetch_queries(mode="process"):
+    """某方向搜索表的 query 列表 + 帖子数 + 采纳/命中数 + 解构进度。"""
+    table = _search_table(mode)
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            cur.execute("""SELECT query_id, MAX(query_text) AS query_text,
-                                  MAX(mode_type) AS mode_type, COUNT(*) AS post_count
-                           FROM search_data GROUP BY query_id ORDER BY query_id""")
+            cur.execute(f"""SELECT query_id, MAX(query_text) AS query_text,
+                                   COUNT(*) AS post_count
+                            FROM {table} GROUP BY query_id ORDER BY query_id""")
             queries = cur.fetchall()
+            cur.execute(f"""SELECT query_id, overall_score, llm_evaluation, publish_time
+                            FROM {table}""")
+            hits = {}
+            for r in cur.fetchall():
+                if is_adopted(r["overall_score"], _loads(r["llm_evaluation"]), r["publish_time"]):
+                    hits[r["query_id"]] = hits.get(r["query_id"], 0) + 1
             cur.execute("SELECT query_id, COUNT(DISTINCT case_id) AS n FROM mode_process GROUP BY query_id")
             np = {r["query_id"]: r["n"] for r in cur.fetchall()}
             cur.execute("SELECT query_id, COUNT(DISTINCT case_id) AS n FROM mode_tools GROUP BY query_id")
@@ -262,18 +329,20 @@ def fetch_queries():
     finally:
         conn.close()
     for q in queries:
+        q["hit_count"] = hits.get(q["query_id"], 0)
         q["process_done"] = np.get(q["query_id"], 0)
         q["tools_done"] = nt.get(q["query_id"], 0)
     return queries
 
 
-def fetch_posts(query_id):
-    """某 query 下全部帖子(JSON 列已解析),带 has_process/has_tools 标记。"""
+def fetch_posts(query_id, mode="process"):
+    """某方向搜索表里某 query 的全部帖子(JSON 列已解析),带 has_process/has_tools 标记。"""
+    table = _search_table(mode)
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            cur.execute("""SELECT * FROM search_data WHERE query_id=%s
-                           ORDER BY overall_score DESC, id""", (query_id,))
+            cur.execute(f"""SELECT * FROM {table} WHERE query_id=%s
+                            ORDER BY overall_score DESC, id""", (query_id,))
             rows = cur.fetchall()
             cur.execute("SELECT DISTINCT case_id FROM mode_process WHERE query_id=%s", (query_id,))
             hp = {r["case_id"] for r in cur.fetchall()}
@@ -284,18 +353,20 @@ def fetch_posts(query_id):
     for r in rows:
         for col in ("images", "videos", "found_by", "knowledge_type", "llm_evaluation"):
             r[col] = _loads(r[col])
+        r["adopted"] = is_adopted(r["overall_score"], r["llm_evaluation"], r["publish_time"])
         r["has_process"] = r["case_id"] in hp
         r["has_tools"] = r["case_id"] in ht
         r.pop("created_at", None); r.pop("updated_at", None)
     return rows
 
 
-def fetch_post(query_id, case_id):
-    """单帖完整行(给 pipeline 脚本重建 source 用)。无则 None。"""
+def fetch_post(query_id, case_id, table="search_process"):
+    """指定搜索表的单帖完整行(给 pipeline 脚本重建 source 用)。无则 None。"""
+    table = _search_table(table)
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            cur.execute("SELECT * FROM search_data WHERE query_id=%s AND case_id=%s",
+            cur.execute(f"SELECT * FROM {table} WHERE query_id=%s AND case_id=%s",
                         (query_id, case_id))
             row = cur.fetchone()
     finally:
@@ -477,8 +548,19 @@ def fetch_dashboard_rows():
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            cur.execute("SELECT query_id, case_id, knowledge_type FROM search_data")
+            # 进度分母走「采纳」口径,需带上 is_adopted 判定所需字段;
+            # mode 标方向(工序帖来自 search_process,工具帖来自 search_tools)。
+            cols = ("query_id, case_id, platform, knowledge_type, "
+                    "overall_score, publish_time, llm_evaluation")
+            cur.execute(f"SELECT {cols} FROM search_process")
             posts = cur.fetchall()
+            for p in posts:
+                p["mode"] = "process"
+            cur.execute(f"SELECT {cols} FROM search_tools")
+            st = cur.fetchall()
+            for p in st:
+                p["mode"] = "tools"
+            posts += st
             cur.execute("""SELECT case_id, version, steps, tools_used, cost_usd,
                                   duration_s, created_at FROM mode_process""")
             procs = cur.fetchall()
@@ -490,6 +572,9 @@ def fetch_dashboard_rows():
         conn.close()
     for p in posts:
         p["knowledge_type"] = _loads(p["knowledge_type"], [])
+        # 采纳判定:口径同帖子列表(is_adopted),作为「需解构」分母依据
+        p["adopted"] = is_adopted(
+            p["overall_score"], _loads(p["llm_evaluation"]), p["publish_time"])
     for r in procs:
         r["steps"] = _loads(r["steps"], [])
         r["tools_used"] = _loads(r["tools_used"], [])
@@ -507,7 +592,7 @@ def check():
     conn = _conn()
     try:
         with conn.cursor() as cur:
-            for t in ("search_data", "mode_process", "mode_tools"):
+            for t in ("search_process", "search_tools", "mode_process", "mode_tools"):
                 cur.execute(f"SELECT COUNT(*) AS n FROM {t}")
                 print(f"{t}: {cur.fetchone()['n']} 行")
     finally:
@@ -520,5 +605,7 @@ if __name__ == "__main__":
         init_tables()
     elif cmd == "check":
         check()
+    elif cmd == "clear":
+        clear_tables()
     else:
-        print("用法:\n  python db.py init    # 建表\n  python db.py check   # 三表行数")
+        print("用法:\n  python db.py init    # 建表\n  python db.py check   # 四表行数\n  python db.py clear   # 清空四表数据")

+ 9 - 6
examples/mode_workflow/import_history.py

@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-"""一次性导入:fixed_query_eval/runs_full/*/form_A.json → search_data 表。
-幂等(upsert),可反复执行。
+"""一次性导入:fixed_query_eval/runs_full/*/form_A.json → 搜索表。
+幂等(upsert),可反复执行。默认导入 search_process(工序方向)。
 
 用法:
   python import_history.py
-  python import_history.py --runs-dir /path/to/runs_full
+  python import_history.py --runs-dir /path/to/runs_full --table search_tools
 """
 import argparse
 import json
@@ -20,8 +20,10 @@ DEFAULT_RUNS = (HERE.parent / "process_pipeline" / "script" / "search_eval"
 
 
 def main():
-    p = argparse.ArgumentParser(description="历史搜索结果导入 search_data")
+    p = argparse.ArgumentParser(description="历史搜索结果导入搜索表")
     p.add_argument("--runs-dir", default=str(DEFAULT_RUNS))
+    p.add_argument("--table", default="search_process",
+                   choices=["search_process", "search_tools"])
     args = p.parse_args()
 
     runs = Path(args.runs_dir)
@@ -34,10 +36,11 @@ def main():
         data = json.loads(f.read_text(encoding="utf-8"))
         qid = f.parent.name
         results = data.get("results", [])
-        n = db.upsert_search_posts(qid, data.get("query") or data.get("original_q"), results)
+        n = db.upsert_search_posts(qid, data.get("query") or data.get("original_q"),
+                                   results, table=args.table)
         print(f"  {qid}: 文件 {len(results)} 条 → 入库 {n} 条")
         total += n
-    print(f"✅ 共导入 {total} 条 → search_data")
+    print(f"✅ 共导入 {total} 条 → {args.table}")
     return 0
 
 

File diff ditekan karena terlalu besar
+ 564 - 139
examples/mode_workflow/index.html


+ 30 - 6
examples/mode_workflow/pipeline/procedure_extract.py

@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-"""工序解构 · search_data 帖子 → workflow JSON → mode_process 表
+"""工序解构 · search_process 帖子 → workflow JSON → mode_process 表
 ================================================================================
 单次大模型直出(无 agent / 无 validate 循环),prompt 见 prompts/procedure_extract_system.md。
 配图下载转 base64(绕防盗链)随文本一起发。结果按工序拆行写 mode_process。
@@ -33,6 +33,7 @@ import db
 PROMPT_FILE = MW / "prompts" / "procedure_extract_system.md"
 DEFAULT_MODEL = "anthropic/claude-sonnet-4-6"
 MAX_IMAGES = 8
+MAX_IMG_DIM = 8000   # Anthropic 单维像素上限,超过整请求 400(长图必踩)
 
 
 # ── 以下 4 个助手原样取自 mode_procedure/mode-dsl/procedure_model_extract.py ──
@@ -51,6 +52,28 @@ def _detect_image_mime(data: bytes):
     return None
 
 
+def _downscale_if_oversized(data, mime):
+    """任一维 >MAX_IMG_DIM 则等比缩到最长边 ≤MAX_IMG_DIM,返回 (data, mime)。
+    Anthropic 拒收任一维 >8000px 的图(整请求 400),公众号「长图」常踩此坑。
+    缩图失败则原样返回(至多退回原 400,不致崩)。"""
+    try:
+        from io import BytesIO
+        from PIL import Image
+        im = Image.open(BytesIO(data))
+        w, h = im.size
+        if max(w, h) <= MAX_IMG_DIM:
+            return data, mime
+        scale = (MAX_IMG_DIM - 100) / max(w, h)
+        im = im.convert("RGB").resize((max(1, int(w * scale)), max(1, int(h * scale))))
+        fmt, out_mime = ("JPEG", "image/jpeg") if mime == "image/jpeg" else ("PNG", "image/png")
+        buf = BytesIO()
+        im.save(buf, format=fmt)
+        print(f"   🔧 超限图 {w}x{h} → {im.width}x{im.height}(避 Anthropic 8000px 上限)")
+        return buf.getvalue(), out_mime
+    except Exception:
+        return data, mime
+
+
 async def _fetch_data_url(url, sem):
     from agent.tools.builtin.file.image_cdn import _download_image
     async with sem:
@@ -61,6 +84,7 @@ async def _fetch_data_url(url, sem):
     mime = _detect_image_mime(data)
     if mime is None:
         return None
+    data, mime = _downscale_if_oversized(data, mime)
     return f"data:{mime};base64,{base64.b64encode(data).decode()}"
 
 
@@ -155,9 +179,9 @@ async def extract_one(row, system, llm_call, model, args):
     dur = round(time.monotonic() - t0, 1)
     n = db.replace_process(args.query_id, cid, row["platform"], row["title"],
                            data, model, args.version, cost, dur)
-    out_dir = MW / "runs" / "procedures"
+    out_dir = MW / "runs" / "mode_process" / args.query_id   # 按 query 分组存放
     out_dir.mkdir(parents=True, exist_ok=True)
-    (out_dir / f"{cid}_{args.version}.json").write_text(
+    (out_dir / f"{cid}.json").write_text(
         json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
     print(f"   ✅ {cid} → {n} 个工序 · ${cost:.4f} · {dur}s")
     return cost
@@ -167,9 +191,9 @@ async def run(args):
     case_ids = [c.strip() for c in args.case_ids.split(",") if c.strip()]
     rows = []
     for cid in case_ids:
-        row = db.fetch_post(args.query_id, cid)
+        row = db.fetch_post(args.query_id, cid, table="search_process")
         if row is None:
-            print(f"⚠️ {args.query_id}/{cid} 不在 search_data,跳过")
+            print(f"⚠️ {args.query_id}/{cid} 不在 search_process,跳过")
             continue
         rows.append(row)
     if not rows:
@@ -189,7 +213,7 @@ async def run(args):
 
 
 def main():
-    p = argparse.ArgumentParser(description="工序解构:search_data 帖子 → mode_process")
+    p = argparse.ArgumentParser(description="工序解构:search_process 帖子 → mode_process")
     p.add_argument("--query-id", required=True)
     p.add_argument("--case-ids", required=True, help="逗号分隔 case_id 列表")
     p.add_argument("--model", default=DEFAULT_MODEL)

+ 8 - 7
examples/mode_workflow/pipeline/search_eval.py

@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
-"""搜索 + 评估 · 任意 query → 多渠道搜索去重 → LLM 逐帖评估 → search_data 表
+"""搜索 + 评估 · 任意 query → 多渠道搜索去重 → LLM 逐帖评估 → search_process/search_tools 表
+(方向由 --mode-type 决定:工序 → search_process,工具 → search_tools)
 ================================================================================
 引擎函数全部只读复用 search_and_evaluate.py(搜索/去重/转写/评估/英平台翻译)。
 
@@ -74,11 +75,11 @@ async def run(args):
     for s in sources:
         s.pop("_image_data_urls", None)
 
-    n = db.upsert_search_posts(args.query_id, args.query, sources,
-                               mode_type=args.mode_type or None)
-    print(f"🗄️  search_data 入库 {n} 行 · 方向 {args.mode_type or '通用'} · 评估成本 ${cost:.4f}")
+    table = "search_tools" if args.mode_type == "工具" else "search_process"
+    n = db.upsert_search_posts(args.query_id, args.query, sources, table=table)
+    print(f"🗄️  {table} 入库 {n} 行 · 方向 {args.mode_type or '工序'} · 评估成本 ${cost:.4f}")
 
-    out_dir = MW / "runs" / "search"
+    out_dir = MW / "runs" / table
     out_dir.mkdir(parents=True, exist_ok=True)
     (out_dir / f"{args.query_id}.json").write_text(json.dumps({
         "query_id": args.query_id, "query": args.query, "phrasings": phrasings,
@@ -88,12 +89,12 @@ async def run(args):
 
 
 def main():
-    p = argparse.ArgumentParser(description="搜索+评估 → search_data")
+    p = argparse.ArgumentParser(description="搜索+评估 → search_process/search_tools")
     p.add_argument("--query-id", required=True, help="如 q0004(server 自动分配)")
     p.add_argument("--query", required=True, help="基准 query(评估锚点)")
     p.add_argument("--synonyms", default="", help="逗号分隔的同义措辞(可选)")
     p.add_argument("--mode-type", default="", choices=["", "工序", "工具"],
-                   help="该 query 的解构方向(写入 search_data.mode_type;空=通用)")
+                   help="解构方向,决定写哪张表(工具 → search_tools;其余 → search_process)")
     p.add_argument("--platforms", default="xhs,gzh")
     p.add_argument("--max-count", type=int, default=10)
     p.add_argument("--eval-model", default=DEFAULT_EVAL_MODEL, choices=list(EVAL_MODELS))

+ 8 - 8
examples/mode_workflow/pipeline/tool_extract.py

@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-"""工具解构 · search_data 帖子 → 结构化工具条目 → mode_tools 表
+"""工具解构 · search_tools 帖子 → 结构化工具条目 → mode_tools 表
 ================================================================================
-- 帖子源:search_data 表(--query-id + --case-ids 定位)
+- 帖子源:search_tools 表(--query-id + --case-ids 定位)
 - 模型默认 google/gemini-3.1-flash-lite,可 --model 传任意 OpenRouter id
 - 多模态:复用 search_and_evaluate._attach_image_refs(URL 直传)
-- 写库:db.replace_tools(同版本幂等,跨版本保留);runs/tools/ 留调试副本
+- 写库:db.replace_tools(同版本幂等,跨版本保留);runs/mode_tools/ 留调试副本
 
 用法(一般由 server.py 起子进程调):
   python pipeline/tool_extract.py --query-id q0000 --case-ids xhs_abc,gzh_def
@@ -39,7 +39,7 @@ MAX_IMAGES = 6
 
 
 def _row_to_source(row):
-    """search_data 行 → 引擎函数认的 source dict。"""
+    """search_tools 行 → 引擎函数认的 source dict。"""
     return {
         "case_id": row["case_id"], "platform": row["platform"],
         "channel_content_id": row["channel_content_id"],
@@ -89,9 +89,9 @@ async def run(args):
     case_ids = [c.strip() for c in args.case_ids.split(",") if c.strip()]
     sources = []
     for cid in case_ids:
-        row = db.fetch_post(qid, cid)
+        row = db.fetch_post(qid, cid, table="search_tools")
         if row is None:
-            print(f"⚠️ {qid}/{cid} 不在 search_data,跳过")
+            print(f"⚠️ {qid}/{cid} 不在 search_tools,跳过")
             continue
         sources.append(_row_to_source(row))
     if not sources:
@@ -107,7 +107,7 @@ async def run(args):
 
     await _attach_image_refs(sources, MAX_IMAGES, max(2, args.max_concurrent * 2), "url")
     sem = asyncio.Semaphore(args.max_concurrent)
-    out_dir = MW / "runs" / "tools"
+    out_dir = MW / "runs" / "mode_tools"
     out_dir.mkdir(parents=True, exist_ok=True)
 
     async def _work(s):
@@ -131,7 +131,7 @@ async def run(args):
 
 
 def main():
-    p = argparse.ArgumentParser(description="工具解构:search_data 帖子 → mode_tools")
+    p = argparse.ArgumentParser(description="工具解构:search_tools 帖子 → mode_tools")
     p.add_argument("--query-id", required=True)
     p.add_argument("--case-ids", required=True, help="逗号分隔 case_id 列表")
     p.add_argument("--model", default=None, help="默认 gemini-flash-lite,可传 OpenRouter id")

+ 1200 - 0
examples/mode_workflow/search.html

@@ -0,0 +1,1200 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>知识检索 — 知识检索中心</title>
+  <style>
+    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+
+    :root {
+      --primary:       #2563EB;
+      --primary-light: #EFF6FF;
+      --primary-hover: #1D4ED8;
+      --bg:            #F1F5F9;
+      --surface:       #FFFFFF;
+      --border:        #E2E8F0;
+      --border-focus:  #A5B4FC;
+      --text:          #0F172A;
+      --text-sub:      #475569;
+      --text-muted:    #94A3B8;
+      --radius:        8px;
+
+      --substance-bg: #EFF6FF; --substance: #1D4ED8;
+      --form-bg:      #F5F3FF; --form:      #6D28D9;
+      --intent-bg:    #F0FDF4; --intent:    #15803D;
+      --effect-bg:    #FFF7ED; --effect:    #C2410C;
+      --feeling-bg:   #FDF2F8; --feeling:   #BE185D;
+      --dim-bg:       #F8FAFC; --dim:       #64748B;
+    }
+
+    body {
+      font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
+      background: var(--bg);
+      color: var(--text);
+      font-size: 14px;
+      line-height: 1.5;
+    }
+
+    /* ── 搜索栏 ───────────────────────────────────────────────────── */
+    .search-section {
+      position: sticky; top: 0; z-index: 199;
+      background: var(--surface);
+      border-bottom: 1px solid var(--border);
+      padding: 11px 16px;
+    }
+    .search-inner { max-width: 1400px; margin: 0 auto; display: flex; gap: 8px; }
+    .search-input-wrap { flex: 0 1 680px; min-width: 240px; position: relative; }
+    .search-icon {
+      position: absolute; left: 10px; top: 50%;
+      transform: translateY(-50%);
+      color: var(--text-muted); pointer-events: none;
+      display: flex; align-items: center;
+    }
+    .search-input {
+      width: 100%; height: 38px;
+      padding: 0 12px 0 34px;
+      border: 1.5px solid var(--border); border-radius: 6px;
+      font-size: 14px; outline: none;
+      background: var(--bg); color: var(--text);
+      transition: border-color .15s, background .15s;
+    }
+    .search-input:focus { border-color: var(--border-focus); background: #fff; }
+    .btn-primary {
+      height: 38px; padding: 0 18px;
+      background: var(--primary); color: #fff;
+      border: none; border-radius: 6px;
+      font-size: 14px; font-weight: 500; cursor: pointer;
+      transition: background .15s; white-space: nowrap;
+    }
+    .btn-primary:hover { background: var(--primary-hover); }
+
+    /* ── 布局 ─────────────────────────────────────────────────────── */
+    .layout {
+      display: flex;
+      max-width: 1400px; margin: 0 auto;
+      padding: 16px; gap: 14px;
+      align-items: flex-start;
+    }
+
+    /* ── 侧栏 ─────────────────────────────────────────────────────── */
+    .sidebar {
+      width: 232px; flex-shrink: 0;
+      position: sticky; top: 126px;
+      max-height: calc(100vh - 132px);
+      overflow-y: auto;
+    }
+    .sidebar::-webkit-scrollbar { width: 3px; }
+    .sidebar::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
+
+    .filter-card {
+      background: var(--surface);
+      border: 1px solid var(--border); border-radius: var(--radius);
+      overflow: hidden;
+    }
+    .filter-section { border-bottom: 1px solid var(--border); }
+    .filter-section:last-child { border-bottom: none; }
+    .section-hd {
+      display: flex; align-items: center; justify-content: space-between;
+      padding: 10px 13px; cursor: pointer; user-select: none;
+      font-size: 13px; font-weight: 600; color: var(--text);
+      transition: background .1s;
+    }
+    .section-hd:hover { background: var(--bg); }
+    .section-hd .chevron { color: var(--text-muted); font-size: 10px; transition: transform .2s; }
+    .section-hd.open .chevron { transform: rotate(180deg); }
+    .section-bd { display: none; padding: 2px 13px 10px; }
+    .section-bd.open { display: block; }
+
+    .sub-group { margin-bottom: 10px; }
+    .sub-label {
+      font-size: 10px; font-weight: 700; letter-spacing: .6px;
+      text-transform: uppercase; color: var(--text-muted);
+      padding: 5px 0 3px;
+    }
+    .semantic-input {
+      width: 100%; height: 26px; padding: 0 8px;
+      border: 1px solid var(--border); border-radius: 4px;
+      font-size: 12px; outline: none; color: var(--text);
+      background: var(--bg); margin-bottom: 5px;
+      transition: border-color .15s;
+    }
+    .semantic-input:focus { border-color: var(--border-focus); background: #fff; }
+    .semantic-input::placeholder { color: var(--text-muted); }
+
+    .opt {
+      display: flex; align-items: center; gap: 6px;
+      padding: 3px 0; cursor: pointer;
+      font-size: 13px; color: var(--text-sub);
+    }
+    .opt:hover { color: var(--primary); }
+    .opt input[type="checkbox"] {
+      accent-color: var(--primary);
+      width: 13px; height: 13px; cursor: pointer; flex-shrink: 0;
+    }
+    .opt-text { flex: 1; }
+    .opt-count {
+      font-size: 11px; color: var(--text-muted);
+      background: var(--bg); border-radius: 8px;
+      padding: 0 5px; min-width: 20px; text-align: center;
+    }
+
+    .range-row { display: flex; align-items: center; gap: 5px; margin-top: 5px; }
+    .range-inp {
+      flex: 1; height: 28px; padding: 0 7px;
+      border: 1px solid var(--border); border-radius: 4px;
+      font-size: 12px; outline: none; color: var(--text); min-width: 0;
+    }
+    .range-inp:focus { border-color: var(--border-focus); }
+    .range-sep { color: var(--text-muted); font-size: 12px; }
+
+    /* ── 建议下拉(portal,fixed 定位到 body)──────────────────────── */
+    .suggest-dropdown {
+      background: var(--surface);
+      border: 1px solid var(--border); border-radius: 4px;
+      overflow: hidden;
+      box-shadow: 0 6px 16px rgba(0,0,0,.12);
+      max-height: 220px; overflow-y: auto;
+    }
+    .suggest-item {
+      padding: 6px 10px; font-size: 12px;
+      color: var(--text-sub); cursor: pointer;
+      transition: background .1s;
+    }
+    .suggest-item:hover { background: var(--primary-light); color: var(--primary); }
+
+    /* ── 结果区域 ─────────────────────────────────────────────────── */
+    .results-area { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
+
+    .chips-bar {
+      display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
+      padding: 9px 13px;
+      background: var(--surface);
+      border: 1px solid var(--border); border-radius: var(--radius);
+    }
+    .chips-label { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
+    .chip {
+      display: inline-flex; align-items: center; gap: 3px;
+      padding: 2px 8px; border-radius: 4px;
+      background: var(--primary-light); color: var(--primary);
+      font-size: 12px; font-weight: 500; cursor: pointer;
+    }
+    .chip-x { font-size: 13px; opacity: .55; margin-left: 1px; }
+    .chip:hover .chip-x { opacity: 1; }
+    .chip-clear { margin-left: auto; font-size: 12px; color: var(--text-muted); cursor: pointer; }
+    .chip-clear:hover { color: #EF4444; }
+
+    .results-bar {
+      display: flex; align-items: center; justify-content: space-between;
+    }
+    .results-count { font-size: 13px; color: var(--text-sub); }
+    .results-count strong { color: var(--text); font-weight: 600; }
+    .sort-label { font-size: 12px; color: var(--text-muted); }
+
+    /* ── 卡片 ─────────────────────────────────────────────────────── */
+    .card {
+      background: var(--surface);
+      border: 1px solid var(--border); border-radius: var(--radius);
+      padding: 15px 16px; cursor: pointer;
+      transition: border-color .15s, box-shadow .15s;
+    }
+    .card:hover { border-color: #C7D2FE; box-shadow: 0 3px 12px rgba(79,70,229,.08); }
+
+    .card-top {
+      display: flex; align-items: flex-start;
+      justify-content: space-between; gap: 10px; margin-bottom: 6px;
+    }
+    .card-title {
+      font-size: 15px; font-weight: 600; color: var(--text);
+      line-height: 1.4; flex: 1;
+    }
+    .card-title em {
+      font-style: normal; color: var(--primary);
+      background: var(--primary-light); padding: 0 2px; border-radius: 2px;
+    }
+    .score-badge {
+      flex-shrink: 0; font-size: 11px; font-weight: 600;
+      color: #15803D; background: #F0FDF4;
+      padding: 2px 7px; border-radius: 10px; white-space: nowrap;
+    }
+    .card-meta {
+      display: flex; align-items: center; flex-wrap: wrap;
+      gap: 3px 10px; font-size: 12px; color: var(--text-muted); margin-bottom: 9px;
+    }
+    .source-badge {
+      display: inline-flex; align-items: center;
+      padding: 1px 6px;
+      background: var(--bg); border: 1px solid var(--border);
+      border-radius: 4px; font-size: 11px; color: var(--text-sub);
+    }
+    .meta-dot { color: var(--border); }
+    .tag-row { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px; }
+    .tag {
+      display: inline-flex; align-items: center; gap: 2px;
+      padding: 2px 7px; border-radius: 4px;
+      font-size: 11px; font-weight: 500; line-height: 1.6;
+    }
+    .tag-pre { opacity: .65; font-size: 10px; }
+    .tag.s  { background: var(--substance-bg); color: var(--substance); }
+    .tag.fo { background: var(--form-bg);      color: var(--form); }
+    .tag.i  { background: var(--intent-bg);    color: var(--intent); }
+    .tag.e  { background: var(--effect-bg);    color: var(--effect); }
+    .tag.fe { background: var(--feeling-bg);   color: var(--feeling); }
+    .tag.d  { background: var(--dim-bg);       color: var(--dim); border: 1px solid var(--border); }
+    .tag.hit { box-shadow: 0 0 0 1.5px currentColor; font-weight: 700; }
+    .tag.d.hit { border-color: var(--dim); }
+    .ext-item.hit .ext-key { color: var(--text-sub); }
+    .ext-item.hit .ext-val { color: var(--primary); font-weight: 700; }
+    .card-foot {
+      display: flex; align-items: center; justify-content: space-between;
+      padding-top: 9px; border-top: 1px solid var(--bg);
+    }
+    .ext-row { display: flex; flex-wrap: wrap; gap: 10px; }
+    .ext-item { font-size: 11px; }
+    .ext-key { color: var(--text-muted); }
+    .ext-val { color: var(--text-sub); font-weight: 500; }
+    .card-time { font-size: 11px; color: var(--text-muted); white-space: nowrap; }
+
+    /* ── 分页 ─────────────────────────────────────────────────────── */
+    .pagination {
+      display: flex; justify-content: center; align-items: center;
+      gap: 3px; padding: 6px 0 4px;
+    }
+    .pg-btn {
+      min-width: 32px; height: 32px; padding: 0 8px;
+      display: inline-flex; align-items: center; justify-content: center;
+      border: 1px solid var(--border); border-radius: 4px;
+      background: var(--surface); color: var(--text-sub);
+      font-size: 13px; cursor: pointer; transition: all .15s; user-select: none;
+    }
+    .pg-btn:hover:not(.active):not([disabled]) { border-color: var(--primary); color: var(--primary); }
+    .pg-btn.active { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
+    .pg-btn[disabled] { color: var(--text-muted); cursor: default; }
+    .pg-dots { font-size: 13px; color: var(--text-muted); padding: 0 2px; }
+
+    /* ── 空/加载/错误状态 ─────────────────────────────────────────── */
+    .state-box {
+      text-align: center; padding: 60px 20px;
+      color: var(--text-muted); font-size: 14px;
+      background: var(--surface);
+      border: 1px solid var(--border); border-radius: var(--radius);
+    }
+    .state-box.error { color: #EF4444; }
+    .state-box .state-icon { font-size: 32px; margin-bottom: 10px; }
+    .state-box p { margin-top: 6px; font-size: 13px; }
+
+    /* ── 侧栏骨架 ─────────────────────────────────────────────────── */
+    .sidebar-loading {
+      padding: 20px 13px;
+      display: flex; flex-direction: column; gap: 8px;
+    }
+    .skel {
+      height: 12px; border-radius: 4px;
+      background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
+      background-size: 200% 100%;
+      animation: shimmer 1.4s infinite;
+    }
+    @keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
+
+    /* ── 语义输入框 loading 圈 ────────────────────────────────────────── */
+    .sem-wrap { position: relative; }
+    .sem-wrap .semantic-input { padding-right: 26px; }
+    .sem-spinner {
+      position: absolute; right: 7px; top: 50%;
+      transform: translateY(-50%);
+      width: 11px; height: 11px;
+      border: 2px solid var(--border);
+      border-top-color: var(--primary);
+      border-radius: 50%;
+      animation: sem-spin .65s linear infinite;
+      display: none; pointer-events: none;
+    }
+    .sem-spinner.show { display: block; }
+    @keyframes sem-spin { to { transform: translateY(-50%) rotate(360deg); } }
+
+    /* ── 正文展开 ─────────────────────────────────────────────────── */
+    .content-toggle {
+      display: flex; align-items: center; gap: 5px;
+      padding: 7px 0 2px;
+      font-size: 12px; color: var(--text-muted);
+      cursor: pointer; user-select: none;
+      border-top: 1px solid var(--bg); margin-top: 8px;
+    }
+    .content-toggle:hover { color: var(--primary); }
+    .content-caret {
+      font-size: 9px; display: inline-block;
+      transition: transform .2s; margin-left: auto;
+    }
+    .content-toggle.open .content-caret { transform: rotate(180deg); }
+    .content-body { display: none; }
+    .content-body.open { display: block; padding-top: 6px; }
+    .content-pre {
+      margin: 0; padding: 10px 12px;
+      background: var(--bg); border: 1px solid var(--border); border-radius: 5px;
+      font-family: 'Courier New', Consolas, monospace;
+      font-size: 11px; line-height: 1.65; color: var(--text-sub);
+      max-height: 300px; overflow-y: auto;
+      white-space: pre-wrap; word-break: break-all;
+    }
+  </style>
+</head>
+<body>
+
+<div class="search-section">
+  <div class="search-inner">
+    <div class="search-input-wrap">
+      <span class="search-icon">
+        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
+          <circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
+        </svg>
+      </span>
+      <input id="search-input" class="search-input" type="text" placeholder="搜索知识标题、正文内容…">
+    </div>
+    <button id="search-btn" class="btn-primary">搜索</button>
+  </div>
+</div>
+
+<div class="layout">
+  <aside class="sidebar">
+    <div class="filter-card" id="sidebar-card">
+      <div class="sidebar-loading">
+        <div class="skel" style="width:60%"></div>
+        <div class="skel" style="width:90%"></div>
+        <div class="skel" style="width:75%"></div>
+        <div class="skel" style="width:80%"></div>
+        <div class="skel" style="width:55%"></div>
+      </div>
+    </div>
+  </aside>
+
+  <div class="results-area">
+    <div class="chips-bar" id="chips-bar" style="display:none"></div>
+
+    <div class="results-bar">
+      <div class="results-count" id="results-count">加载中…</div>
+      <div class="sort-label" id="sort-label"></div>
+    </div>
+
+    <div id="results-list">
+      <div class="state-box"><div class="state-icon">🔍</div><p>正在加载…</p></div>
+    </div>
+
+    <div class="pagination" id="pagination"></div>
+  </div>
+</div>
+
+<script>
+const API = '/api/v1/knowledge';
+
+const SCOPE_TYPES  = ['substance','form','intent','effect','feeling'];
+const SCOPE_LABELS = {substance:'实质', form:'形式', intent:'意图', effect:'作用', feeling:'感受'};
+const SCOPE_TAGS   = {substance:'s', form:'fo', intent:'i', effect:'e', feeling:'fe'};
+
+// ── 转义工具 ──────────────────────────────────────────────────────────
+const esc = s => String(s ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
+
+function debounce(fn, ms) {
+  let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); };
+}
+
+// ── 全局状态 ──────────────────────────────────────────────────────────
+let dims = null;
+let _portalDropdown = null;
+function clearPortalDropdown() {
+  if (_portalDropdown) { _portalDropdown.remove(); _portalDropdown = null; }
+}
+document.addEventListener('mousedown', e => {
+  if (_portalDropdown && !_portalDropdown.contains(e.target)) clearPortalDropdown();
+});
+
+const sel = {
+  query:          '',
+  scopes:         {substance: new Set(), form: new Set(), intent: new Set(), effect: new Set(), feeling: new Set()},
+  scopeSemantic:  {substance: '', form: '', intent: '', effect: '', feeling: ''},
+  dimAttr:        new Set(),
+  dimCreate:      new Set(),
+  customValues:   {},   // key → Set<string>
+  customSemantics:{},   // key → string
+  customRanges:   {},   // key → {gte, lte}
+  page:           1,
+};
+
+let _chips = [];
+
+// ── 初始化 ────────────────────────────────────────────────────────────
+async function init() {
+  document.getElementById('search-btn').addEventListener('click', triggerSearch);
+  document.getElementById('search-input').addEventListener('keydown', e => {
+    if (e.key === 'Enter') triggerSearch();
+  });
+
+  try {
+    const r = await fetch(API + '/dimensions');
+    if (r.ok) {
+      dims = await r.json();
+      renderSidebar();
+    }
+  } catch(e) {
+    console.warn('Failed to load dimensions', e);
+    document.getElementById('sidebar-card').innerHTML =
+      '<div class="sidebar-loading" style="color:var(--text-muted);font-size:12px;padding:16px 13px">筛选项加载失败</div>';
+  }
+
+  doSearch();
+}
+
+function triggerSearch() {
+  sel.query = document.getElementById('search-input').value.trim();
+  sel.page  = 1;
+  doSearch();
+}
+
+// ── 侧栏渲染 ──────────────────────────────────────────────────────────
+function renderSidebar() {
+  const card = document.getElementById('sidebar-card');
+  let html = '';
+
+  // 作用域
+  html += `<div class="filter-section">
+    <div class="section-hd open" onclick="toggleSection(this)">作用域 <span class="chevron">▼</span></div>
+    <div class="section-bd open" id="scope-bd">`;
+  for (const sg of (dims?.scope_groups || [])) {
+    html += renderScopeGroup(sg);
+  }
+  html += `</div></div>`;
+
+  // 属性维度(从 facets 动态注入)
+  html += `<div class="filter-section" id="dim-attr-section" style="display:none">
+    <div class="section-hd open" onclick="toggleSection(this)">属性维度 <span class="chevron">▼</span></div>
+    <div class="section-bd open" id="dim-attr-bd"></div>
+  </div>`;
+
+  // 创作维度(从 facets 动态注入)
+  html += `<div class="filter-section" id="dim-create-section" style="display:none">
+    <div class="section-hd open" onclick="toggleSection(this)">创作维度 <span class="chevron">▼</span></div>
+    <div class="section-bd open" id="dim-create-bd"></div>
+  </div>`;
+
+  // 自定义字段(section 默认隐藏,有 facets 数据时才显示)
+  if (dims?.custom_fields?.length) {
+    html += `<div class="filter-section" id="custom-section" style="display:none">
+      <div class="section-hd open" onclick="toggleSection(this)">自定义索引 <span class="chevron">▼</span></div>
+      <div class="section-bd open" id="custom-bd">`;
+    for (const cf of dims.custom_fields) {
+      html += renderCustomField(cf);
+    }
+    html += `</div></div>`;
+  }
+
+  card.innerHTML = html;
+  bindSidebarEvents();
+}
+
+function renderScopeGroup(sg) {
+  const st    = sg.scope_type;
+  const label = SCOPE_LABELS[st] || st;
+  return `<div class="sub-group" id="sg-${st}">
+    <div class="sub-label">${label}</div>
+    <div class="sem-wrap">
+      <input class="semantic-input" type="text" id="sem-${st}" placeholder="语义搜索${label}标签…">
+      <span class="sem-spinner" id="sem-${st}-sp"></span>
+    </div>
+    <div class="suggest-list" id="sug-${st}"></div>
+  </div>`;
+}
+
+function renderCustomField(cf) {
+  const label = esc(cf.description || cf.key);
+  let html = `<div class="sub-group" id="cf-${esc(cf.key)}"><div class="sub-label">${label}</div>`;
+
+  if (cf.value_type === 'str') {
+    if (cf.semantic_enabled) {
+      html += `<div class="sem-wrap">
+        <input class="semantic-input" type="text" id="csem-${esc(cf.key)}" placeholder="语义搜索${label}…">
+        <span class="sem-spinner" id="csem-${esc(cf.key)}-sp"></span>
+      </div>`;
+    }
+    html += `<div class="suggest-list" id="csug-${esc(cf.key)}"></div>`;
+  } else if (cf.value_type === 'num') {
+    html += `<div class="range-row">
+      <input class="range-inp" type="number" id="cgte-${esc(cf.key)}" placeholder="最小">
+      <span class="range-sep">—</span>
+      <input class="range-inp" type="number" id="clte-${esc(cf.key)}" placeholder="最大">
+    </div>`;
+  } else if (cf.value_type === 'date') {
+    html += `<div class="range-row">
+      <input class="range-inp" type="date" id="cgte-${esc(cf.key)}">
+      <span class="range-sep">—</span>
+      <input class="range-inp" type="date" id="clte-${esc(cf.key)}">
+    </div>`;
+  }
+
+  html += `</div>`;
+  return html;
+}
+
+function bindSidebarEvents() {
+  // 作用域复选框
+  document.querySelectorAll('input[data-scope]').forEach(cb => {
+    cb.addEventListener('change', () => {
+      const st = cb.dataset.scope, val = cb.dataset.val;
+      if (cb.checked) sel.scopes[st].add(val); else sel.scopes[st].delete(val);
+      sel.page = 1; doSearch();
+    });
+  });
+
+  // 作用域语义输入
+  const debouncedSuggestScope = debounce((st, q) => {
+    if (q) suggestScope(st, q);
+    else clearPortalDropdown();
+  }, 300);
+
+  for (const sg of (dims?.scope_groups || [])) {
+    const st  = sg.scope_type;
+    const inp = document.getElementById('sem-' + st);
+    if (!inp) continue;
+    inp.addEventListener('input', () => {
+      sel.scopeSemantic[st] = inp.value.trim();
+      debouncedSuggestScope(st, inp.value.trim());
+    });
+    inp.addEventListener('keydown', e => { if (e.key === 'Enter') { sel.page = 1; doSearch(); } });
+    inp.addEventListener('blur', clearPortalDropdown);
+  }
+
+  // 自定义字段复选框
+  document.querySelectorAll('input[data-ckey]').forEach(cb => {
+    cb.addEventListener('change', () => {
+      const key = cb.dataset.ckey, val = cb.dataset.val;
+      if (!sel.customValues[key]) sel.customValues[key] = new Set();
+      if (cb.checked) sel.customValues[key].add(val); else sel.customValues[key].delete(val);
+      sel.page = 1; doSearch();
+    });
+  });
+
+  // 自定义语义输入
+  const debouncedSuggestCustom = debounce((key, q) => {
+    if (q) suggestCustom(key, q);
+    else clearPortalDropdown();
+  }, 300);
+
+  for (const cf of (dims?.custom_fields || [])) {
+    if (cf.value_type !== 'str' || !cf.semantic_enabled) continue;
+    const inp = document.getElementById('csem-' + cf.key);
+    if (!inp) continue;
+    inp.addEventListener('input', () => {
+      sel.customSemantics[cf.key] = inp.value.trim();
+      debouncedSuggestCustom(cf.key, inp.value.trim());
+    });
+    inp.addEventListener('keydown', e => { if (e.key === 'Enter') { sel.page = 1; doSearch(); } });
+    inp.addEventListener('blur', clearPortalDropdown);
+  }
+
+  // 自定义范围输入
+  for (const cf of (dims?.custom_fields || [])) {
+    if (cf.value_type !== 'num' && cf.value_type !== 'date') continue;
+    const gteEl = document.getElementById('cgte-' + cf.key);
+    const lteEl = document.getElementById('clte-' + cf.key);
+    const onChange = debounce(() => {
+      if (!sel.customRanges[cf.key]) sel.customRanges[cf.key] = {};
+      if (cf.value_type === 'num') {
+        sel.customRanges[cf.key].gte = gteEl?.value !== '' ? parseFloat(gteEl.value) : null;
+        sel.customRanges[cf.key].lte = lteEl?.value !== '' ? parseFloat(lteEl.value) : null;
+      } else {
+        sel.customRanges[cf.key].gte = gteEl?.value ? new Date(gteEl.value).getTime() : null;
+        sel.customRanges[cf.key].lte = lteEl?.value ? new Date(lteEl.value + 'T23:59:59').getTime() : null;
+      }
+      sel.page = 1; doSearch();
+    }, 500);
+    gteEl?.addEventListener('input', onChange);
+    lteEl?.addEventListener('input', onChange);
+  }
+}
+
+// ── 建议 API ──────────────────────────────────────────────────────────
+async function suggestScope(scopeType, q) {
+  const inputEl = document.getElementById('sem-' + scopeType);
+  const sp = document.getElementById('sem-' + scopeType + '-sp');
+  if (!inputEl) return;
+  if (sp) sp.classList.add('show');
+  try {
+    const r = await fetch(`${API}/scope-tags/suggest?scope_type=${encodeURIComponent(scopeType)}&q=${encodeURIComponent(q)}`);
+    if (!r.ok) return;
+    const data = await r.json();
+    renderSuggestDropdown(inputEl, data.tags || [], val => {
+      sel.scopes[scopeType].add(val);
+      inputEl.value = '';
+      sel.scopeSemantic[scopeType] = '';
+      addInlineScopeTag(scopeType, val);
+      sel.page = 1; doSearch();
+    });
+  } catch(e) {
+  } finally {
+    if (sp) sp.classList.remove('show');
+  }
+}
+
+async function suggestCustom(key, q) {
+  const inputEl = document.getElementById('csem-' + key);
+  const sp = document.getElementById('csem-' + key + '-sp');
+  if (!inputEl) return;
+  if (sp) sp.classList.add('show');
+  try {
+    const r = await fetch(`${API}/custom-values/suggest?key=${encodeURIComponent(key)}&q=${encodeURIComponent(q)}`);
+    if (!r.ok) return;
+    const data = await r.json();
+    renderSuggestDropdown(inputEl, data.values || [], val => {
+      if (!sel.customValues[key]) sel.customValues[key] = new Set();
+      sel.customValues[key].add(val);
+      inputEl.value = '';
+      sel.customSemantics[key] = '';
+      addInlineCustomValue(key, val);
+      sel.page = 1; doSearch();
+    });
+  } catch(e) {
+  } finally {
+    if (sp) sp.classList.remove('show');
+  }
+}
+
+function renderSuggestDropdown(inputEl, items, onSelect) {
+  clearPortalDropdown();
+  if (!items.length) return;
+  const rect = inputEl.getBoundingClientRect();
+  const div = document.createElement('div');
+  div.className = 'suggest-dropdown';
+  div.style.cssText = `position:fixed;z-index:9999;top:${rect.bottom + 2}px;left:${rect.left}px;width:${rect.width}px;`;
+  items.forEach(item => {
+    const el = document.createElement('div');
+    el.className = 'suggest-item';
+    el.textContent = item;
+    el.addEventListener('mousedown', e => e.preventDefault());
+    el.addEventListener('click', () => { onSelect(item); clearPortalDropdown(); });
+    div.appendChild(el);
+  });
+  document.body.appendChild(div);
+  _portalDropdown = div;
+}
+
+function addInlineScopeTag(scopeType, val) {
+  const container = document.getElementById('sg-' + scopeType);
+  if (!container) return;
+  const existing = container.querySelector(`input[data-val="${CSS.escape(val)}"]`);
+  if (existing) { existing.checked = true; return; }
+  const label = document.createElement('label');
+  label.className = 'opt';
+  label.innerHTML = `<input type="checkbox" checked data-scope="${esc(scopeType)}" data-val="${esc(val)}"><span class="opt-text">${esc(val)}</span>`;
+  label.querySelector('input').addEventListener('change', function() {
+    if (this.checked) sel.scopes[scopeType].add(val); else sel.scopes[scopeType].delete(val);
+    sel.page = 1; doSearch();
+  });
+  const sugEl = container.querySelector('.suggest-list');
+  if (sugEl) container.insertBefore(label, sugEl); else container.appendChild(label);
+}
+
+function addInlineCustomValue(key, val) {
+  const container = document.getElementById('cf-' + key);
+  if (!container) return;
+  const existing = container.querySelector(`input[data-val="${CSS.escape(val)}"]`);
+  if (existing) { existing.checked = true; return; }
+  const label = document.createElement('label');
+  label.className = 'opt';
+  label.innerHTML = `<input type="checkbox" checked data-ckey="${esc(key)}" data-val="${esc(val)}"><span class="opt-text">${esc(val)}</span>`;
+  label.querySelector('input').addEventListener('change', function() {
+    if (!sel.customValues[key]) sel.customValues[key] = new Set();
+    if (this.checked) sel.customValues[key].add(val); else sel.customValues[key].delete(val);
+    sel.page = 1; doSearch();
+  });
+  const sugEl = container.querySelector('.suggest-list');
+  if (sugEl) container.insertBefore(label, sugEl); else container.appendChild(label);
+}
+
+// ── 搜索请求 ──────────────────────────────────────────────────────────
+function buildRequest() {
+  const req = {
+    page: sel.page,
+    page_size: 20,
+    include_facets: true,
+    highlight: !!sel.query,
+    include_content: true,
+    include_matched_conditions: true,
+  };
+
+  if (sel.query) req.query = sel.query;
+
+  const scopes = [];
+  for (const st of SCOPE_TYPES) {
+    const values   = [...sel.scopes[st]];
+    const semantic = sel.scopeSemantic[st];
+    if (values.length || semantic) {
+      const sf = {scope_type: st};
+      if (values.length) sf.values = values;
+      if (semantic)      sf.semantic_query = semantic;
+      scopes.push(sf);
+    }
+  }
+  if (scopes.length) req.scopes = scopes;
+
+  if (sel.dimAttr.size)   req.dim_attributes = [...sel.dimAttr];
+  if (sel.dimCreate.size) req.dim_creations  = [...sel.dimCreate];
+
+  const customFilters = [];
+  const allKeys = new Set([
+    ...Object.keys(sel.customValues),
+    ...Object.keys(sel.customSemantics),
+    ...Object.keys(sel.customRanges),
+  ]);
+  for (const key of allKeys) {
+    const cf = {key};
+    const vals = [...(sel.customValues[key] || [])];
+    const sem  = sel.customSemantics[key];
+    const rng  = sel.customRanges[key];
+    if (vals.length) cf.values = vals;
+    if (sem)         cf.semantic_query = sem;
+    if (rng?.gte != null) cf.gte = rng.gte;
+    if (rng?.lte != null) cf.lte = rng.lte;
+    if (Object.keys(cf).length > 1) customFilters.push(cf);
+  }
+  if (customFilters.length) req.custom_filters = customFilters;
+
+  return req;
+}
+
+async function doSearch() {
+  renderChips();
+  document.getElementById('results-list').innerHTML =
+    '<div class="state-box"><div class="state-icon">⏳</div><p>搜索中…</p></div>';
+
+  let resp;
+  try {
+    const r = await fetch(API + '/search', {
+      method: 'POST',
+      headers: {'Content-Type': 'application/json'},
+      body: JSON.stringify(buildRequest()),
+    });
+    if (!r.ok) {
+      const msg = (await r.json().catch(() => ({}))).detail || r.statusText;
+      throw new Error(msg);
+    }
+    resp = await r.json();
+  } catch(e) {
+    document.getElementById('results-count').textContent = '';
+    document.getElementById('results-list').innerHTML =
+      `<div class="state-box error"><div class="state-icon">⚠️</div><p>搜索出错:${esc(e.message)}</p></div>`;
+    return;
+  }
+
+  renderResults(resp);
+  if (resp.facets) updateSidebarFacets(resp.facets);
+}
+
+// ── 渲染结果 ──────────────────────────────────────────────────────────
+function renderResults(data) {
+  document.getElementById('results-count').innerHTML =
+    `找到 <strong>${data.total.toLocaleString()}</strong> 条相关知识`;
+  document.getElementById('sort-label').textContent =
+    sel.query ? '按相关度排序' : '按最新更新排序';
+
+  const list = document.getElementById('results-list');
+  if (!data.hits.length) {
+    list.innerHTML = '<div class="state-box"><div class="state-icon">📭</div><p>未找到匹配的知识条目,请调整搜索条件</p></div>';
+  } else {
+    list.innerHTML = data.hits.map(renderCard).join('');
+  }
+
+  renderPagination(data.total, data.page, data.page_size);
+}
+
+function renderCard(hit) {
+  let titleHtml = esc(hit.title || '(无标题)');
+  if (hit.highlight?.title?.[0]) titleHtml = hit.highlight.title[0];
+
+  const score = hit.score != null
+    ? `<span class="score-badge">相关度 ${hit.score.toFixed(2)}</span>` : '';
+
+  let meta = '';
+  if (hit.source_type) meta += `<span class="source-badge">${esc(hit.source_type)}</span>`;
+  if (hit.author)      meta += `<span>${esc(hit.author)}</span>`;
+  if (hit.author && hit.source_title) meta += '<span class="meta-dot">·</span>';
+  if (hit.source_title) meta += `<span>${esc(hit.source_title)}</span>`;
+
+  // 从 matched_conditions 构建命中查找表
+  const mc = hit.matched_conditions;
+  const hitScopes = {};   // scope_type → Set<string>
+  const hitCustom = {};   // key → Set<string>(str 类型)
+  const hitRange  = {};   // key → bool(num/date 类型)
+  const hitDimAttr   = new Set(mc?.dim_attributes || []);
+  const hitDimCreate = new Set(mc?.dim_creations  || []);
+  for (const ms of (mc?.scopes || [])) hitScopes[ms.scope_type] = new Set(ms.matched_values);
+  for (const cm of (mc?.custom || [])) {
+    if (cm.matched_values != null) hitCustom[cm.key] = new Set(cm.matched_values);
+    if (cm.in_range  != null) hitRange[cm.key]  = cm.in_range;
+  }
+
+  let tags = '';
+  const scopeDefs = [
+    ['s','scope_substance','substance','实质'],
+    ['fo','scope_form','form','形式'],
+    ['i','scope_intent','intent','意图'],
+    ['e','scope_effect','effect','作用'],
+    ['fe','scope_feeling','feeling','感受'],
+  ];
+  for (const [cls, field, st, label] of scopeDefs) {
+    const hitSet = hitScopes[st] || new Set();
+    for (const t of (hit[field] || [])) {
+      const h = hitSet.has(t) ? ' hit' : '';
+      tags += `<span class="tag ${cls}${h}" title="${h ? '命中筛选条件' : ''}"><span class="tag-pre">${label}</span>${esc(t)}</span>`;
+    }
+  }
+  for (const d of (hit.dim_attributes || [])) {
+    const h = hitDimAttr.has(d) ? ' hit' : '';
+    tags += `<span class="tag d${h}" title="${h ? '命中筛选条件' : ''}">${esc(d)}</span>`;
+  }
+  for (const d of (hit.dim_creations || [])) {
+    const h = hitDimCreate.has(d) ? ' hit' : '';
+    tags += `<span class="tag d${h}" title="${h ? '命中筛选条件' : ''}">${esc(d)}</span>`;
+  }
+
+  let extHtml = '';
+  for (const item of (hit.custom_ext || [])) {
+    let val = item.value;
+    if (item.type === 'date' && typeof val === 'number') {
+      val = new Date(val).toLocaleDateString('zh-CN');
+    }
+    const isHit = item.type === 'str'
+      ? hitCustom[item.key]?.has(String(item.value ?? ''))
+      : hitRange[item.key] === true;
+    const h = isHit ? ' hit' : '';
+    extHtml += `<span class="ext-item${h}" title="${h ? '命中筛选条件' : ''}"><span class="ext-key">${esc(item.key)}:</span><span class="ext-val">${esc(String(val ?? ''))}</span></span>`;
+  }
+
+  const updatedAt = hit.updated_at
+    ? new Date(hit.updated_at).toLocaleDateString('zh-CN') : '';
+
+  // 正文展开区:尝试格式化 JSON,否则原样展示
+  let contentSection = '';
+  if (hit.content) {
+    let display = hit.content;
+    try { display = JSON.stringify(JSON.parse(hit.content), null, 2); } catch {}
+    contentSection = `
+    <div class="content-toggle" onclick="this.classList.toggle('open');this.nextElementSibling.classList.toggle('open')">
+      <span>正文</span><span class="content-caret">▾</span>
+    </div>
+    <div class="content-body">
+      <pre class="content-pre">${esc(display)}</pre>
+    </div>`;
+  }
+
+  return `<div class="card">
+    <div class="card-top"><div class="card-title">${titleHtml}</div>${score}</div>
+    ${meta ? `<div class="card-meta">${meta}</div>` : ''}
+    ${tags ? `<div class="tag-row">${tags}</div>` : ''}
+    ${contentSection}
+    <div class="card-foot">
+      <div class="ext-row">${extHtml}</div>
+      <span class="card-time">${updatedAt ? updatedAt + ' 更新' : ''}</span>
+    </div>
+  </div>`;
+}
+
+// ── 分页 ──────────────────────────────────────────────────────────────
+function renderPagination(total, page, pageSize) {
+  const totalPages = Math.ceil(total / pageSize);
+  const pg = document.getElementById('pagination');
+  if (totalPages <= 1) { pg.innerHTML = ''; return; }
+
+  let html = `<button class="pg-btn" onclick="goPage(${page-1})" ${page<=1?'disabled':''}>‹</button>`;
+
+  const pages = buildPageList(page, totalPages);
+  let prev = null;
+  for (const p of pages) {
+    if (prev !== null && p - prev > 1) html += '<span class="pg-dots">…</span>';
+    html += `<button class="pg-btn ${p===page?'active':''}" onclick="goPage(${p})">${p}</button>`;
+    prev = p;
+  }
+  html += `<button class="pg-btn" onclick="goPage(${page+1})" ${page>=totalPages?'disabled':''}>›</button>`;
+  pg.innerHTML = html;
+}
+
+function buildPageList(cur, total) {
+  const s = new Set([1, total]);
+  for (let p = Math.max(1, cur-1); p <= Math.min(total, cur+1); p++) s.add(p);
+  return [...s].sort((a,b) => a-b);
+}
+
+function goPage(p) {
+  sel.page = p;
+  doSearch();
+  window.scrollTo({top: 0, behavior: 'smooth'});
+}
+
+// ── Facets → 侧栏 ─────────────────────────────────────────────────────
+function updateSidebarFacets(facets) {
+  // 属性维度 / 创作维度:整体替换
+  updateFacetSection(
+    'dim-attr-section', 'dim-attr-bd',
+    facets.dim_attributes || [],
+    sel.dimAttr, 'data-dim-attr',
+    cb => { const v = cb.dataset.dimAttr; cb.checked ? sel.dimAttr.add(v) : sel.dimAttr.delete(v); sel.page=1; doSearch(); }
+  );
+  updateFacetSection(
+    'dim-create-section', 'dim-create-bd',
+    facets.dim_creations || [],
+    sel.dimCreate, 'data-dim-create',
+    cb => { const v = cb.dataset.dimCreate; cb.checked ? sel.dimCreate.add(v) : sel.dimCreate.delete(v); sel.page=1; doSearch(); }
+  );
+
+  // 作用域标签:完全由 facets 驱动,移除消失的项、补充新出现的项
+  const scopeMap = Object.fromEntries((facets.scopes || []).map(s => [s.scope_type, s.buckets || []]));
+  for (const st of SCOPE_TYPES) {
+    const buckets     = scopeMap[st] || [];
+    const bucketMap   = Object.fromEntries(buckets.map(b => [b.value, b.count]));
+    const sgContainer = document.getElementById('sg-' + st);
+    if (!sgContainer) continue;
+
+    // 移除不在当前 facets 且未被选中的项
+    sgContainer.querySelectorAll('label[data-facet-src]').forEach(label => {
+      const val = label.querySelector('input')?.dataset.val;
+      if (val && bucketMap[val] == null && !(sel.scopes[st]?.has(val))) label.remove();
+    });
+
+    // 更新已存在项的计数,补充 facets 中新出现的项
+    const sugEl = sgContainer.querySelector('.suggest-list');
+    for (const b of buckets) {
+      const existing = sgContainer.querySelector(`input[data-val="${CSS.escape(b.value)}"]`);
+      if (existing) {
+        syncCountBadge(existing.closest('.opt'), b.count);
+        continue;
+      }
+      const label = document.createElement('label');
+      label.className = 'opt';
+      label.dataset.facetSrc = 'true';
+      const chk = sel.scopes[st]?.has(b.value) ? 'checked' : '';
+      label.innerHTML = `<input type="checkbox" ${chk} data-scope="${esc(st)}" data-val="${esc(b.value)}"><span class="opt-text">${esc(b.value)}</span><span class="opt-count">${b.count}</span>`;
+      label.querySelector('input').addEventListener('change', function() {
+        if (this.checked) sel.scopes[st].add(b.value); else sel.scopes[st].delete(b.value);
+        sel.page = 1; doSearch();
+      });
+      if (sugEl) sgContainer.insertBefore(label, sugEl); else sgContainer.appendChild(label);
+    }
+  }
+
+  // 自定义字段
+  updateCustomExtFacets(facets.custom_ext || []);
+}
+
+function updateFacetSection(sectionId, bdId, buckets, selSet, dataAttr, onChange) {
+  const section = document.getElementById(sectionId);
+  const bd      = document.getElementById(bdId);
+  if (!section || !bd) return;
+
+  if (!buckets.length) { section.style.display = 'none'; return; }
+  section.style.display = '';
+
+  let html = '';
+  for (const b of buckets) {
+    const checked = selSet.has(b.value) ? 'checked' : '';
+    html += `<label class="opt">
+      <input type="checkbox" ${checked} ${dataAttr}="${esc(b.value)}">
+      <span class="opt-text">${esc(b.value)}</span>
+      <span class="opt-count">${b.count}</span>
+    </label>`;
+  }
+  bd.innerHTML = html;
+  bd.querySelectorAll(`input[${dataAttr}]`).forEach(cb => {
+    cb.addEventListener('change', () => onChange(cb));
+  });
+}
+
+// 自定义字段 facets 处理:key 本身的显隐也由 facets 驱动
+function updateCustomExtFacets(customExtFacets) {
+  if (!dims?.custom_fields?.length) return;
+  const facetMap = Object.fromEntries(customExtFacets.map(f => [f.key, f]));
+  let anyVisible = false;
+
+  for (const cf of dims.custom_fields) {
+    const container = document.getElementById('cf-' + cf.key);
+    if (!container) continue;
+    const facet = facetMap[cf.key];
+
+    // 有活跃筛选时即使 facets 无数据也保留显示
+    const hasActiveFilter =
+      (cf.value_type === 'str' &&
+        (sel.customValues[cf.key]?.size > 0 || !!sel.customSemantics[cf.key])) ||
+      ((cf.value_type === 'num' || cf.value_type === 'date') &&
+        (sel.customRanges[cf.key]?.gte != null || sel.customRanges[cf.key]?.lte != null));
+
+    const hasFacetData =
+      (cf.value_type === 'str' && facet?.buckets?.length > 0) ||
+      ((cf.value_type === 'num' || cf.value_type === 'date') && facet?.stats?.count > 0);
+
+    if (!hasFacetData && !hasActiveFilter) {
+      container.style.display = 'none';
+      continue;
+    }
+
+    container.style.display = '';
+    anyVisible = true;
+
+    if (cf.value_type === 'str') {
+      updateCustomStrCounts(cf.key, container, facet?.buckets || []);
+    } else if (cf.value_type === 'num' && facet?.stats?.count > 0) {
+      const s = facet.stats;
+      const gteEl = document.getElementById('cgte-' + cf.key);
+      const lteEl = document.getElementById('clte-' + cf.key);
+      if (gteEl && s.min != null) gteEl.placeholder = `最小 (${parseFloat(s.min.toFixed(2))})`;
+      if (lteEl && s.max != null) lteEl.placeholder = `最大 (${parseFloat(s.max.toFixed(2))})`;
+    }
+    // date 类型:range input 不显示 placeholder,仅控制可见性
+  }
+
+  // 整个"自定义索引"区块:有可见 key 才展示
+  const section = document.getElementById('custom-section');
+  if (section) section.style.display = anyVisible ? '' : 'none';
+}
+
+function updateCustomStrCounts(key, container, buckets) {
+  const bucketMap = Object.fromEntries(buckets.map(b => [b.value, b.count]));
+
+  // 移除不在当前 facets 且未被选中的项
+  container.querySelectorAll('label[data-facet-src]').forEach(label => {
+    const val = label.querySelector('input')?.dataset.val;
+    if (val && bucketMap[val] == null && !(sel.customValues[key]?.has(val))) label.remove();
+  });
+
+  // 更新已存在项的计数,补充 facets 中新出现的项
+  const sugEl = container.querySelector('.suggest-list');
+  for (const b of buckets) {
+    const existing = container.querySelector(`input[data-val="${CSS.escape(b.value)}"]`);
+    if (existing) {
+      syncCountBadge(existing.closest('.opt'), b.count);
+      continue;
+    }
+    const label = document.createElement('label');
+    label.className = 'opt';
+    label.dataset.facetSrc = 'true';
+    const chk = sel.customValues[key]?.has(b.value) ? 'checked' : '';
+    label.innerHTML = `<input type="checkbox" ${chk} data-ckey="${esc(key)}" data-val="${esc(b.value)}"><span class="opt-text">${esc(b.value)}</span><span class="opt-count">${b.count}</span>`;
+    label.querySelector('input').addEventListener('change', function() {
+      if (!sel.customValues[key]) sel.customValues[key] = new Set();
+      if (this.checked) sel.customValues[key].add(b.value); else sel.customValues[key].delete(b.value);
+      sel.page = 1; doSearch();
+    });
+    if (sugEl) container.insertBefore(label, sugEl); else container.appendChild(label);
+  }
+}
+
+// 在 .opt 元素上同步 .opt-count 徽章;count 为 undefined 时清除徽章
+function syncCountBadge(optEl, count) {
+  if (!optEl) return;
+  let el = optEl.querySelector('.opt-count');
+  if (count != null) {
+    if (!el) { el = document.createElement('span'); el.className = 'opt-count'; optEl.appendChild(el); }
+    el.textContent = count;
+  } else if (el) {
+    el.remove();
+  }
+}
+
+// ── Chips 栏 ──────────────────────────────────────────────────────────
+function renderChips() {
+  _chips = [];
+
+  for (const st of SCOPE_TYPES) {
+    for (const val of sel.scopes[st]) {
+      _chips.push({
+        label: `${SCOPE_LABELS[st]}:${val}`,
+        remove: () => { sel.scopes[st].delete(val); uncheckInput(`input[data-scope="${CSS.escape(st)}"][data-val="${CSS.escape(val)}"]`); sel.page=1; doSearch(); }
+      });
+    }
+    if (sel.scopeSemantic[st]) {
+      _chips.push({
+        label: `${SCOPE_LABELS[st]} 语义:${sel.scopeSemantic[st]}`,
+        remove: () => {
+          sel.scopeSemantic[st] = '';
+          const inp = document.getElementById('sem-' + st);
+          if (inp) inp.value = '';
+          sel.page = 1; doSearch();
+        }
+      });
+    }
+  }
+
+  for (const val of sel.dimAttr)   _chips.push({label:`属性:${val}`,   remove:()=>{sel.dimAttr.delete(val);   uncheckInput(`input[data-dim-attr="${CSS.escape(val)}"]`);   sel.page=1; doSearch();}});
+  for (const val of sel.dimCreate) _chips.push({label:`创作:${val}`,   remove:()=>{sel.dimCreate.delete(val); uncheckInput(`input[data-dim-create="${CSS.escape(val)}"]`); sel.page=1; doSearch();}});
+
+  for (const [key, vals] of Object.entries(sel.customValues)) {
+    for (const val of vals) {
+      _chips.push({
+        label: `${key}:${val}`,
+        remove: () => { sel.customValues[key].delete(val); uncheckInput(`input[data-ckey="${CSS.escape(key)}"][data-val="${CSS.escape(val)}"]`); sel.page=1; doSearch(); }
+      });
+    }
+  }
+  for (const [key, sem] of Object.entries(sel.customSemantics)) {
+    if (!sem) continue;
+    _chips.push({
+      label: `${key} 语义:${sem}`,
+      remove: () => { sel.customSemantics[key]=''; const i=document.getElementById('csem-'+key); if(i)i.value=''; sel.page=1; doSearch(); }
+    });
+  }
+  for (const [key, rng] of Object.entries(sel.customRanges)) {
+    if (rng.gte == null && rng.lte == null) continue;
+    const parts = [];
+    if (rng.gte != null) parts.push(`≥ ${rng.gte}`);
+    if (rng.lte != null) parts.push(`≤ ${rng.lte}`);
+    _chips.push({
+      label: `${key}:${parts.join(' ')}`,
+      remove: () => {
+        sel.customRanges[key] = {};
+        const g = document.getElementById('cgte-'+key), l = document.getElementById('clte-'+key);
+        if(g) g.value=''; if(l) l.value='';
+        sel.page=1; doSearch();
+      }
+    });
+  }
+
+  const bar = document.getElementById('chips-bar');
+  if (!_chips.length) { bar.style.display = 'none'; return; }
+  bar.style.display = '';
+
+  let html = '<span class="chips-label">已选筛选:</span>';
+  _chips.forEach((c, i) => {
+    html += `<span class="chip" data-chip="${i}">${esc(c.label)}<span class="chip-x">×</span></span>`;
+  });
+  html += '<span class="chip-clear" id="chip-clear-all">清空全部</span>';
+  bar.innerHTML = html;
+
+  bar.querySelectorAll('[data-chip]').forEach(el => {
+    el.addEventListener('click', () => { _chips[+el.dataset.chip].remove(); });
+  });
+  document.getElementById('chip-clear-all')?.addEventListener('click', clearAllFilters);
+}
+
+function uncheckInput(selector) {
+  const el = document.querySelector(selector);
+  if (el) el.checked = false;
+}
+
+function clearAllFilters() {
+  SCOPE_TYPES.forEach(st => { sel.scopes[st].clear(); sel.scopeSemantic[st] = ''; const i=document.getElementById('sem-'+st); if(i)i.value=''; });
+  sel.dimAttr.clear();
+  sel.dimCreate.clear();
+  sel.customValues   = {};
+  sel.customSemantics= {};
+  sel.customRanges   = {};
+  document.querySelectorAll('input[data-scope],input[data-ckey],input[data-dim-attr],input[data-dim-create]').forEach(cb => cb.checked = false);
+  document.querySelectorAll('.range-inp').forEach(inp => inp.value = '');
+  sel.page = 1;
+  doSearch();
+}
+
+// ── 折叠展开 ──────────────────────────────────────────────────────────
+function toggleSection(hd) {
+  hd.classList.toggle('open');
+  hd.nextElementSibling.classList.toggle('open');
+}
+
+document.addEventListener('DOMContentLoaded', init);
+</script>
+</body>
+</html>

+ 50 - 9
examples/mode_workflow/server.py

@@ -3,6 +3,7 @@
 ================================================================================
 单服务(默认 8772):
   - GET  /                    index.html
+  - GET  /search.html         知识检索页(聚类库 tab 内嵌;API 域名由 .env 注入)
   - GET  /api/dashboard       Dashboard 全部聚合指标(含内容树覆盖)
   - GET  /api/queries|posts|process|tools(+_versions)   Dataset 数据
   - POST /api/run_search|extract_process|extract_tools  起子进程跑 pipeline
@@ -11,6 +12,7 @@
 用法:python server.py [port]
 """
 import json
+import os
 import subprocess
 import sys
 import threading
@@ -33,6 +35,21 @@ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8772
 MATRIX_FILE = HERE / "reference" / "judged_matrix.json"
 LOG_DIR = HERE / "runs" / "logs"
 
+# 知识检索 API 域名:从 .env 的 KNOWLEDGE_API_BASE 读取(db.py 已 load_dotenv)。
+# search.html 内写的是相对路径 '/api/v1/knowledge';serve 时把它替换成绝对地址,
+# 这样页面由本服务托管、接口仍打到独立的知识检索后端。
+KNOWLEDGE_API_BASE = os.getenv("KNOWLEDGE_API_BASE", "").rstrip("/")
+
+
+def _render_search_html():
+    html = (HERE / "search.html").read_text(encoding="utf-8")
+    if KNOWLEDGE_API_BASE:
+        html = html.replace(
+            "const API = '/api/v1/knowledge';",
+            f"const API = '{KNOWLEDGE_API_BASE}/api/v1/knowledge';",
+        )
+    return html.encode("utf-8")
+
 # ── 任务管理:task_id → {proc, log, status} ──────────────────────────────────
 TASKS = {}
 _TASK_LOCK = threading.Lock()
@@ -73,7 +90,8 @@ def _task_status(task_id):
 
 
 def _next_query_id():
-    qs = [q["query_id"] for q in db.fetch_queries()]
+    """两张搜索表统一编号,避免跨方向撞 ID。"""
+    qs = [q["query_id"] for m in ("process", "tools") for q in db.fetch_queries(m)]
     nums = [int(q[1:]) for q in qs if q.startswith("q") and q[1:].isdigit()]
     return f"q{(max(nums) + 1 if nums else 0):04d}"
 
@@ -168,14 +186,26 @@ def _dashboard():
             daily[ts[:10]] += c
     cost_trend = [{"date": d, "cost": round(v, 4)} for d, v in sorted(daily.items())]
 
-    # 进度:分母 = knowledge_type 含对应类型的帖子(distinct case)
-    proc_targets = {p["case_id"] for p in posts if "工序" in (p["knowledge_type"] or [])}
-    tool_targets = {p["case_id"] for p in posts if "工具" in (p["knowledge_type"] or [])}
-    proc_done = {r["case_id"] for r in procs}
-    tool_done = {r["case_id"] for r in tools}
+    # 进度:分子分母同口径,都走「采纳」。分母 = 该方向 search 表里采纳的帖(distinct case),
+    # 即「需解构」;分子 = 采纳帖里已解构的(∩ 保证 ≤ 分母,杜绝越界/虚高)。
+    # 方向由 p["mode"] 区分(process=search_process,tools=search_tools),不再看 knowledge_type。
+    proc_targets = {p["case_id"] for p in posts if p["mode"] == "process" and p["adopted"]}
+    tool_targets = {p["case_id"] for p in posts if p["mode"] == "tools" and p["adopted"]}
+    proc_extracted = {r["case_id"] for r in procs}
+    tool_extracted = {r["case_id"] for r in tools}
+    proc_done = proc_extracted & proc_targets
+    tool_done = tool_extracted & tool_targets
+
+    # 渠道分项/解构总数:按实际解构过的 distinct case(不限采纳),平台由 case 内禀。
+    extracted_all = proc_extracted | tool_extracted
+    case_plat = {p["case_id"]: (p["platform"] or "other") for p in posts}
+    collected_by_plat = Counter((p["platform"] or "other") for p in posts)
+    extracted_by_plat = Counter(case_plat.get(c, "other") for c in extracted_all)
 
     return {
         "result": {
+            "collected_by_platform": collected_by_plat.most_common(),
+            "extracted_by_platform": extracted_by_plat.most_common(),
             "matrix_covered": len(covered), "matrix_valid": len(valid),
             "matrix_cells": sorted([ai, ti] for ai, ti in covered),
             "matrix_actions": [a["name"] for a in jm["actions"]],
@@ -185,7 +215,7 @@ def _dashboard():
             "form_count": len(form_counter),
             "form_top": form_counter.most_common(15),
             "post_count": len(posts),
-            "extracted_post_count": len(proc_done | tool_done),
+            "extracted_post_count": len(extracted_all),
             "tool_count": len({r["tool_name"] for r in latest_tools if r["tool_name"]}),
             "via_top10": via_counter.most_common(10),
         },
@@ -226,14 +256,25 @@ class Handler(BaseHTTPRequestHandler):
                 self.send_response(200)
                 self.send_header("Content-Type", "text/html; charset=utf-8")
                 self.send_header("Content-Length", str(len(body)))
+                # 单文件前端,改版频繁:禁缓存,避免浏览器拿到旧 index.html
+                self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
+                self.end_headers()
+                self.wfile.write(body)
+            elif u.path == "/search.html":
+                # 聚类库 tab 内嵌的知识检索页;API 域名由 .env 注入
+                body = _render_search_html()
+                self.send_response(200)
+                self.send_header("Content-Type", "text/html; charset=utf-8")
+                self.send_header("Content-Length", str(len(body)))
+                self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
                 self.end_headers()
                 self.wfile.write(body)
             elif u.path == "/api/dashboard":
                 self._json(_dashboard())
             elif u.path == "/api/queries":
-                self._json(db.fetch_queries())
+                self._json(db.fetch_queries(qs.get("mode", "process")))
             elif u.path == "/api/posts":
-                self._json(db.fetch_posts(qs.get("query_id", "")))
+                self._json(db.fetch_posts(qs.get("query_id", ""), qs.get("mode", "process")))
             elif u.path == "/api/process_versions":
                 self._json(db.fetch_process_versions(qs.get("case_id", "")))
             elif u.path == "/api/process":

+ 113 - 0
examples/mode_workflow/shell/README.md

@@ -0,0 +1,113 @@
+# mode_workflow 查看服务 + 公网分享 使用说明
+
+把本地的 mode_workflow 查看服务(`server.py`,默认 `:8772`)一键起好,并通过 Cloudflare 隧道生成一个**公网链接**,发给客户就能看 —— 无需对方在同一局域网、无需对方改代理设置。
+
+脚本:`share.sh`(本目录)
+
+---
+
+## 快速开始
+
+```bash
+cd /Users/max_liu/max_liu/company/Agent/examples/mode_workflow/shell
+
+./share.sh start      # 起服务 + 隧道,打印公网链接
+```
+
+执行后会输出类似:
+
+```
+🌐 公网链接(发给客户即可,无需局域网/改代理):
+    https://advanced-how-leasing-brief.trycloudflare.com
+```
+
+把这个链接发给客户即可。**进程一直保留**(已脱离终端),关掉终端窗口也不会断。
+
+---
+
+## 全部命令
+
+| 命令 | 作用 |
+|------|------|
+| `./share.sh start`   | 起 `server.py`(后台)+ cloudflared 隧道(后台,http2),打印公网链接 |
+| `./share.sh stop`    | 停掉服务和隧道 |
+| `./share.sh restart` | 重启两者(**会换一个新链接**,记得重新发) |
+| `./share.sh status`  | 查看运行状态 + 当前链接 + 本地自检(HTTP 状态码) |
+| `./share.sh url`     | 只打印当前公网链接(方便复制) |
+
+`start` 是幂等的:服务已在跑就跳过,不会重复起进程,可放心反复执行当作"确保它在跑"。
+
+---
+
+## 典型场景
+
+**第一次分享 / 重新分享:**
+```bash
+./share.sh start          # 拿到链接,发给客户
+```
+
+**链接突然打不开了(先别慌,一条命令查):**
+```bash
+./share.sh status
+```
+- `server.py ❌` → 后端挂了,执行 `./share.sh start` 拉起来。
+- `cloudflared ❌` 或链接变了 → 隧道断了,执行 `./share.sh restart`(换新链接)。
+- 两个都 ✅ 但对方打不开 → 多半是对方浏览器/系统代理拦截,见下方"常见问题"。
+
+**忘了链接是多少:**
+```bash
+./share.sh url
+```
+
+**用完关闭分享:**
+```bash
+./share.sh stop
+```
+
+---
+
+## 它替你规避的坑(为什么不直接用局域网 IP / 不直接 `python server.py`)
+
+| 坑 | 现象 | 脚本的处理 |
+|----|------|-----------|
+| 前台运行,关终端被 SIGHUP 杀掉 | 关窗口/休眠后链接 502 | 用 `setsid`/`nohup` 脱离终端守护 |
+| QUIC/UDP 被公司网或 VPN 封 | 隧道死循环重连,公网打不开 | 固定 `--protocol http2`,走 TCP 443 |
+| 局域网共享要求同网段 | WiFi 客户端隔离 → ping 不通 | 走公网隧道,完全绕开局域网 |
+| 访客本地代理拦截内网 IP | 客户打不开 `192.168.x.x` | 公网 HTTPS,访客代理正常放行 |
+| 重复启动起一堆进程 | 端口冲突/混乱 | `start` 先检测端口,幂等 |
+
+---
+
+## 常见问题
+
+**Q:链接打开是 502 / Bad Gateway?**
+后端 `server.py` 没在跑(隧道只是转发器)。`./share.sh status` 确认,再 `./share.sh start`。
+
+**Q:对方打不开,但我本地和 `status` 都正常?**
+对方浏览器或系统开了代理(Clash/V2Ray 等),把公网域名也拦了。让对方临时关代理,或把 `trycloudflare.com` 加进代理白名单/直连规则。
+
+**Q:链接每次重启都变,能不能固定?**
+`trycloudflare` 是临时地址,绑定在 cloudflared 进程生命周期上,进程停就失效、重启换新。要**永久固定地址**需要 Cloudflare 账号 + 自有域名做 named tunnel —— 需要时再单独配置。
+
+**Q:日志在哪?**
+- 服务日志:`../.server.log`
+- 隧道日志:`../.cloudflared.log`
+(都在 `mode_workflow/` 目录下,以 `.` 开头隐藏。)
+
+**Q:换个端口?**
+```bash
+PORT=9000 ./share.sh start
+```
+
+**Q:用指定的 python 解释器?**
+```bash
+PYTHON=/path/to/python ./share.sh start
+```
+
+---
+
+## 依赖
+
+- `cloudflared`(已安装;如缺失:`brew install cloudflared`)
+- `python`(项目当前用 conda `base` 环境的 `python`)
+- `lsof` / `curl`(macOS 自带)

+ 131 - 0
examples/mode_workflow/shell/share.sh

@@ -0,0 +1,131 @@
+#!/usr/bin/env bash
+# ──────────────────────────────────────────────────────────────────────────
+# mode_workflow 查看服务 + Cloudflare 隧道 一键管理脚本
+#
+#   ./share.sh start     启动 server.py(后台) + cloudflared 隧道(后台,http2),打印公网链接
+#   ./share.sh stop      停掉两者
+#   ./share.sh restart   重启两者(换新链接)
+#   ./share.sh status     查看运行状态 + 当前链接
+#   ./share.sh url        只打印当前公网链接
+#
+# 设计要点:
+#   - 两个进程都用 nohup/setsid 脱离终端,关掉终端窗口也不会被 SIGHUP 杀掉。
+#   - cloudflared 强制 --protocol http2,绕开公司网/VPN 常封的 UDP(QUIC)。
+#   - 幂等:重复 start 会先清掉旧进程,不会起一堆。
+# ──────────────────────────────────────────────────────────────────────────
+set -euo pipefail
+
+# 项目目录 = 本脚本所在目录(shell/)的上一级
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJ_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+PORT="${PORT:-8772}"
+
+SERVER_LOG="$PROJ_DIR/.server.log"
+CF_LOG="$PROJ_DIR/.cloudflared.log"
+SERVER_PIDF="$PROJ_DIR/.server.pid"
+CF_PIDF="$PROJ_DIR/.cloudflared.pid"
+
+PY="${PYTHON:-python}"
+
+# 选一个能后台脱离的方式:优先 setsid,macOS 没有就用 nohup
+_spawn() {  # _spawn <logfile> <cmd...>
+  local log="$1"; shift
+  if command -v setsid >/dev/null 2>&1; then
+    setsid "$@" >"$log" 2>&1 < /dev/null &
+  else
+    nohup "$@" >"$log" 2>&1 < /dev/null &
+  fi
+  echo $!
+}
+
+_alive() { [ -n "${1:-}" ] && kill -0 "$1" 2>/dev/null; }
+
+_server_running() { lsof -nP -iTCP:"$PORT" -sTCP:LISTEN >/dev/null 2>&1; }
+
+_extract_url() {
+  # 优先看脚本自己的日志,兼容回退到手动启动时的 /tmp 日志;没找到不报错
+  { grep -hEo "https://[a-z0-9-]+\.trycloudflare\.com" "$CF_LOG" /tmp/cf_tunnel.log 2>/dev/null || true; } | tail -1
+}
+
+start_server() {
+  if _server_running; then
+    echo "✅ server.py 已在跑 (:$PORT)"
+    return
+  fi
+  echo "▶️  启动 server.py …"
+  ( cd "$PROJ_DIR" && _spawn "$SERVER_LOG" "$PY" server.py "$PORT" ) > "$SERVER_PIDF"
+  # 等监听端口起来
+  for _ in $(seq 1 20); do
+    _server_running && break
+    sleep 0.5
+  done
+  if _server_running; then
+    echo "✅ server.py 已启动 (:$PORT)  日志: $SERVER_LOG"
+  else
+    echo "❌ server.py 启动失败,看日志: $SERVER_LOG"; tail -15 "$SERVER_LOG" || true; exit 1
+  fi
+}
+
+start_tunnel() {
+  echo "▶️  启动 cloudflared 隧道 (http2) …"
+  : > "$CF_LOG"
+  _spawn "$CF_LOG" cloudflared tunnel --protocol http2 --url "http://localhost:$PORT" > "$CF_PIDF"
+  # 等 URL 出现
+  local url=""
+  for _ in $(seq 1 40); do
+    url="$(_extract_url)"
+    [ -n "$url" ] && break
+    sleep 0.5
+  done
+  if [ -n "$url" ]; then
+    # 再等连接注册成功
+    for _ in $(seq 1 20); do
+      grep -q "Registered tunnel connection" "$CF_LOG" && break
+      sleep 0.5
+    done
+    echo
+    echo "🌐 公网链接(发给客户即可,无需局域网/改代理):"
+    echo "    $url"
+    echo
+  else
+    echo "❌ 隧道未拿到地址,看日志: $CF_LOG"; tail -15 "$CF_LOG" || true; exit 1
+  fi
+}
+
+stop_all() {
+  echo "⏹  停止隧道与服务 …"
+  pkill -f "cloudflared tunnel --protocol http2 --url http://localhost:$PORT" 2>/dev/null && echo "  - cloudflared 已停" || echo "  - 无 cloudflared"
+  # 杀掉占用端口的 server.py
+  local pids; pids="$(lsof -nP -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true)"
+  if [ -n "$pids" ]; then
+    echo "$pids" | xargs kill 2>/dev/null && echo "  - server.py (:$PORT) 已停"
+  else
+    echo "  - 无 server.py 监听 :$PORT"
+  fi
+  rm -f "$SERVER_PIDF" "$CF_PIDF"
+}
+
+status() {
+  echo "── 状态 ──────────────────────────────"
+  if _server_running; then echo "server.py : ✅ 运行中 (:$PORT)"; else echo "server.py : ❌ 未运行"; fi
+  if pgrep -f "cloudflared tunnel .*localhost:$PORT" >/dev/null 2>&1; then
+    echo "cloudflared: ✅ 运行中"
+  else
+    echo "cloudflared: ❌ 未运行"
+  fi
+  local url; url="$(_extract_url)"
+  [ -n "$url" ] && echo "公网链接   : $url" || echo "公网链接   : (无)"
+  # 本地健康检查(绕代理)
+  local code; code="$(curl -s -m3 --noproxy '*' -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT/" 2>/dev/null || echo 000)"
+  echo "本地自检   : HTTP $code"
+  echo "─────────────────────────────────────"
+}
+
+case "${1:-start}" in
+  start)   start_server; start_tunnel ;;
+  stop)    stop_all ;;
+  restart) stop_all; sleep 1; start_server; start_tunnel ;;
+  status)  status ;;
+  url)     u="$(_extract_url)"; [ -n "$u" ] && echo "$u" || { echo "(隧道未运行)"; exit 1; } ;;
+  *) echo "用法: $0 {start|stop|restart|status|url}"; exit 1 ;;
+esac

+ 4370 - 47
examples/process_pipeline/script/search_eval/fixed_query_eval/.cloudflared.log

@@ -1,47 +1,4370 @@
-2026-06-11T02:33:40Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee, are subject to the Cloudflare Online Services Terms of Use (https://www.cloudflare.com/website-terms/), and Cloudflare reserves the right to investigate your use of Tunnels for violations of such terms. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
-2026-06-11T02:33:40Z INF Requesting new quick Tunnel on trycloudflare.com...
-2026-06-11T02:33:44Z INF +--------------------------------------------------------------------------------------------+
-2026-06-11T02:33:44Z INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
-2026-06-11T02:33:44Z INF |  https://colours-float-distributor-went.trycloudflare.com                                  |
-2026-06-11T02:33:44Z INF +--------------------------------------------------------------------------------------------+
-2026-06-11T02:33:44Z INF Cannot determine default configuration path. No file [config.yml config.yaml] in [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp /etc/cloudflared /usr/local/etc/cloudflared]
-2026-06-11T02:33:44Z INF Version 2026.6.0 (Checksum a13041d6ffff9d56f7df1629c24d9c0bacf4f73409d6cab0f5a1f60631ba9667)
-2026-06-11T02:33:44Z INF GOOS: darwin, GOVersion: go1.26.4, GoArch: amd64
-2026-06-11T02:33:44Z INF Settings: map[ha-connections:1 p:http2 protocol:http2 url:http://localhost:8770]
-2026-06-11T02:33:44Z INF cloudflared will not automatically update if installed by a package manager.
-2026-06-11T02:33:44Z INF Generated Connector ID: eadaf12f-1007-43fe-93f2-279140b8773d
-2026-06-11T02:33:44Z INF Initial protocol http2
-2026-06-11T02:33:44Z INF ICMP proxy will use 192.168.81.50 as source for IPv4
-2026-06-11T02:33:44Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
-2026-06-11T02:33:44Z INF Created ICMP proxy listening on 192.168.81.50:0
-2026-06-11T02:33:44Z INF Created ICMP proxy listening on [::1]:0
-2026-06-11T02:33:44Z INF ICMP proxy will use 192.168.81.50 as source for IPv4
-2026-06-11T02:33:44Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
-2026-06-11T02:33:44Z INF Starting metrics server on 127.0.0.1:20241/metrics
-2026-06-11T02:33:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.77
-2026-06-11T02:33:46Z INF Registered tunnel connection connIndex=0 connection=6bb57297-9ab0-4bf7-9f72-6aeb0bc233dc event=0 ip=198.41.192.77 location=lax10 protocol=http2
-2026-06-11T02:33:54Z INF +-----------------------------------------------------------------------------------------------+
-2026-06-11T02:33:54Z INF |                                    CONNECTIVITY PRE-CHECKS                                    |
-2026-06-11T02:33:54Z INF +-----------------------------------------------------------------------------------------------+
-2026-06-11T02:33:54Z INF |  COMPONENT         TARGET                     STATUS  DETAILS                                 |
-2026-06-11T02:33:54Z INF |  DNS Resolution    region1.v2.argotunnel.com  PASS    DNS Resolved successfully               |
-2026-06-11T02:33:54Z INF |  DNS Resolution    region2.v2.argotunnel.com  PASS    DNS Resolved successfully               |
-2026-06-11T02:33:54Z INF |  UDP Connectivity  region1.v2.argotunnel.com  PASS    QUIC connection successful              |
-2026-06-11T02:33:54Z INF |  UDP Connectivity  region2.v2.argotunnel.com  FAIL    QUIC connection failed                  |
-2026-06-11T02:33:54Z INF |  TCP Connectivity  region1.v2.argotunnel.com  PASS    HTTP/2 connection successful            |
-2026-06-11T02:33:54Z INF |  TCP Connectivity  region2.v2.argotunnel.com  PASS    HTTP/2 connection successful            |
-2026-06-11T02:33:54Z INF |  Cloudflare API    api.cloudflare.com:443     PASS    API is reachable                        |
-2026-06-11T02:33:54Z INF |  WARNING: Allow outbound QUIC traffic on port 7844 or use HTTP2.                              |
-2026-06-11T02:33:54Z INF |                                                                                               |
-2026-06-11T02:33:54Z INF |  SUMMARY: Environment ready with degraded transport. cloudflared will proceed using 'http2'.  |
-2026-06-11T02:33:54Z INF +-----------------------------------------------------------------------------------------------+
-2026-06-11T02:33:54Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=region1.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=region2.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="UDP Connectivity" details="QUIC connection successful" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=region1.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="UDP Connectivity" details="QUIC connection failed" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=fail target=region2.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=region1.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=region2.v2.argotunnel.com
-2026-06-11T02:33:54Z INF precheck component="Cloudflare API" details="API is reachable" run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a status=pass target=api.cloudflare.com:443
-2026-06-11T02:33:54Z INF precheck complete hard_fail=false run_id=284bf4de-59c1-41e5-9be3-bbcb31374a0a suggested_protocol=http2
-2026-06-11T02:55:26Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8770: connect: connection refused" connIndex=0 event=1 ingressRule=0 originService=http://localhost:8770
-2026-06-11T02:55:26Z ERR failed to serve incoming request error="Failed to proxy HTTP: Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8770: connect: connection refused"
+2026-06-12T07:15:34Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee, are subject to the Cloudflare Online Services Terms of Use (https://www.cloudflare.com/website-terms/), and Cloudflare reserves the right to investigate your use of Tunnels for violations of such terms. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
+2026-06-12T07:15:34Z INF Requesting new quick Tunnel on trycloudflare.com...
+2026-06-12T07:15:39Z INF +--------------------------------------------------------------------------------------------+
+2026-06-12T07:15:39Z INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
+2026-06-12T07:15:39Z INF |  https://rebecca-eliminate-significantly-andreas.trycloudflare.com                         |
+2026-06-12T07:15:39Z INF +--------------------------------------------------------------------------------------------+
+2026-06-12T07:15:39Z INF Cannot determine default configuration path. No file [config.yml config.yaml] in [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp /etc/cloudflared /usr/local/etc/cloudflared]
+2026-06-12T07:15:39Z INF Version 2026.6.0 (Checksum a13041d6ffff9d56f7df1629c24d9c0bacf4f73409d6cab0f5a1f60631ba9667)
+2026-06-12T07:15:39Z INF GOOS: darwin, GOVersion: go1.26.4, GoArch: amd64
+2026-06-12T07:15:39Z INF Settings: map[ha-connections:1 p:http2 protocol:http2 url:http://localhost:8770]
+2026-06-12T07:15:39Z INF cloudflared will not automatically update if installed by a package manager.
+2026-06-12T07:15:39Z INF Generated Connector ID: f9318307-36d5-42a6-99c8-69ba04ffe668
+2026-06-12T07:15:39Z INF Initial protocol http2
+2026-06-12T07:15:39Z INF ICMP proxy will use 192.168.81.52 as source for IPv4
+2026-06-12T07:15:39Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
+2026-06-12T07:15:39Z INF Created ICMP proxy listening on 192.168.81.52:0
+2026-06-12T07:15:39Z INF Created ICMP proxy listening on [::1]:0
+2026-06-12T07:15:39Z INF ICMP proxy will use 192.168.81.52 as source for IPv4
+2026-06-12T07:15:39Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
+2026-06-12T07:15:39Z INF Starting metrics server on 127.0.0.1:20241/metrics
+2026-06-12T07:15:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T07:15:40Z INF Registered tunnel connection connIndex=0 connection=8c0b4f2c-5294-4600-8597-fbba0554d9cc event=0 ip=198.41.192.47 location=lax05 protocol=http2
+2026-06-12T07:15:47Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T07:15:47Z INF |                               CONNECTIVITY PRE-CHECKS                               |
+2026-06-12T07:15:47Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T07:15:47Z INF |  COMPONENT         TARGET                     STATUS  DETAILS                       |
+2026-06-12T07:15:47Z INF |  DNS Resolution    region1.v2.argotunnel.com  PASS    DNS Resolved successfully     |
+2026-06-12T07:15:47Z INF |  DNS Resolution    region2.v2.argotunnel.com  PASS    DNS Resolved successfully     |
+2026-06-12T07:15:47Z INF |  UDP Connectivity  region1.v2.argotunnel.com  PASS    QUIC connection successful    |
+2026-06-12T07:15:47Z INF |  UDP Connectivity  region2.v2.argotunnel.com  PASS    QUIC connection successful    |
+2026-06-12T07:15:47Z INF |  TCP Connectivity  region1.v2.argotunnel.com  PASS    HTTP/2 connection successful  |
+2026-06-12T07:15:47Z INF |  TCP Connectivity  region2.v2.argotunnel.com  PASS    HTTP/2 connection successful  |
+2026-06-12T07:15:47Z INF |  Cloudflare API    api.cloudflare.com:443     PASS    API is reachable              |
+2026-06-12T07:15:47Z INF |                                                                                     |
+2026-06-12T07:15:47Z INF |  SUMMARY: Environment is healthy. cloudflared will use 'quic' as primary protocol.  |
+2026-06-12T07:15:47Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T07:15:47Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region1.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region2.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="UDP Connectivity" details="QUIC connection successful" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region1.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="UDP Connectivity" details="QUIC connection successful" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region2.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region1.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=region2.v2.argotunnel.com
+2026-06-12T07:15:47Z INF precheck component="Cloudflare API" details="API is reachable" run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 status=pass target=api.cloudflare.com:443
+2026-06-12T07:15:47Z INF precheck complete hard_fail=false run_id=b9fc90bc-ffd4-484c-8716-c113815cf924 suggested_protocol=quic
+2026-06-12T08:15:44Z ERR Failed to refresh DNS local resolver error="lookup region1.v2.argotunnel.com: i/o timeout"
+2026-06-12T14:58:09Z INF Lost connection with the edge connIndex=0
+2026-06-12T14:58:09Z ERR failed to serve incoming request error="Error shutting down control stream: context canceled"
+2026-06-12T14:58:09Z ERR Serve tunnel error error="connection with edge closed" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:09Z INF Retrying connection in up to 1s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:11Z ERR Connection terminated error="connection with edge closed" connIndex=0
+2026-06-12T14:58:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:58:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:19Z INF Retrying connection in up to 4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T14:58:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:58:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:43Z INF Retrying connection in up to 8s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:58:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T14:59:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:59:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:59:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:59:40Z INF Retrying connection in up to 16s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T14:59:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:00:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:00:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:28Z INF Retrying connection in up to 32s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:00:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:00:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:00:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:03:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:03:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:03:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:03:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:03:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:08:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:08:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:08:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:08:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:09:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:12:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:12:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:12:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:12:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:12:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:13:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:13:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:13:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:13:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:13:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:14:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:14:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:14:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:14:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:14:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:20:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:20:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:20:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:20:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:20:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:24:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:24:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:24:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:24:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:25:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:27:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:27:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:27:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:27:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:27:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:30:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:30:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:30:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:30:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:31:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:35:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:35:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:35:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:35:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:35:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:38:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:38:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:38:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:38:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:38:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:40:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:40:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:40:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:40:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:40:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:44:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:44:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:44:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:44:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:44:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:47:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:47:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:47:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:47:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:47:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:48:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:48:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:48:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:48:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:48:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:49:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:49:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:49:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:49:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:50:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:55:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:55:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:55:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:55:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:55:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:56:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:56:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:56:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:56:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T15:56:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:00:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:00:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:00:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:00:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:00:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:02:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:02:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:02:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:02:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:02:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:04:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:04:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:04:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:04:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:05:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:08:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:08:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:08:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:08:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:08:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:12:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:12:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:12:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:12:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:12:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:17:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:17:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:17:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:17:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:17:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:17:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:17:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:18:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:18:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:18:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:20:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:20:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:20:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:20:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:21:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:25:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:25:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:25:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:25:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:25:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:25:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:25:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:26:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:30:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:30:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:30:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:30:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:30:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:32:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:32:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:32:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:32:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:32:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:33:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:33:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:33:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:33:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:33:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:38:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:38:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:38:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:38:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:39:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:40:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:41:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:41:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:41:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:41:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:45:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:45:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:45:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:45:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:45:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:48:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:48:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:48:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:48:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:48:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:50:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:50:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:50:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:50:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:50:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:53:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:53:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:53:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:53:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:53:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:58:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:58:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:58:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:58:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T16:59:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:04:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:04:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:04:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:04:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:04:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:08:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:08:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:08:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:08:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:09:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:10:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:10:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:10:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:10:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:11:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:13:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:13:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:13:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:13:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:13:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:15:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:15:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:15:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:15:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:15:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:18:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:18:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:18:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:18:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:18:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:19:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:19:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:19:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:19:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:19:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:25:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:25:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:25:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:25:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:25:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:28:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:28:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:28:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:28:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:29:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:31:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:31:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:34:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:34:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:34:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:35:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:35:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:35:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:35:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:35:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:37:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:37:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:37:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:37:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:38:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:43:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:43:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:43:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:43:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:43:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:46:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:46:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:46:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:46:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:46:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:51:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:51:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:51:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:51:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:51:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:52:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:52:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:52:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:52:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:52:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:53:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:53:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:53:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:53:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:54:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:55:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:55:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:55:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:55:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T17:55:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:01:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:01:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:01:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:01:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:01:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:05:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:06:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:06:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:06:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:06:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:07:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:07:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:07:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:07:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:07:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:08:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:08:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:08:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:08:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:08:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:09:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:09:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:09:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:09:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:09:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:12:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:12:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:12:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:12:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:12:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:13:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:13:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:13:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:13:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:13:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:14:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:14:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:14:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:14:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:14:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:19:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:19:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:19:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:19:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:19:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:23:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:23:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:23:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:23:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:23:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:23:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:23:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:23:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:23:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:24:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:27:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:27:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:27:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:27:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:27:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:28:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:28:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:28:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:28:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:28:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:33:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:33:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:33:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:33:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:33:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:37:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:37:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:37:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:37:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:37:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:38:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:38:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:38:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:38:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:38:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:42:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:42:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:42:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:42:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:42:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:47:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:47:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:47:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:47:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:47:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:47:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:47:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:47:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:47:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:48:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:49:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:49:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:49:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:49:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:50:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:52:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:52:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:52:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:52:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:52:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:54:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:54:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:54:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:54:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:54:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:57:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:57:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:57:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:57:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T18:58:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:01:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:01:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:01:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:01:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:01:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:02:52Z ERR Failed to refresh DNS local resolver error="lookup region1.v2.argotunnel.com: i/o timeout"
+2026-06-12T19:06:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:06:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:06:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:06:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:06:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:08:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:08:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:08:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:08:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:08:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:11:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:11:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:11:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:11:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:12:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:17:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:17:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:17:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:17:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:17:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:18:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:18:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:18:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:18:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:19:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:24:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:24:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:24:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:24:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:24:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:27:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:27:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:27:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:27:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:28:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:30:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:30:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:30:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:30:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:31:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:36:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:36:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:36:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:36:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:36:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:37:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:37:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:37:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:37:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:38:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:41:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:41:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:41:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:41:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:42:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:44:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:44:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:44:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:44:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:44:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:49:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:49:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:49:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:49:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:50:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:53:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:53:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:53:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:53:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:54:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:57:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:57:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:57:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:57:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:57:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:58:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:58:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:58:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:58:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T19:58:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:02:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:02:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:02:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:02:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:02:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:03:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:03:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:03:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:03:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:03:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:08:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:08:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:08:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:08:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:09:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:09:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:09:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:09:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:09:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:09:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:13:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:13:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:13:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:13:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:13:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:15:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:15:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:15:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:15:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:15:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:16:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:16:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:16:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:16:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:17:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:21:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:21:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:21:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:21:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:21:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:25:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:25:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:25:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:25:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:26:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:27:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:27:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:27:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:27:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:27:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:32:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:32:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:32:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:32:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:32:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:34:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:34:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:34:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:34:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:34:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:38:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:38:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:38:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:38:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:38:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:39:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:39:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:39:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:39:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:39:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:40:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:40:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:40:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:40:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:40:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:43:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:43:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:43:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:43:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:44:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:46:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:46:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:46:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:46:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:47:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:50:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:50:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:50:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:50:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:50:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:52:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:52:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:52:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:52:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:52:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:55:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:55:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:55:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:55:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:55:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:56:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:56:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:56:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:56:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:56:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:58:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:58:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:58:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:58:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T20:58:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:02:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:03:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:03:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:03:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:03:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:06:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:06:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:06:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:06:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:06:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:09:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:09:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:09:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:09:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:09:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:10:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:10:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:10:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:10:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:10:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:13:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:13:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:13:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:13:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:13:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:17:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:17:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:17:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:17:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:17:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:22:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:22:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:22:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:22:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:22:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:23:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:23:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:23:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:23:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:23:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:26:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:26:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:26:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:26:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:26:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:28:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:28:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:28:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:28:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:28:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:29:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:29:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:29:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:29:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:29:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:31:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:31:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:31:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:31:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:31:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:35:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:35:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:35:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:35:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:35:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:37:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:37:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:37:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:37:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:38:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:39:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:39:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:39:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:39:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:39:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:44:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:44:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:44:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:44:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:44:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:49:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:49:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:49:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:49:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:49:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:54:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:54:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:54:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:54:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:55:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:55:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:55:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:55:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:55:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:55:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:58:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:58:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:58:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:58:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T21:59:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:03:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:04:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:04:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:04:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:04:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:09:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:09:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:09:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:09:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:09:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:12:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:12:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:12:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:12:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:12:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:17:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:17:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:17:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:17:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:17:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:21:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:21:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:21:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:21:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:21:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:26:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:26:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:26:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:26:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:26:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:31:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:31:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:31:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:31:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:31:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:36:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:36:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:36:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:36:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:36:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:41:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:41:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:41:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:41:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:41:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:45:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:45:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:45:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:45:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:45:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:47:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:47:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:47:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:47:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:47:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:51:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:52:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:52:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:52:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:52:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:53:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:53:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:53:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:53:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:53:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:55:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:55:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:55:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:55:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:56:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:58:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:58:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:58:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:58:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T22:58:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:01:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:01:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:01:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:01:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:01:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:05:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:05:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:05:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:05:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:05:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:06:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:06:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:06:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:06:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:06:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:08:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:08:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:08:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:08:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:08:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:13:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:13:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:13:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:13:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:13:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:15:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:15:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:15:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:15:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:15:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:18:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:18:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:18:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:18:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:18:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:19:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:19:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:19:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:19:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:19:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:23:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:23:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:23:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:23:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:24:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:27:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:27:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:27:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:27:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:27:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:32:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:32:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:32:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:32:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:32:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:33:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:33:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:33:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:33:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:33:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:34:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:34:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:34:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:34:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:35:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:38:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:38:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:38:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:38:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:38:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:43:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:43:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:43:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:43:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:43:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:47:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:47:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:47:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:47:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:47:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:51:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:51:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:51:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:51:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:51:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:56:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:56:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:56:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:56:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-12T23:56:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:00:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:00:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:00:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:00:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:01:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:05:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:05:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:05:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:05:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:05:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:06:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:06:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:06:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:06:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:06:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:11:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:11:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:11:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:11:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:11:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:16:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:16:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:16:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:16:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:17:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:21:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:21:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:21:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:21:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:21:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:22:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:22:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:22:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:22:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:22:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:23:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:23:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:23:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:23:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:24:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:27:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:27:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:27:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:27:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:27:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:28:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:28:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:28:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:28:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:28:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:30:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:30:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:30:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:30:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:31:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:35:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:35:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:35:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:35:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:35:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:39:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:39:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:39:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:39:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:40:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:44:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:44:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:44:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:44:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:44:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:45:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:45:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:45:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:45:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:45:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:48:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:48:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:48:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:48:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:48:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:53:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:53:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:53:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:53:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:53:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:54:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:54:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:54:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:54:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:55:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:57:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:57:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:57:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:57:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T00:57:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:01:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:01:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:01:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:01:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:01:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:04:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:04:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:04:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:04:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:04:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:09:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:09:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:09:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:09:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:09:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:12:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:12:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:12:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:12:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:12:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:15:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:15:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:15:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:15:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:15:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:16:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:16:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:16:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:16:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:16:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:21:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:21:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:21:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:21:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:21:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:24:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:24:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:24:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:24:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:24:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:27:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:27:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:27:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:27:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:27:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:31:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:31:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:31:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:31:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:31:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:34:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:34:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:34:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:34:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:34:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:34:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:34:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:34:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:34:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:35:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:35:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:35:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:35:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:35:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:35:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:37:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:37:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:37:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:37:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:38:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:40:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:40:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:40:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:40:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:40:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:42:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:43:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:43:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:43:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:43:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:45:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:45:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:45:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:45:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:45:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:48:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:48:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:48:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:48:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:49:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:54:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:54:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:54:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:54:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:54:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:55:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:55:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:55:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:55:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:56:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:56:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:56:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:56:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:56:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T01:56:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:00:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:00:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:00:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:00:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:00:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:06:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:06:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:06:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:06:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:06:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:10:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:10:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:10:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:10:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:10:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:14:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:14:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:14:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:14:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:14:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:15:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:15:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:15:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:15:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:15:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:20:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:20:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:20:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:20:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:20:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:25:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:25:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:25:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:25:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:25:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:27:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:27:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:27:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:27:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:27:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:31:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:31:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:31:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:31:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:31:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:32:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:32:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:32:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:32:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:32:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:37:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:37:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:37:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:37:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:37:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:42:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:42:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:42:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:42:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:42:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:46:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:46:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:46:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:46:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:46:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:48:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:48:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:48:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:48:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:48:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:53:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:53:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:53:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:53:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:53:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:54:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:54:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:54:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:54:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:55:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:58:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:58:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:58:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:58:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T02:58:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:02:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:02:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:02:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:02:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:02:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:03:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:03:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:03:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:03:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:04:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:05:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:05:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:05:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:05:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:05:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:08:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:08:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:08:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:08:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:08:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:09:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:09:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:09:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:09:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:10:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:12:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:12:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:12:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:12:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:12:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:17:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:17:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:17:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:17:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:17:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:22:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:22:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:22:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:22:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:22:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:23:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:23:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:24:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:24:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:24:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:28:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:28:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:28:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:28:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:28:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:33:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:33:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:33:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:33:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:33:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:38:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:38:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:38:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:38:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:39:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:44:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:44:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:44:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:44:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:45:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:45:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:45:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:45:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:45:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:45:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:49:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:49:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:49:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:49:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:50:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:51:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:51:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:51:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:51:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:52:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:57:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:57:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:57:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:57:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T03:57:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:01:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:01:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:01:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:01:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:02:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:03:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:03:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:03:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:03:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:03:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:04:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:04:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:04:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:04:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:04:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:06:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:06:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:06:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:06:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:07:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:11:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:11:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:11:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:11:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:11:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:14:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:14:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:14:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:14:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:14:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:15:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:15:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:15:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:15:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:16:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:20:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:20:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:20:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:20:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:20:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:21:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:21:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:21:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:21:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:21:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:25:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:25:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:25:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:25:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:26:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:29:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:29:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:29:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:29:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:29:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:31:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:31:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:31:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:31:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:31:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:32:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:32:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:32:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:32:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:32:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:36:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:36:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:36:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:36:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:36:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:40:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:40:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:40:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:40:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:40:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:41:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:41:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:41:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:41:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:41:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:42:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:42:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:42:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:42:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:42:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:47:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:47:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:47:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:47:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:47:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:48:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:48:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:48:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:48:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:48:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:52:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:52:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:52:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:52:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:53:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:56:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:56:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:56:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:56:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T04:57:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:01:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:01:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:01:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:01:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:01:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:04:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:04:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:04:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:04:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:04:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:08:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:08:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:08:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:08:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:09:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:13:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:13:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:13:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:13:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:14:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:15:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:15:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:16:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:16:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:16:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:20:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:20:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:20:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:20:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:20:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:22:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:22:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:22:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:22:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:22:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:26:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:26:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:26:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:26:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:26:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:28:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:28:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:28:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:28:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:28:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:29:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:29:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:29:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:29:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:30:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:33:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:33:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:33:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:33:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:33:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:34:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:34:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:34:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:34:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:34:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:36:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:36:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:36:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:36:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:36:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:37:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:37:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:37:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:37:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:37:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:39:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:39:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:39:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:39:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:40:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:44:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:44:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:44:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:44:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:44:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:44:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:44:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:44:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:44:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:45:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:45:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:45:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:45:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:45:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:46:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:46:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:46:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:46:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:46:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:46:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:49:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:49:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:49:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:49:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:49:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:55:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:55:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:55:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:55:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:55:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:57:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:57:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:57:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:57:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:58:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:59:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:59:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:59:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:59:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T05:59:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:00:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:00:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:00:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:00:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:00:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:04:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:04:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:04:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:04:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:05:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:05:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:05:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:05:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:05:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:05:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:09:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:09:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:09:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:09:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:09:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:14:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:14:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:14:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:14:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:14:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:16:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:16:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:16:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:16:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:17:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:17:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:17:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:17:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:17:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:17:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:22:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:22:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:22:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:22:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:22:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:26:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:26:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:26:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:26:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:26:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:29:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:29:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:29:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:29:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:29:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:34:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:34:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:34:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:34:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:35:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:49:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:49:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:49:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:49:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:49:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:50:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:50:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:50:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:50:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:50:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:54:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:54:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:54:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:54:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:54:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:56:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:56:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:56:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:56:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:56:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:58:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:58:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:58:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:58:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T06:59:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:03:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:03:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:03:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:03:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:03:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:07:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:07:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:07:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:07:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:07:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:08:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:08:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:08:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:08:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:08:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:12:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:12:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:12:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:12:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:12:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:17:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:17:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:17:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:17:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:17:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:17:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:17:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:17:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:17:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:18:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:22:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:22:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:22:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:22:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:23:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:26:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:26:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:26:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:26:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:26:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:31:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:31:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:31:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:31:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:32:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:32:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:32:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:32:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:32:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:32:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:35:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:35:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:35:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:35:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:36:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:38:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:38:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:38:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:38:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:38:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:39:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:39:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:39:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:39:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:40:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:44:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:44:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:44:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:44:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:45:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:48:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:48:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:48:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:48:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:49:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:51:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:51:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:51:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:51:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:51:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:55:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:55:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:55:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:55:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:55:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:58:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:58:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:58:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:58:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T07:59:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:04:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:04:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:04:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:04:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:04:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:07:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:07:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:07:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:07:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:07:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:12:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:12:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:12:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:12:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:12:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:14:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:14:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:14:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:14:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:14:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:17:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:17:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:17:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:17:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:17:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:20:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:20:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:20:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:20:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:20:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:23:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:23:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:23:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:23:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:23:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:27:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:27:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:27:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:27:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:28:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:33:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:33:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:33:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:33:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:33:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:38:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:38:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:38:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:38:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:39:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:39:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:39:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:39:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:39:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:40:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:42:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:42:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:42:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:42:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:42:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:47:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:47:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:47:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:47:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:47:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:50:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:50:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:50:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:50:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:51:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:52:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:52:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:52:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:52:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:52:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:55:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:55:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:55:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:55:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T08:55:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:00:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:00:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:00:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:00:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:00:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:04:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:04:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:04:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:04:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:05:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:10:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:10:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:10:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:10:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:11:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:15:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:15:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:15:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:15:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:16:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:21:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:21:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:21:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:21:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:21:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:26:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:26:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:26:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:26:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:26:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:30:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:30:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:30:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:30:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:30:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:31:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:31:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:31:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:31:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:31:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:35:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:35:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:35:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:35:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:36:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:41:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:41:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:41:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:41:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:41:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:44:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:44:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:44:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:44:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:44:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:49:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:49:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:49:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:49:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:50:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:55:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:55:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:55:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:55:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:55:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:59:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:59:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:59:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:59:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T09:59:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:04:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:04:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:04:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:04:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:04:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:08:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:08:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:08:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:08:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:09:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:12:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:12:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:12:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:12:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:12:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:16:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:16:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:16:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:16:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:17:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:20:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:20:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:20:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:20:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:21:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:25:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:25:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:25:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:25:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:25:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:28:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:28:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:28:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:28:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:28:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:30:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:30:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:30:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:30:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:31:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:32:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:32:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:32:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:32:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:33:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:35:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:35:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:35:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:35:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:35:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:37:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:37:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:37:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:37:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:37:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:38:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:38:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:38:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:38:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:39:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:39:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:39:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:39:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:39:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:39:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:40:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:40:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:40:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:40:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:40:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:44:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:44:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:44:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:44:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:45:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:47:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:47:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:47:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:47:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:47:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:50:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:50:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:50:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:50:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:50:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:53:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:53:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:53:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:53:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:53:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:56:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:56:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:56:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:56:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:56:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:57:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:57:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:57:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:57:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T10:58:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:02:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:02:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:02:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:02:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:03:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:08:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:08:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:08:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:08:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:08:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:13:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:13:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:13:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:13:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:14:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:15:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:15:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:15:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:15:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:15:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:16:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:16:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:16:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:16:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:16:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:21:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:21:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:21:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:21:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:21:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:23:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:23:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:23:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:23:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:23:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:26:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:26:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:26:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:26:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:26:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:28:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:28:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:28:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:28:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:29:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:33:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:33:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:33:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:33:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:34:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:34:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:34:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:34:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:34:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:34:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:37:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:37:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:37:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:37:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:38:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:42:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:42:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:42:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:42:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:43:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:47:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:47:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:47:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:47:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:47:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:48:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:48:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:48:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:48:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:48:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:50:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:50:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:50:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:50:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:50:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:54:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:55:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:55:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:55:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:55:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:56:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:56:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:56:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:56:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T11:56:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:01:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:01:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:01:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:01:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:01:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:06:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:06:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:06:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:06:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:06:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:06:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:06:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:06:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:06:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:07:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:09:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:09:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:09:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:09:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:10:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:15:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:15:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:15:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:15:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:15:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:16:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:16:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:16:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:16:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:16:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:19:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:19:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:19:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:19:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:20:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:22:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:22:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:22:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:22:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:22:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:24:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:24:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:24:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:24:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:24:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:29:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:29:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:29:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:29:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:29:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:30:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:30:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:30:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:30:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:30:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:34:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:34:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:34:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:34:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:34:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:34:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:34:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:34:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:34:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:35:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:40:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:40:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:40:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:40:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:40:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:44:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:44:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:44:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:44:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:45:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:46:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:46:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:46:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:46:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:46:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:48:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:48:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:48:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:48:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:48:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:53:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:53:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:53:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:53:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:53:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:57:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:58:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:58:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:58:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T12:58:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:01:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:01:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:01:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:01:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:02:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:05:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:05:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:05:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:05:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:05:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:08:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:08:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:08:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:08:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:09:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:09:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:09:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:09:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:09:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:09:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:10:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:10:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:10:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:10:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:11:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:12:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:12:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:12:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:12:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:13:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:14:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:14:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:14:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:14:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:14:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:16:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:16:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:16:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:16:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:16:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:17:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:17:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:17:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:17:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:18:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:21:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:21:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:21:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:21:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:21:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:22:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:22:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:22:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:22:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:23:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:25:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:25:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:25:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:25:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:25:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:27:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:27:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:27:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:27:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:27:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:31:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:31:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:31:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:31:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:31:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:32:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:32:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:32:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:32:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:33:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:38:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:38:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:38:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:38:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:38:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:42:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:42:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:42:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:42:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:42:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:47:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:47:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:47:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:47:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:48:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:50:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:50:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:50:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:50:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:50:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:51:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:51:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:51:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:51:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:52:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:52:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:52:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:52:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:52:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:52:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:53:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:53:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:53:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:53:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:54:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:55:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:55:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:55:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:55:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:55:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:57:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:58:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:58:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:58:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T13:58:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:01:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:01:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:01:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:01:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:01:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:06:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:06:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:06:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:06:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:07:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:10:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:10:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:10:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:10:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:11:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:11:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:11:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:11:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:11:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:11:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:12:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:12:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:12:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:12:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:12:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:15:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:15:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:15:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:15:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:15:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:17:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:17:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:17:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:17:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:18:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:19:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:19:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:19:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:19:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:19:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:21:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:21:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:21:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:21:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:21:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:22:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:22:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:22:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:22:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:22:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:24:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:24:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:24:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:24:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:24:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:26:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:26:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:26:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:26:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:27:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:28:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:28:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:28:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:28:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:28:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:32:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:32:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:32:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:32:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:32:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:33:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:33:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:33:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:33:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:33:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:35:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:35:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:35:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:35:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:35:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:38:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:38:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:38:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:38:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:38:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:40:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:40:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:40:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:40:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:40:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:42:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:42:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:42:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:42:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:43:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:44:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:44:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:44:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:44:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:44:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:45:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:45:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:45:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:45:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:45:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:49:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:49:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:49:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:49:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:49:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:52:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:52:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:52:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:52:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:52:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:57:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:57:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:57:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:57:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T14:58:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:01:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:01:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:01:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:01:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:01:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:04:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:04:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:04:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:04:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:04:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:05:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:05:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:05:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:05:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:06:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:09:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:09:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:09:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:09:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:09:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:12:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:12:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:12:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:12:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:12:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:14:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:14:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:14:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:14:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:14:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:18:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:18:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:18:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:18:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:19:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:20:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:20:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:20:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:20:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:21:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:23:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:23:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:23:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:23:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:23:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:27:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:27:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:27:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:27:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:28:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:32:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:32:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:32:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:32:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:33:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:38:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:38:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:38:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:38:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:38:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:43:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:43:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:43:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:43:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:43:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:43:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:43:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:43:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:43:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:44:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:44:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:44:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:44:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:44:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:45:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:49:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:49:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:49:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:49:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:49:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:51:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:51:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:51:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:51:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:51:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:54:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:54:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:54:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:54:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:55:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:55:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:55:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:55:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:55:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:55:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:58:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:58:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:58:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:58:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T15:58:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:02:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:02:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:02:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:02:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:02:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:07:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:07:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:07:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:07:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:07:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:08:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:08:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:08:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:08:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:08:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:09:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:09:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:09:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:09:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:09:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:12:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:12:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:12:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:12:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:13:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:16:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:16:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:16:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:16:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:16:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:17:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:17:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:17:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:17:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:18:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:19:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:19:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:19:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:19:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:19:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:22:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:22:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:22:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:22:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:22:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:25:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:25:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:25:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:25:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:25:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:30:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:30:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:30:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:30:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:30:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:32:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:32:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:32:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:32:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:32:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:34:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:34:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:34:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:34:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:34:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:35:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:35:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:35:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:35:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:35:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:36:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:36:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:36:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:36:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:36:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:40:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:40:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:40:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:40:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:41:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:43:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:43:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:43:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:43:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:43:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:45:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:45:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:45:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:45:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:45:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:48:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:48:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:48:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:48:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:48:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:49:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:49:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:49:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:49:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:49:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:49:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:49:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:49:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:49:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:50:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:54:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:54:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:54:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:54:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:55:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:59:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:59:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:59:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:59:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T16:59:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:03:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:03:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:03:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:03:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:03:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:07:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:07:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:07:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:07:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:07:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:08:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:08:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:08:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:08:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:09:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:10:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:10:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:10:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:10:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:10:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:12:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:12:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:12:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:12:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:12:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:15:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:15:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:15:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:15:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:15:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:16:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:16:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:16:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:16:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:16:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:18:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:18:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:18:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:18:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:18:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:22:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:22:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:22:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:22:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:22:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:23:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:23:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:23:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:23:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:23:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:27:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:27:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:27:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:27:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:27:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:32:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:32:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:32:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:32:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:32:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:35:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:35:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:35:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:35:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:36:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:39:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:39:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:39:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:39:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:39:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:40:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:40:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:40:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:40:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:40:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:42:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:42:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:42:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:42:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:42:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:42:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:42:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:42:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:42:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:43:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:46:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:46:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:46:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:46:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:46:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:49:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:49:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:49:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:49:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:49:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:55:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:55:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:55:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:55:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T17:55:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:00:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:00:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:00:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:00:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:00:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:05:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:05:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:05:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:05:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:05:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:07:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:07:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:07:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:07:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:08:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:12:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:12:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:12:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:12:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:12:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:16:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:16:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:16:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:16:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:16:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:17:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:17:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:17:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:17:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:18:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:21:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:21:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:21:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:21:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:22:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:23:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:23:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:23:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:23:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:24:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:28:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:29:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:29:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:29:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:29:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:33:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:33:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:33:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:33:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:33:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:37:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:37:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:37:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:37:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:37:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:39:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:39:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:39:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:39:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:39:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:40:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:40:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:40:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:40:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:41:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:41:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:41:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:41:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:41:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:41:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:43:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:43:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:43:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:43:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:44:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:47:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:47:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:47:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:47:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:47:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:48:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:48:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:48:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:48:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:48:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:50:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:50:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:50:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:50:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:50:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:52:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:52:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:52:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:52:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:52:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:53:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:53:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:53:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:53:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:53:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:53:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:53:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:54:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:54:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:54:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:56:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:56:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:56:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:56:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T18:56:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:00:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:00:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:00:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:00:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:01:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:05:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:05:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:05:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:05:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:05:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:08:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:08:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:08:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:08:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:08:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:11:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:11:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:11:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:11:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:12:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:15:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:15:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:15:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:15:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:15:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:16:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:16:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:16:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:16:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:16:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:20:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:20:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:20:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:20:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:20:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:22:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:22:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:22:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:22:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:22:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:25:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:25:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:25:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:25:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:25:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:26:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:26:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:26:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:26:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:26:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:27:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:27:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:27:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:27:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:28:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:32:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:32:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:32:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:32:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:32:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:35:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:35:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:35:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:35:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:35:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:39:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:39:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:39:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:39:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:40:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:43:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:43:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:44:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:44:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:44:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:48:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:48:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:48:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:48:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:48:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:49:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:49:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:49:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:49:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:50:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:55:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:55:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:55:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:55:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T19:55:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:00:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:00:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:00:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:00:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:00:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:01:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:01:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:01:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:01:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:01:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:02:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:02:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:02:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:02:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:02:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:04:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:04:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:04:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:04:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:04:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:06:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:06:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:06:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:06:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:06:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:11:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:11:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:11:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:11:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:12:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:17:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:17:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:17:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:17:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:17:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:18:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:18:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:18:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:18:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:18:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:20:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:20:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:20:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:20:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:20:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:21:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:21:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:21:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:21:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:21:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:25:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:25:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:25:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:25:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:25:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:26:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:26:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:26:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:26:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:26:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:26:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:26:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:26:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:26:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:27:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:30:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:30:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:30:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:30:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:30:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:34:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:34:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:34:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:34:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:34:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:39:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:39:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:39:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:39:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:39:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:44:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:44:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:44:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:44:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:44:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:48:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:48:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:48:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:48:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:48:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:51:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:51:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:51:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:51:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:52:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:54:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:54:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:54:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:54:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:54:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:55:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:55:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:55:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:55:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T20:55:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:01:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:01:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:01:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:01:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:01:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:02:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:02:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:02:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:02:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:03:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:06:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:06:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:06:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:06:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:06:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:07:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:07:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:07:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:07:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:07:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:10:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:10:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:10:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:10:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:10:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:13:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:13:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:13:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:13:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:13:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:14:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:14:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:14:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:14:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:15:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:17:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:17:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:17:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:17:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:18:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:20:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:20:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:20:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:20:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:20:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:24:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:24:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:24:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:24:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:24:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:28:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:28:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:28:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:28:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:29:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:32:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:32:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:32:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:32:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:32:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:36:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:36:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:36:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:36:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:36:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:41:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:41:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:41:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:41:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:41:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:46:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:46:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:46:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:46:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:46:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:47:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:47:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:47:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:47:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:48:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:49:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:49:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:49:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:49:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:49:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:53:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:53:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:53:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:53:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:53:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:56:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:56:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:56:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:56:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:56:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:58:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:58:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:58:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:58:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T21:58:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:02:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:02:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:02:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:02:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:02:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:07:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:07:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:07:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:07:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:07:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:08:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:08:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:08:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:08:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:09:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:10:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:10:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:10:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:10:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:10:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:11:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:12:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:12:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:12:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:12:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:17:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:17:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:17:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:17:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:17:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:20:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:20:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:20:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:20:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:20:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:22:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:22:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:22:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:22:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:22:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:23:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:23:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:23:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:23:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:23:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:25:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:25:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:25:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:25:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:26:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:29:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:30:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:30:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:30:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:30:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:32:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:32:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:32:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:32:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:32:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:37:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:37:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:37:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:37:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:37:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:40:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:40:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:40:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:40:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:40:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:40:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:40:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:40:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:40:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:41:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:41:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:41:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:41:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:41:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:42:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:42:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:42:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:42:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:42:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:43:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:47:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:47:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:47:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:47:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:47:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:52:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:52:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:52:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:52:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:53:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:57:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:57:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:57:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:57:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T22:57:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:02:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:02:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:02:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:02:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:02:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:02:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:02:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:02:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:02:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:03:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:07:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:07:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:07:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:07:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:07:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:12:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:13:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:13:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:13:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:13:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:14:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:14:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:14:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:14:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:15:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:20:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:20:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:20:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:20:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:20:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:26:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:26:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:26:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:26:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:26:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:30:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:30:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:30:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:30:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:31:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:31:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:31:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:31:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:31:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:32:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:35:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:35:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:35:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:35:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:35:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:39:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:39:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:39:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:39:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:39:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:41:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:41:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:41:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:41:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:41:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:44:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:44:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:44:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:44:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:44:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:45:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:45:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:45:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:45:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:45:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:50:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:50:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:50:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:50:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:50:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:54:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:54:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:54:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:54:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:54:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:59:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:59:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:59:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:59:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-13T23:59:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:03:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:03:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:03:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:03:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:03:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:05:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:05:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:05:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:05:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:05:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:06:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:06:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:06:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:06:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:06:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:10:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:10:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:10:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:10:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:10:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:12:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:12:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:12:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:12:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:12:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:16:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:16:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:16:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:16:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:16:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:17:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:17:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:17:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:17:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:17:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:19:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:19:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:19:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:19:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:19:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:24:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:24:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:24:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:24:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:24:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:28:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:28:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:28:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:28:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:28:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:30:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:30:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:30:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:30:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:30:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:33:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:33:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:33:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:33:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:33:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:35:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:35:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:35:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:35:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:35:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:37:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:37:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:37:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:37:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:38:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:38:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:38:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:38:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:38:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:38:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:43:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:43:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:43:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:43:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:43:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:44:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:44:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:44:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:44:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:44:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:47:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:47:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:47:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:47:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:48:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:52:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:52:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:52:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:52:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:52:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:54:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:54:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:54:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:54:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:55:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:59:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:59:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:59:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T00:59:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:00:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:04:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:04:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:04:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:04:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:05:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:10:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:10:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:10:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:10:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:10:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:13:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:13:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:13:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:13:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:13:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:17:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:17:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:17:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:17:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:17:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:21:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:21:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:21:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:21:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:21:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:26:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:26:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:26:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:26:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:27:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:31:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:31:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:31:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:31:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:32:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:32:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:33:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:33:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:33:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:33:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:38:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:38:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:38:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:38:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:38:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:43:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:43:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:43:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:43:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:43:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:45:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:45:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:45:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:45:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:46:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:49:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:49:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:49:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:49:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:49:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:54:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:54:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:54:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:54:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:54:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:55:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:55:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:55:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:55:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:55:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:58:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:58:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:58:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:58:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T01:59:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:02:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:02:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:02:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:02:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:03:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:06:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:06:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:06:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:06:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:06:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:06:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:06:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:06:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:06:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:07:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:08:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:08:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:08:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:08:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:09:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:13:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:13:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:13:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:13:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:13:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:16:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:17:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:17:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:17:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:17:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:18:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:18:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:18:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:18:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:18:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:20:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:20:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:20:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:20:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:20:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:24:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:24:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:24:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:24:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:24:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:25:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:25:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:25:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:25:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:25:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:28:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:28:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:28:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:28:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:28:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:31:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:31:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:31:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:31:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:31:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:35:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:35:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:35:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:35:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:35:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:36:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:36:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:36:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:36:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:36:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:38:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:38:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:38:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:38:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:39:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:43:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:43:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:43:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:43:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:43:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:45:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:45:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:45:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:45:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:45:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:45:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:45:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:45:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:45:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:46:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:51:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:51:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:51:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:51:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:51:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:55:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:55:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:55:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:55:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:55:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:58:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:58:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:58:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:58:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T02:58:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:02:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:02:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:02:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:02:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:02:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:06:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:06:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:06:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:06:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:07:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:08:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:08:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:08:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:08:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:08:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:13:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:13:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:13:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:13:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:13:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:14:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:14:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:14:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:14:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:14:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:16:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:16:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:16:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:16:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:16:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:21:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:21:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:21:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:21:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:22:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:26:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:26:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:26:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:26:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:26:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:26:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:26:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:26:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:26:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:27:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:28:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:28:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:28:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:28:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:28:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:33:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:33:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:33:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:33:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:33:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:34:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:34:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:34:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:34:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:34:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:35:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:35:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:35:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:35:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:36:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:40:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:40:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:40:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:40:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:40:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:41:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:41:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:41:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:41:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:41:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:45:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:45:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:45:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:45:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:45:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:49:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:49:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:49:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:49:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:49:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:51:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:51:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:51:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:51:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:51:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:54:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:54:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:54:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:54:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T03:54:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:18:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:18:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:18:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:18:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:18:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:22:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:22:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:22:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:22:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:23:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:26:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:26:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:26:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:26:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:26:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:26:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:26:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:26:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:26:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:27:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:29:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:29:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:29:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:29:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:29:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:34:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:35:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:35:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:35:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:35:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:39:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:39:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:39:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:39:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T04:40:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T10:46:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T10:46:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T10:46:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T10:46:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T11:26:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T13:00:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:00:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T13:00:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:00:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:00:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T13:01:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:01:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T13:01:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:01:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:01:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T13:02:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:02:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T13:02:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:02:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T13:02:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T13:49:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T14:21:51Z ERR Unable to establish connection with Cloudflare edge error="TLS handshake with edge error: read tcp 192.168.0.106:59966->198.41.192.47:7844: i/o timeout" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T14:21:51Z ERR Serve tunnel error error="TLS handshake with edge error: read tcp 192.168.0.106:59966->198.41.192.47:7844: i/o timeout" connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T14:21:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.47
+2026-06-14T14:37:30Z ERR Connection terminated error="TLS handshake with edge error: read tcp 192.168.0.106:59966->198.41.192.47:7844: i/o timeout" connIndex=0
+2026-06-14T14:50:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T14:50:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T14:50:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T14:50:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T15:08:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T19:51:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T19:51:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T19:51:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T19:51:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-14T20:41:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:16:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:16:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:16:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:16:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:16:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:18:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:18:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:18:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:18:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:19:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:19:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:19:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:19:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:19:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:20:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:23:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:23:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:23:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:23:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:23:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:27:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:27:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:27:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:27:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:28:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:33:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:33:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:33:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:33:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:33:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:36:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:36:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:36:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:36:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:37:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:42:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:42:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:42:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:42:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:42:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:44:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:44:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:44:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:44:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:44:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:46:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:47:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:47:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:47:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:47:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:49:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:49:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:49:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:49:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:49:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:51:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:51:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:51:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:51:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:51:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:53:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:53:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:53:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:53:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:53:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:56:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:56:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:56:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:56:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T02:56:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:00:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:00:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:00:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:00:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:00:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:02:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:02:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:02:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:02:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:03:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:05:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:05:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:05:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:05:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:05:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:07:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:07:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:07:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:07:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:07:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:10:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:10:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:10:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:10:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:10:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:13:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:13:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:13:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:13:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:13:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:18:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:18:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:18:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:18:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:18:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:20:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:20:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:20:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:20:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:21:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:25:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:25:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:25:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:25:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:26:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:28:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:28:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:28:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:28:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:29:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:33:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:33:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:33:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:33:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:33:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:35:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:35:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:35:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:35:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:36:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:39:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:39:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:39:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:39:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:39:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:42:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:42:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:42:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:42:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:42:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:43:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:43:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:43:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:43:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:43:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:48:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:48:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:48:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:48:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:48:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:49:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:49:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:49:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:49:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:49:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:50:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:50:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:50:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:50:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:51:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:53:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:53:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:53:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:53:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:53:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:56:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:56:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:56:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:56:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T03:57:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:01:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:01:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:01:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:01:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:01:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:02:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:02:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:02:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:02:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:02:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:07:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:07:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:07:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:07:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:07:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:09:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:09:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:09:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:09:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:09:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:15:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:15:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:15:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:15:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:15:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:19:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:19:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:19:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:19:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:20:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:24:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:24:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:24:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:24:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:24:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:30:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:30:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:30:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:30:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:30:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:32:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:32:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:32:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:32:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:33:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:37:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:37:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:37:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:37:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:38:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:41:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:41:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:41:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:41:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:42:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:42:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:42:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:42:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:42:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:42:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:47:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:47:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:47:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:47:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:47:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:48:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:48:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:48:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:48:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:48:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:49:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:49:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:49:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:49:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:49:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:50:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:50:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:50:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:50:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:50:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:52:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:52:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:52:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:52:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:52:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:54:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:55:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:55:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:55:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:55:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:56:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:56:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:56:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:56:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T04:57:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:00:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:00:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:00:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:00:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:01:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:04:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:04:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:04:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:04:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:04:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:06:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:06:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:06:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:06:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:06:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:08:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:08:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:08:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:08:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:08:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:08:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:08:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:08:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:08:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:09:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:12:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:12:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:12:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:12:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:12:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:17:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:17:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:17:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:17:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:17:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:20:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:20:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:20:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:20:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:20:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:21:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:21:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:21:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:21:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:21:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:26:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:26:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:26:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:26:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:26:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:30:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:30:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:30:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:30:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:30:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:35:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:35:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:35:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:35:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:35:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:40:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:40:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:40:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:40:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:40:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:43:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:43:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:43:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:43:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:43:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:46:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:46:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:46:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:46:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:47:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:49:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:49:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:49:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:49:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:49:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:49:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:50:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:50:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:50:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:50:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:54:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:54:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:54:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:54:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:54:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:59:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:59:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:59:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T05:59:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:00:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:00:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:00:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:00:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:00:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:00:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:03:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:03:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:03:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:03:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:03:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:07:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:07:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:07:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:07:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:07:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:10:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:10:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:10:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:10:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:10:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:12:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:12:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:12:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:12:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:12:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:13:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:13:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:13:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:13:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:13:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:16:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:16:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:16:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:16:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:16:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:20:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:20:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:20:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:20:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:20:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:23:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:23:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:23:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:23:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:24:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:27:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:27:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:27:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:27:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:27:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:32:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:32:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:32:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:32:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:32:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:34:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:34:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:34:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:34:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:35:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:39:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:39:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:39:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:39:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:39:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:44:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:44:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:44:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:44:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:45:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:46:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:46:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:46:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:46:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:47:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:50:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:50:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:50:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:50:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:51:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:53:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:53:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:53:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:53:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:53:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:57:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:57:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:57:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:57:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T06:57:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:02:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:02:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:02:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:02:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:02:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:04:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:04:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:04:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:04:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:04:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:06:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:06:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:06:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:06:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:07:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:09:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:09:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:09:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:09:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:09:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:10:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:10:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:10:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:10:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:10:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:10:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:10:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:10:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:10:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:11:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:15:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:15:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:15:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:15:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:16:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:20:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:20:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:20:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:20:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:21:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:23:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:23:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:23:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:23:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:24:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:28:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:28:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:28:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:28:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:28:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:33:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:33:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:33:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:33:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:34:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:38:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:38:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:38:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:38:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:38:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:41:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:41:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:41:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:41:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:42:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:42:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:42:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:42:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:42:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:43:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:43:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:43:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:43:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:43:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:43:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:44:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:44:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:44:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:44:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:44:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:47:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:47:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:47:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.192.7
+2026-06-15T07:47:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.192.7

+ 1 - 1
examples/process_pipeline/script/search_eval/fixed_query_eval/.cloudflared.pid

@@ -1 +1 @@
-30858
+11449

+ 0 - 0
examples/process_pipeline/script/search_eval/fixed_query_eval/.server.out


+ 1 - 1
examples/process_pipeline/script/search_eval/fixed_query_eval/.server.pid

@@ -1 +1 @@
-30849
+11440

+ 57 - 3
examples/process_pipeline/script/search_eval/fixed_query_eval/index.html

@@ -1694,6 +1694,33 @@
     </div>
   </dialog>
 
+  <!-- fixed_query_eval:重新解构 · 编辑工具解构 prompt 弹框 -->
+  <dialog id="toolPromptDialog" style="width: 850px; max-width: 95%; border: 1px solid var(--line); border-radius: 12px; padding: 0; box-shadow: var(--shadow); background: var(--panel);">
+    <div style="display: flex; justify-content: space-between; align-items: center; background: #faf7f1; border-bottom: 1px solid var(--line); padding: 16px 20px;">
+      <h3 style="margin: 0; font-size: 18px; color: var(--ink); font-weight: 800;">🔧 重新解构 · 编辑解构 Prompt</h3>
+      <button onclick="document.getElementById('toolPromptDialog').close()" style="background: none; border: 1px solid var(--line); padding: 5px 14px; border-radius: 8px; cursor: pointer; color: var(--muted); font-weight: 600; font-size: 12px;">关闭</button>
+    </div>
+    <div style="padding: 20px;">
+      <p style="margin: 0 0 12px; font-size: 13px; color: var(--muted);">修改下面的解构 Prompt 后,点「保存修改」将按最新 Prompt 重新解构本帖(生成新版本,旧版本保留)。</p>
+      <div style="margin-bottom: 14px; display: flex; align-items: center; gap: 10px;">
+        <span style="font-size: 13.5px; font-weight: 700; color: var(--ink);">模型:</span>
+        <select id="toolPromptModel" style="padding: 6px 12px; border-radius: 8px; border: 1px solid #d1d5db; outline: none; font-size: 13px; font-weight: 600; background: #fff; cursor: pointer;">
+          <option value="gemini-flash-lite">gemini3.1-flash-lite</option>
+          <option value="gemini-3.5-flash">gemini3.5</option>
+          <option value="sonnet">claude4.6</option>
+        </select>
+      </div>
+      <div style="position: relative; margin-bottom: 20px;">
+        <textarea id="toolPromptTextarea" style="width: 100%; height: 480px; font-family: ui-monospace, Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13.5px; line-height: 1.55; padding: 14px; border: 1px solid #d1d5db; border-radius: 8px; box-sizing: border-box; outline: none; background: #fafaf9; color: #1f2937; resize: vertical; border-left: 4px solid var(--cyan); box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);"></textarea>
+      </div>
+      <div style="display: flex; justify-content: flex-end; gap: 12px; align-items: center; border-top: 1px solid var(--line); padding-top: 16px;">
+        <span id="toolPromptStatus" style="font-size: 13.5px; font-weight: 700; margin-right: auto;"></span>
+        <button onclick="document.getElementById('toolPromptDialog').close()" class="btn" style="background: #f3f4f6; height: 38px; padding: 0 18px; border-radius: 8px; font-weight: 600;">取消</button>
+        <button id="toolPromptSaveBtn" onclick="confirmReExtractTools()" class="btn" style="background: var(--mint); color: #fff; border-color: var(--mint); font-weight: bold; height: 38px; padding: 0 20px; border-radius: 8px; box-shadow: var(--shadow);">💾 保存修改</button>
+      </div>
+    </div>
+  </dialog>
+
   <script>
     let DATA = { queries: [], actions: [], types: [], matrix: [] }, st = { form: 'A', lens: '工序', tools: [], tier: 0, qi: 0, fi: 0, channel: "all", matrixView: 'full' }, VIEW = [];
     let currentProcTask = null;
@@ -3045,14 +3072,41 @@
           _pollToolsThenLoad(it, pane);
         });
     }
+    // 「重新解构」→ 弹框,载入当前解构 prompt 供编辑(确认后才真正重新解构)
     function reExtractTools() {
       const it = _curDetailItem(); if (!it) return;
-      if (!confirm('重新解构会生成一个新版本(旧版本保留,可在版本下拉里切回),确定?')) return;
+      const dlg = document.getElementById('toolPromptDialog');
+      const ta = document.getElementById('toolPromptTextarea');
+      const status = document.getElementById('toolPromptStatus');
+      const saveBtn = document.getElementById('toolPromptSaveBtn');
+      ta.value = '';
+      status.textContent = '加载中…'; status.style.color = 'var(--muted)';
+      saveBtn.disabled = true;
+      if (typeof dlg.showModal === 'function') dlg.showModal(); else dlg.setAttribute('open', '');
+      fetch('/api/tool_prompt')
+        .then(r => r.json())
+        .then(d => {
+          if (d.content === undefined) throw new Error(d.error || '无内容');
+          ta.value = d.content;
+          status.textContent = ''; saveBtn.disabled = false;
+        })
+        .catch(e => { status.textContent = '加载失败:' + e.message; status.style.color = '#c0392b'; });
+    }
+    // 弹框「保存修改」→ 按编辑后的 prompt 重新解构本帖
+    function confirmReExtractTools() {
+      const it = _curDetailItem(); if (!it) return;
+      const ta = document.getElementById('toolPromptTextarea');
+      const prompt = ta.value;
+      if (!prompt.trim()) { alert('Prompt 不能为空'); return; }
+      const modelSel = document.getElementById('toolPromptModel');
+      const model = modelSel.value;
+      const modelLabel = modelSel.options[modelSel.selectedIndex].text;
+      document.getElementById('toolPromptDialog').close();
       toolVersion = null;   // 解构后看最新版本
       const pane = document.getElementById('modalContentTools');
-      pane.innerHTML = `<div style="padding:48px;text-align:center;color:var(--muted)">⏳ 重新解构中…(${TOOL_MODEL_LABEL})</div>`;
+      pane.innerHTML = `<div style="padding:48px;text-align:center;color:var(--muted)">⏳ 重新解构中…(${esc(modelLabel)})</div>`;
       fetch('/api/extract_tools', { method: 'POST', headers: { 'Content-Type': 'application/json' },
-        body: JSON.stringify({ q: it.run, case_ids: [it.case_id], force: true }) })
+        body: JSON.stringify({ q: it.run, case_ids: [it.case_id], force: true, prompt, model }) })
         .then(r => r.json()).then(() => _pollToolsThenLoad(it, pane));
     }
     function _toolField(label, val, color) {

+ 23 - 23
examples/process_pipeline/script/search_eval/fixed_query_eval/prompts/tool_extract_system.md

@@ -1,7 +1,7 @@
 你是一个内容知识提取助手,将网络帖子(公众号文章、视频号图文、短视频等)中的工具信息提炼为结构化知识条目。
 
-提取规则:
 
+提取规则:
 - **图片 / 视频帧里的信息必须逐字提取成文字**——教程的真正干货(提示词原文、参数数值、按钮/菜单名、步骤顺序、操作前后的对比图说明)几乎都在配图里,不要只看正文。
 - **保留具体细节,不要抽象化**:看到提示词就抄原文,看到参数就记数值,看到操作就写清是哪个按钮/功能、第几步。
 - 去除废话:广告语、情绪渲染、关注引导、重复内容、无实质信息的过渡句。
@@ -13,28 +13,28 @@
 请识别内容中提到的所有工具。**只输出一个 JSON 对象**,格式如下(每个工具一个对象,放进 tools 数组):
 
 {
-"tools": [
-{
-"工具名称": string,
-"实质作用域": string, // 工具适合处理的内容主体,如「人物」「产品」「风景」,如果作者提及,从提及中提取,未直接提及从案例、prompt中总结;若未提及,填「实拍图片」或「信息图片」「视频」等泛称,
-"形式作用域": string | null, // 工具擅长的风格或表现形式,如「实拍氛围感」「写实」「动漫」;如果作者提及,从提及中提取,未直接提及从案例、prompt中总结;若未提及填 null
-"创作层级": "制作层" | "创作层", // 制作层 = 生产内容(出图/出视频/剪辑/配音);创作层 = 辅助方向(选题/灵感/脚本)
-"来源链接": string | null,
-"输入": string | null, // 该工具需要喂入什么素材类型
-"输出": string | null, // 该工具产出什么,如「底图」「渲染图」
-"用法": string[] | null, // 工具的用法,如参数如何填写,prompt 如何写,
-"案例": [ // 帖子里展示的具体复现实例(输入→输出的完整链路)数组。注意很多案例都在图片里,需要仔细甄别;无则 null
-{
-"输入": string, // 具体输入了什么,特别是用了什么提示词
-"输出": string, // 最终产出了什么图 / 视频 / 文件
-"效果": string | null // 达成的具体效果、或操作前后的对比差异;无则 null
-}
-],
-"缺点": string[] | null, // 帖子中提到的工具局限、不足或注意事项,每条为一个独立缺点
-"最新更新时间": string | null
-}
-]
+  "tools": [
+    {
+      "工具名称": string,
+      "实质作用域": string[],      // 工具适合处理的图片内容元素,可多个。即「这类图里有什么」,如「人物」「风景」「产品」「信息图表」「海洋」「建筑」「UI截图」「排版图」等;优先从作者提及或案例中提取,未提及则从使用场景归纳,无法归纳时填 ["实拍图片"] 或 ["图形图片"] 等泛称
+      "形式作用域": string[] | null, // 工具擅长的风格或表现形式,可多个,如「实拍氛围感」「写实」「动漫」「扁平插画」「3D渲染」等;优先从作者提及或案例中提取,未提及则从使用场景归纳,无法归纳时填 null
+      "创作层级": "制作层" | "创作层",  // 制作层 = 生产内容(出图/出视频/剪辑/配音);创作层 = 辅助方向(选题/灵感/脚本)
+      "来源链接": string | null,
+      "输入": string | null,        // 该工具需要喂入什么素材,要求具体可执行:数量、内容主体、拍摄/绘制要求、格式限制等,让读者看完知道该去准备什么;帖子未提及的维度不填,输出应该是短语,如果有多个,用、分割,比如:人物三视图、提示词
+      "输出": string | null,        // 该工具产出什么,如「底图」「渲染图」
+    "用法": string[] | null,       // 工具的用法,如参数如何填写,prompt 如何写,
+      "案例": [                      // 帖子里展示的具体复现实例(输入→输出的完整链路)数组。注意很多案例都在图片里,需要仔细甄别;无则 null
+        {
+          "输入": string,           // 具体输入了什么,特别是用了什么提示词
+          "输出": string,           // 最终产出了什么图 / 视频 / 文件
+          "效果": string | null     // 达成的具体效果、或操作前后的对比差异;无则 null
+        }
+      ],
+      "缺点": string[] | null,       // 帖子中提到的工具局限、不足或注意事项,每条为一个独立缺点
+      "最新更新时间": string | null
+    }
+  ]
 }
 
 若识别到多个工具,tools 数组中包含多个对象。若未识别到任何工具,输出 {"tools": []}。
-不要输出 JSON 以外的任何内容(不要 markdown 代码块标记、不要解释)。
+不要输出 JSON 以外的任何内容(不要 markdown 代码块标记、不要解释)。

+ 8 - 4
examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/_extract.log

@@ -1,5 +1,9 @@
-🔧 工具解构 1 帖 · 模型 google/gemini-3.1-flash-lite · 版本 v_06111055
-INFO:httpx:HTTP Request: POST https://openrouter.ai/api/v1/chat/completions "HTTP/1.1 200 OK"
-   ✅ xhs_69ee8e140000000220033107 → 3 个工具 · $0.0029 · 版本 v_06111055 → xhs_69ee8e140000000220033107.json
+🔧 工具解构 1 帖 · 模型 claude-sonnet-4-6 · 版本 v_06121527
+INFO:agent.llm.openrouter:[OpenRouter/Anthropic] payload contains 6 image block(s)
+[OpenRouter/Anthropic] payload contains 6 image block(s)
+INFO:httpx:HTTP Request: POST https://openrouter.ai/api/v1/messages "HTTP/1.1 200 OK"
+   [ToolExtract[gzh_3c1c86d58786df826985b34cd6cda29d]] Auto-fixed JSON: fixed_by_json_repair
+   ✅ gzh_3c1c86d58786df826985b34cd6cda29d → 1 个工具 · $0.1190 · 版本 v_06121527 → gzh_3c1c86d58786df826985b34cd6cda29d.json
+⚠️ fqe_tools 写库失败(不影响本地 json):(1241, 'Operand should contain 1 column(s)')
 
-📊 完成 1 帖 · 总成本 $0.0029
+📊 完成 1 帖 · 总成本 $0.1190

+ 75 - 97
examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/gzh_3c1c86d58786df826985b34cd6cda29d.json

@@ -3,144 +3,122 @@
   "platform": "gzh",
   "title": "纯干货!GPT-Image-2 实测 30+场景,附提示词(免费领取)",
   "url": "https://mp.weixin.qq.com/s?__biz=Mzk5MDUzOTIzNQ==&idx=1&mid=2247484814&sn=bdb0f2ae917946ece6baf9b60b29ddda",
-  "model": "google/gemini-3.1-flash-lite",
-  "version": "v_06111130",
+  "model": "claude-sonnet-4-6",
+  "version": "v_06121527",
   "tool_count": 1,
   "tools": [
     {
       "工具名称": "GPT-Image-2",
-      "实质作用域": "人物、产品、风景、界面、海报、插画",
-      "形式作用域": "Pixar 3D、涂鸦、手绘、极简拼贴、国潮、暗黑、长卷山水、高保真UI",
+      "实质作用域": [
+        "人物",
+        "产品",
+        "风景",
+        "UI截图",
+        "海报",
+        "插画",
+        "信息图表",
+        "建筑"
+      ],
+      "形式作用域": [
+        "3D渲染",
+        "写实",
+        "动漫",
+        "扁平插画",
+        "水彩",
+        "涂鸦",
+        "纸雕",
+        "国潮",
+        "暗黑风格",
+        "中国传统画"
+      ],
       "创作层级": "制作层",
-      "来源链接": null,
-      "输入": "文字描述(提示词)、参考图片",
-      "输出": "图像",
+      "来源链接": "https://mp.weixin.qq.com/s?__biz=Mzk5MDUzOTIzNQ==&idx=1&mid=2247484814&sn=bdb0f2ae917946ece6baf9b60b29ddda",
+      "输入": "参考照片、提示词文字、产品图、职位JD文字",
+      "输出": "生成图、海报、详情页、UI原型图、插画、信息图",
       "用法": [
-        "Pixar 3D穿屏:将人物角色放置在3D透明玻璃手机画面中,调整姿势使其突破屏幕,采用戏剧化3D透视,添加数字粒子与玻璃裂纹效果,背景采用温暖米色、柔粉色与梦幻紫色渐变,8K超高清品质,比例9:16。",
-        "拯救废片:描述为搞笑涂鸦画,廉价马克笔或蜡笔草图风格,杂乱、粗糙、孩子气,透视差、比例别扭,添加简单卡通背景,颜色不均。",
-        "日常氛围图:添加手绘白色涂鸦线条、手写风中文标注、白色描边气泡文字、箭头、圈圈、波浪线、爱心、星星等装饰。",
-        "随便涂鸦:使用最大色块,涂鸦感重,白底,老式电脑画图程序风格,低清、一像素一像素蹭出来的感觉。",
-        "旅游照变冰箱贴:上下分区,上半部分为极简纯色背景,下半部分为原图。上半部分将主体转化为简约卡通冰箱贴图标,有轻微立体感和投影,白色描边,添加手写标签文字“enjoy”。",
-        "写情书:精美信纸和手写字体风格。",
-        "Sam Altman 微信朋友圈:生成特定场景的社交媒体截图,比例16:9。",
-        "360度登月全景图:生成360度全景图像。",
-        "海贼王 3D 纸雕:平视视角,高饱和度3D多层纸雕场景,实体纸张分层结构,边缘硬切割,可见厚纸横截面。",
-        "田园水彩旅行攻略:分点式构图,米白色或原木浆草纸纹理,水彩轻薄透气感,钢笔淡彩技法,比例3:4。",
-        "暗黑风格插画:游戏原画级别完成度。",
-        "长卷山水画:横版中国传统长卷,笔墨晕染和留白。",
-        "香水详情页:生成电商中文详情页,比例9:16。",
-        "护肤品电商首图:高端护肤品海报,包含产品名、卖点、价格、赠品列表等信息,层级分明。",
-        "电商 APP 首页:高保真移动端界面,包含状态栏、搜索框、分类标签、轮播Banner、10宫格功能区、限时秒杀模块。",
-        "音乐 App 播放页:高保真移动端界面,深色模式,包含专辑封面、歌曲信息、进度条、控制按钮、歌词区域。",
-        "新品上市海报:新中式、轻奢、克制风格,融合宣纸肌理、留白、淡雅山水,包含产品信息、活动文案,比例3:4。",
-        "专辑概念海报:K-POP女团风格,黑色系造型,侧逆光加柔焦,冷灰蓝调。",
-        "品牌入驻海报:指定品牌与地点宣传,比例3:4。",
-        "招聘海报:根据职位JD生成。"
+        "直接输入提示词文字生成图像",
+        "上传参考照片+提示词进行图像风格转换或二次创作",
+        "指定画面比例如9:16、3:4、16:9、竖版等",
+        "在提示词中详细描述画面结构、色彩、风格、文字内容、排版层级",
+        "可生成含精确文字的海报、详情页、UI界面"
       ],
       "案例": [
         {
-          "输入": "将人物角色放置在一个显示小红书帖文的3D透明玻璃手机画面中...",
-          "输出": "Pixar 3D穿屏效果图",
-          "效果": "强烈的深度感与沉浸感,数字破屏视觉特效"
+          "输入": "将人物角色放置在一个显示小红书帖文的3D透明玻璃手机画面中,并重新调整她的身体姿势,使她看起来像是正从屏幕中突破、进入现实世界。其中一只脚必须强烈地朝向观者延伸,采用戏剧化的3D透视效果,创造出强烈的深度感与沉浸感。整体姿势需要具有动态感、自然且符合人体结构,就像是在从屏幕中跨步而出的瞬间。手机屏幕边缘出现真实细腻的玻璃裂纹与数字粒子效果,大量发光的像素碎片与光粒向外扩散,形成富有未来感的\"数字破屏\"视觉特效。所有碎片与光效自然围绕人物运动方向展开,具有电影级空间层次感。整体画面采用温暖米色、柔粉色与梦幻紫色渐变背景,结合金粉色夕阳光斑与电影级柔光渲染。Pixar风格与半现实主义融合,超精细材质,柔和景深,电影感光影,8K超高清品质。将画面优化为竖版【9:16】比例(1080×1440),适用于社交媒体展示。",
+          "输出": "Pixar 3D穿屏效果竖版图,人物从小红书手机屏幕中破屏而出,周围有玻璃裂纹和发光像素碎片",
+          "效果": "电影级3D破屏视觉特效,温暖米色柔粉紫色渐变背景,8K超高清品质"
         },
         {
-          "输入": "把这张照片变成一个搞笑的涂鸦画...",
-          "输出": "搞笑涂鸦风格图",
-          "效果": "杂乱、粗糙、孩子气,像表情包"
+          "输入": "把这张照片变成一个搞笑的涂鸦画。让它看起来像:用廉价马克笔或蜡笔快速画出的草图,杂乱、粗糙、孩子气的风格,透视差、比例别扭,面部特征略显夸张。添加:简单的卡通背景(如建筑、树木、街道),随意的潦草线条和细节,颜色不均、笔触可见。风格:看起来像懒人画,不精致,幽默又有点傻傻的,像表情包,休闲,网络风格。不要:画得太写实。(附上真实照片)",
+          "输出": "马克笔/蜡笔风格涂鸦画,人物在街道背景中,有卡通建筑、树木、小狗等元素",
+          "效果": "将真实照片转化为粗糙孩子气的涂鸦风格,幽默搞笑"
         },
         {
-          "输入": "给我在图片上添加手绘白色涂鸦线条、手写风中文标注...",
-          "输出": "带有涂鸦装饰的日常氛围图",
-          "效果": "小红书风、ins风、温馨日常感"
+          "输入": "给我在图片上添加手绘白色涂鸦线条、手写风中文标注。在主体旁边添加白色描边气泡文字,线条可爱随意,像手绘笔记一样。加入箭头、圈圈、波浪线、爱心、星星等涂鸦装饰。整体是小红书风、ins风、温馨日常感,轻松、治愈、有生活气息。(附上花朵照片)",
+          "输出": "在花朵实拍照片上叠加白色手绘涂鸦线条、气泡文字(今日份春天、白白软软、开啦、风也很温柔、治愈一下)、爱心星星等装饰",
+          "效果": "实拍照片变为小红书/ins风手绘笔记感日常氛围图"
         },
         {
-          "输入": "重画附图,使用最大的色块、涂鸦感更重...",
-          "输出": "低清、迷惑风格的涂鸦图",
-          "效果": "像老式电脑画图程序画出来的"
+          "输入": "重画附图,使用最大的色块、涂鸦感更重,尽可能弄得惨兮兮的。用白底,做得像是在老式电脑画图程序里拿鼠标画出来的。要隐约有点像,但又不太像,像是对上了又哪哪都不对,别扭得让人迷惑,呈现那种低清、一像素一像素蹭出来的感觉,突出它到底有多离谱地烂。算了,随便吧,你想怎么画就怎么画。(附上照片)",
+          "输出": "白底老式电脑画图程序风格的低清涂鸦,色块大、线条粗糙、比例别扭",
+          "效果": "极度简陋的像素涂鸦风格,幽默离谱"
         },
         {
-          "输入": "根据真实照片,生成一张上下分区的旅行摄影海报...",
-          "输出": "冰箱贴风格旅行海报",
-          "效果": "极简拼贴风格,旅行纪念品感"
+          "输入": "根据我提供的真实照片,生成一张上下分区的旅行摄影海报,整体参考\"小红书城市打卡/冰箱贴/极简拼贴\"风格。画面为竖版构图,比例3:4,整张图分为上下两个部分。上半部分占画面约50%,为极简纯色背景;下半部分占画面约50%,可剪裁,但保留原图,不修改。从下半部分真实照片中提取最有识别度的主体元素,将该元素转化为一个简约可制作的\"冰箱贴式人物图标\",卡通风格,保留人物的核心轮廓和五官标志性特征,造型简洁、干净、像旅行纪念品冰箱贴,有轻微立体感和投影,边缘清晰,白色或浅色描边,细节适度简化,图标位于上半部分居中偏上位置,图标尺寸较小且精致,周围保留大量留白。上半部分背景颜色从照片中提取一个最主要、最有记忆点的颜色,背景为纯色,颜色要饱和、干净、有旅行明信片感。在冰箱贴图标下方添加一行优雅的手写标签文字:\"enjoy\"。(附上母子合影照片)",
+          "输出": "上下分区海报:上半部分蓝色纯色背景+母子人物冰箱贴卡通图标+enjoy手写文字,下半部分保留原始母子合影照片",
+          "效果": "旅游照变冰箱贴风格极简海报,上方卡通图标与下方真实照片形成对比"
         },
         {
-          "输入": "帮我写一封情书,用精美的信纸和手写字体的风格呈现",
-          "输出": "情书图片",
-          "效果": "精美信纸和手写字体"
+          "输入": "帮我写一封情书,用精美的信纸和手写字体的风格呈现",
+          "输出": "精美信纸风格情书图片,带花卉装饰边框、手写字体、蜡封印章,标题\"给最爱的你\"",
+          "效果": "纯文字指令生成精美手写情书图片"
         },
         {
-          "输入": "生成 OpenAI CEO Sam Altman 在微信朋友圈用中文介绍宣传 ChatGPT Images 2.0...",
-          "输出": "微信朋友圈截图",
-          "效果": "模拟真实社交媒体界面"
+          "输入": "生成 OpenAI CEO Sam Altman 在微信朋友圈用中文介绍宣传 ChatGPT Images 2.0,底下马斯克评论发「???」,Demis Hassabis 评论称:「我觉得不如 Nano Banana Pro」,图片比例为 16:9。",
+          "输出": "模拟微信朋友圈截图,Sam Altman发帖宣传ChatGPT Images 2.0,马斯克和Demis Hassabis评论",
+          "效果": "高度仿真的微信朋友圈界面截图"
         },
         {
-          "输入": "生成一张人类登月的 360 度全景图",
-          "输出": "360度全景图",
+          "输入": "生成一张人类登月的360度全景图",
+          "输出": "人类登月360度全景图",
           "效果": null
         },
         {
-          "输入": "平视视角,正面直视一个高饱和度 3D 多层纸雕场景...",
-          "输出": "3D纸雕风格海贼王场景图",
-          "效果": "实体纸张分层结构,边缘硬切割"
-        },
-        {
-          "输入": "田园水彩速写/自然风物图鉴风格的竖版信息图...",
-          "输出": "水彩风格旅行攻略图",
-          "效果": "水彩特有的轻薄透气感,钢笔淡彩技法"
+          "输入": "平视视角,正面直视一个高饱和度3D多层纸雕场景。整体为灰蓝、奶油白、深森林绿,点缀琥珀色暖光。所有元素必须是实体纸张分层结构,边缘为硬切割效果,并清晰可见厚纸横截面。极致丰富构图,一个高能量的海盗群像场景,发生在混乱的海上冒险中。多个风格化海盗角色以夸张动作呈现,中层核心是一位戴草帽的年轻船长向前冲刺,周围是姿态鲜明的船员。分层的船只、翻涌海浪和旋转洋流贯穿前中后景,多艘船在不同空间层中碰撞倾斜,船帆破损、旗帜飞扬。背景层中出现体型巨大的对立角色剪影,增强压迫感和空间层级。",
+          "输出": "海贼王主题3D多层纸雕场景图,灰蓝奶油白深绿色调,戴草帽船长为核心的海盗群像",
+          "效果": "3D纸雕风格,层次分明,电影级空间感"
         },
         {
-          "输入": "生成一张暗黑风格的金克斯(Jinx)插画...",
-          "输出": "暗黑风格插画",
-          "效果": "游戏原画级别完成度"
+          "输入": "【24号:早教场中路看花--文化巷/云南大学--翠湖公园--昆明老街--南强夜市 25号:上午打车去捞鱼河湿地公园(包含有风小院花田、古桩月季园)--斗南花市 26号:盘龙江看花--篆新农贸市场--然后12点之前出发去机场】就以上的文字不要增减,生成一张田园水彩速写/自然风物图鉴风格的竖版信息图,比例为3:4,4k。视觉风格规范:采用分点式构图,有框线,序号;背景使用干净的米白色或原木浆草纸纹理;色彩采用自然原生色系,如草木绿、番茄红、泥土棕、暖阳黄;上色需呈现水彩特有的轻薄透气感、水渍边缘以及随性的色彩飞溅;绘画风格采用钢笔淡彩技法,使用松弛、利落、带有速写感的不规则深色线条勾勒轮廓。",
+          "输出": "昆明旅游攻略田园水彩速写风格竖版信息图,3:4比例,4K,含分点式构图、框线、序号",
+          "效果": "纯文字行程转化为精美水彩手绘风格旅游攻略信息图"
         },
         {
-          "输入": "生成一张横版中国传统长卷山水画...",
-          "输出": "长卷山水画",
-          "效果": "笔墨晕染和留白"
-        },
-        {
-          "输入": "生成一张橙色调平身的香水产品图...",
-          "输出": "香水产品图",
+          "输入": "生成一张暗黑风格的金克斯(Jinx)插画,要求画面呼吸感和节奏顺畅,细节精致,具有游戏原画级别的完成度。",
+          "输出": "暗黑风格金克斯游戏原画级插画",
           "效果": null
         },
         {
-          "输入": "高端护肤品电商首图海报...",
-          "输出": "护肤品电商海报",
-          "效果": "干净、轻奢、科学护肤感"
-        },
-        {
-          "输入": "生成一张高保真移动端电商 App 首页界面截图...",
-          "输出": "电商App首页截图",
-          "效果": "极其真实,具有完整的UI逻辑"
-        },
-        {
-          "输入": "生成一张高保真中文音乐 App 播放页界面截图...",
-          "输出": "音乐App播放页截图",
-          "效果": "视觉精致,风格接近现代流媒体播放器"
-        },
-        {
-          "输入": "设计一张 3:4 竖版国潮茶饮新品上市海报...",
-          "输出": "国潮茶饮海报",
-          "效果": "新中式、轻奢、克制"
+          "输入": "生成一张横版中国传统长卷山水画,笔墨晕染和留白。",
+          "输出": "横版中国传统长卷山水画",
+          "效果": null
         },
         {
-          "输入": "生成一张 K-POP 女团第三张迷你专辑的概念海报...",
-          "输出": "K-POP专辑海报",
-          "效果": "冷灰蓝调,质感精致"
+          "输入": "生成一张橙色调平身的香水产品图,香水品牌为Orange",
+          "输出": "橙色调香水产品图",
+          "效果": null
         },
         {
-          "输入": "生成【茶颜悦色】2026.5.21入驻深圳万象天地的宣传海报...",
-          "输出": "品牌入驻海报",
+          "输入": "(有香水垫图)给这个香水产品生成电商中文详情页,9:16,4k。",
+          "输出": "香水电商中文详情页,9:16比例,4K",
           "效果": null
         },
         {
-          "输入": "请根据以上职位描述生成招聘海报",
-          "输出": "招聘海报",
-          "效果": null
+          "输入": "高端护肤品电商首图海报,产品名为澄光维稳精华。整体风格干净、轻奢、科学护肤感强,画面中心是一瓶半透明磨砂玻璃精华液,带淡金色液体和水珠反光,背景为奶白到暖灰渐变,局部有液体流动与微观分子结构装饰。要求同时具备品牌感和卖货感。海报必须包含以下文案:澄光 维稳精华、修护屏障 舒缓泛红 细腻透亮、第2代升级配方、核心成分 神经酰胺 泛醇B5 积雪草提取物 微囊脂质体、适合人群 敏感肌 熬夜肌 换季不稳定肌、限时到手价 229元 买1送3 赠洁面15ml 赠精华5ml 赠面霜10g、左下角小字:实际效果因人而异,请坚持使用。要求重点测试商品卖点、价格、赠品列表、产品名与功能短句的层级。整体要高级,不能土,不要过度直播间风格。",
+          "输出": "澄光维稳精华高端护肤品电商首图海报,含完整文案层级",
+          "效果": "轻奢科学护肤感,品牌感与卖货感兼备"
         }
-      ],
-      "缺点": null,
-      "最新更新时间": "2026-05-19"
+      ]
     }
   ]
 }

+ 9 - 16
examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0000/tools/xhs_69ee8e140000000220033107.json

@@ -4,7 +4,7 @@
   "title": "如何让你的GPT-Image-2更落地!",
   "url": "https://www.xiaohongshu.com/explore/69ee8e140000000220033107",
   "model": "google/gemini-3.1-flash-lite",
-  "version": "v_06111134",
+  "version": "v_06121509",
   "tool_count": 3,
   "tools": [
     {
@@ -16,14 +16,14 @@
       "输入": "角色参考图、提示词",
       "输出": "底图",
       "用法": [
-        "使用提示词生成底图,强调背景简约",
+        "使用提示词生成底图,强调背景简约",
         "提示词示例:[(电影级梦幻特写: 1.5)], [(头部大幅后仰的仰视姿态: 1.4)], (眼神迷离凝视镜头: 1.3), [以参考图这个角色为主角: 1.2]。画面锁定锁及以上,干净简单的深色背景。关键光影为:强烈的背光勾勒出头发闪光的轮廓,面部带有光斑和强烈的明暗对比,散布柔和的透镜耀斑和圆形虚化光斑。超写实细节,神圣且迷幻的氛围。"
       ],
       "案例": [
         {
           "输入": "角色参考图 + 提示词",
-          "输出": "一张近景镜头下的角色肖像特写底图",
-          "效果": "具备优秀的审美和氛围感,但存在画面油腻、光源杂乱、奇怪颗粒等问题"
+          "输出": "一张带有氛围感的角色肖像底图",
+          "效果": "审美理解优秀,大方向发散好,但画面油腻、光源杂乱、有奇怪颗粒"
         }
       ],
       "缺点": [
@@ -43,24 +43,17 @@
       "输出": "渲染图",
       "用法": [
         "调氛围:垫入光影参考,微调提示词,重新渲染灯光氛围",
-        "重新渲染:先转线稿图,PS生成色彩图,再让Nano重新渲染氛围",
-        "优化:线稿图生成后需去掉影响质量的细碎线条",
-        "还原细节:最后渲染时垫入原始角色图,以还原细节和材质"
+        "重新渲染:结合PS生成的色彩图和线稿图进行渲染,最后可垫入原始角色图以还原细节"
       ],
       "案例": [
         {
-          "输入": "图1(底图)+ 图2(光影参考)",
+          "输入": "GPT生成的底图 + 光影参考图",
           "输出": "调整光影氛围后的角色图",
-          "效果": "氛围色改为粉色,脸上增加爱心光斑,角色边缘有强烈轮廓光,保持了原图动作和造型"
-        },
-        {
-          "输入": "线稿图 + 色彩图",
-          "输出": "最终渲染图",
-          "效果": "画面结构稳定、一致性强,解决了油腻和杂乱问题"
+          "效果": "结构稳定、一致性强,不会出现莫名其妙的内容"
         }
       ],
       "缺点": [
-        "氛围感不如GPT出众"
+        "氛围感不如GPT"
       ],
       "最新更新时间": null
     },
@@ -73,7 +66,7 @@
       "输入": "线稿图",
       "输出": "色彩图",
       "用法": [
-        "用于生成色彩图,作为Nano重新渲染的中间步骤"
+        "用于生成色彩图,作为Nano渲染的辅助素材"
       ],
       "案例": null,
       "缺点": null,

+ 9 - 0
examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0003/tools/_extract.log

@@ -0,0 +1,9 @@
+🔧 工具解构 1 帖 · 模型 claude-sonnet-4-6 · 版本 v_06121531
+INFO:agent.llm.openrouter:[OpenRouter/Anthropic] payload contains 6 image block(s)
+[OpenRouter/Anthropic] payload contains 6 image block(s)
+INFO:httpx:HTTP Request: POST https://openrouter.ai/api/v1/messages "HTTP/1.1 200 OK"
+   [ToolExtract[xhs_6954f03f000000001e034538]] Auto-fixed JSON: fixed_by_json_repair
+   ✅ xhs_6954f03f000000001e034538 → 1 个工具 · $0.0739 · 版本 v_06121531 → xhs_6954f03f000000001e034538.json
+⚠️ fqe_tools 写库失败(不影响本地 json):(1241, 'Operand should contain 1 column(s)')
+
+📊 完成 1 帖 · 总成本 $0.0739

+ 43 - 30
examples/process_pipeline/script/search_eval/fixed_query_eval/runs_full/q0003/tools/xhs_6954f03f000000001e034538.json

@@ -3,55 +3,68 @@
   "platform": "xhs",
   "title": "Nano Banana Pro绘图 第五弹 中药知识插图",
   "url": "https://www.xiaohongshu.com/explore/6954f03f000000001e034538",
-  "model": "google/gemini-3.1-flash-lite",
-  "version": "v_06111142",
+  "model": "claude-sonnet-4-6",
+  "version": "v_06121531",
   "tool_count": 1,
   "tools": [
     {
       "工具名称": "Nano Banana Pro",
-      "实质作用域": "中药材知识插图",
-      "形式作用域": "百科海报式设计手稿",
+      "实质作用域": [
+        "中药材",
+        "植物",
+        "信息图表",
+        "科普海报"
+      ],
+      "形式作用域": [
+        "2D插画",
+        "手绘线稿+柔和上色",
+        "本草笔记风",
+        "设计手稿风",
+        "百科海报式"
+      ],
       "创作层级": "制作层",
-      "来源链接": null,
-      "输入": "中药材名称",
-      "输出": "单味药材全景分解图(4K高清,纵向构图)",
+      "来源链接": "https://www.xiaohongshu.com/explore/6954f03f000000001e034538",
+      "输入": "中药材名称、参考图(药材名称样式参照图)、详细提示词",
+      "输出": "单页全景科普海报(4K高清,纵向构图),包含药材本体插画、原植物形态、性味归经标签、功效图标、现代剂型、材质细节放大图",
       "用法": [
-        "设定角色为顶尖本草插画概念设计师",
-        "构图规范:中央放置药材本体,四周环绕原植物形态、关键部位、断面纹理、功效图标、现代剂型及生活化场景",
-        "连接方式:使用细线、箭头、框架建立视觉链接",
-        "风格要求:高质量2D绘画,清晰线稿+柔和上色,背景为米色/羊皮纸纹理/浅灰色科研海报风,注释拟手写式中文",
-        "参考风格:皮埃尔·约瑟夫·雷杜德、爱丽丝·坦洁里尼"
+        "提示词中指定角色:「你是一位顶尖本草插画概态设计师,擅长把\"单味药材\"画成全景式知识分解图」",
+        "提示词中说明药材名称样式:药材大中文字名称+横的分隔线+药材小英文名称,并要求参照参考图样式",
+        "提示词中规定6个模块:模块A(原植物绘制)、模块B(药材本体/纹理细节)、模块C(性质标签:四气五味归经)、模块D(功效与应用:图标+注解)、模块E(现代剂型)、模块F(材质细节放大框)",
+        "提示词中规定风格:高质量2D插画,清晰线稿+柔和上色,背景用米色/羊皮纸纹理/浅灰色科研海报风,注释拟手写式中文,画风参考皮埃尔·约瑟夫·雷杜德、爱丽丝·坦洁里尼",
+        "提示词中规定输出格式:单页全景科普海报,4K高清,纵向构图,清晰留白,信息分区明确",
+        "提示词末尾指定具体药材:「要创作的药材是【柴胡】」(可替换为其他药材名)",
+        "用细线、箭头、框架将中央药材与四周信息建立视觉链接"
       ],
       "案例": [
         {
-          "输入": "柴胡",
-          "输出": "柴胡全景科普海报",
-          "效果": "展示了柴胡的植物形态、饮片细节、性味归经、功效应用及现代剂型"
+          "输入": "提示词指定药材:柴胡(Bupleurum chinense)",
+          "输出": "柴胡全景分解科普海报:中央为柴胡饮片切片插画,左侧模块A为原植物整株形态+根部放大,右上模块C为四气(微寒)/五味(苦、辛)/归经(肝、胆、肺、三焦)贴纸标签,右侧模块D为疏肝解郁/和解表里/升举阳气/退热截疟功效图标,右下模块E为配方颗粒/超微粉/提取物剂型,左下模块F为纤维结构/表皮纹理/断面纹理放大框,模块B为根部纹理细节放大",
+          "效果": "米色羊皮纸背景,手写式中文注释,设计手稿+本草笔记结合风格,信息分区明确"
         },
         {
-          "输入": "陈皮",
-          "输出": "陈皮全景科普海报",
-          "效果": "展示了陈皮的来源、陈化过程、材质细节及应用场景"
+          "输入": "提示词指定药材:陈皮(Citrus reticulata Pericarpium)",
+          "输出": "陈皮全景分解科普海报:中央为陈皮饮片插画,模块A为橘树整株+果实截面+组织放大,模块C为四气(温)/五味(辛、苦)/归经(脾、肺)标签,模块D为理气健脾/燥湿化痰/降逆止呕等功效+生金汁桔茶/陈皮汤料等场景,模块E为陈皮饮片/陈皮颗粒/陈皮口服液/陈皮精油/陈皮精茶/食材精品,模块F为皮层微观结构放大",
+          "效果": "橙色系暖调,米色背景,手写注释风格"
         },
         {
-          "输入": "川芎",
-          "输出": "川芎全景科普海报",
-          "效果": "展示了川芎的植物形态、油室特征、功效及现代剂型"
+          "输入": "提示词指定药材:川芎(Ligusticum chuanxiong)",
+          "输出": "川芎全景分解科普海报:中央为川芎根茎插画(3-10cm标注),模块A为原植物形态(40-60cm,复伞形花序、轮节等标注),模块C为四气(温)/五味(辛)/归经(肝、胆、心包)标签,模块D为活血行气/祛风止痛/治疗头痛/调经止痛功效+川芎茶/药酒场景,模块E为川芎饮片/川芎粉/川芎胶囊/川芎嗪注射液/口服液,模块F为油室/维管束断面放大",
+          "效果": "暖黄色调,火焰氛围渲染中央药材,信息模块清晰分区"
         },
         {
-          "输入": "当归",
-          "输出": "当归全景科普海报",
-          "效果": "展示了当归的归头、归身、归尾结构及药用价值"
+          "输入": "提示词指定药材:当归(Angelica sinensis)",
+          "输出": "当归全景分解科普海报:中央为当归整根插画(40-100cm标注,归头/归身/归尾分区标注),模块A为原植物整株形态,模块C为四气(温)/五味(甘、辛、苦)/归经(肝、心、脾)标签,模块D为补血活血/调经止痛/润肠通便/消肿生肌功效,模块E为归头片/归身片/归尾片/当归片/当归颗粒/当归口服液/当归精油/当归提取物,模块F为断面纹理(形成层环/裂隙/油室)放大",
+          "效果": "米色背景,手写注释,归头/归身/归尾三段功效差异清晰呈现"
         },
         {
-          "输入": "冬虫夏草",
-          "输出": "冬虫夏草全景科普海报",
-          "效果": "展示了冬虫夏草的形成过程、虫体与草体结构及材质细节"
+          "输入": "提示词指定药材:冬虫夏草(Ophiocordyceps sinensis)",
+          "输出": "冬虫夏草全景分解科普海报:中央为虫体(4.2cm)+草体(6.5cm)完整形态插画,来源与形成模块展示冬季幼虫→夏季出草过程,性质标签为四气(平)/五味(甜)/归经(肺、肾),功效为补肺益肾/止血化痰/平喘/增强免疫,材质细节为虫体横切面(V/U形心线)/菌丝体微结构,现代剂型为整条冬虫夏草/虫草粉/虫草胶囊/虫草口服液/虫补/发酵虫草菌粉",
+          "效果": "米色背景带水渍纹理,科研海报风,尺寸标注详细"
         },
         {
-          "输入": "甘草",
-          "输出": "甘草全景科普海报",
-          "效果": "展示了甘草的植物形态、根部纹理及现代剂型"
+          "输入": "提示词指定药材:甘草(Glycyrrhiza uralensis)",
+          "输出": "甘草全景分解科普海报:中央为甘草根茎插画(70cm长、2.5cm直径标注),模块A为原植物形态(80cm,叶片/花序/豆荚放大),模块C为四气(平)/五味(甘)/归经(脾、胃、心、肺)标签,模块D为补脾益气/清热解毒/祛痰止咳/缓急止痛/调和诸药五大功效,模块E为生甘草/炙甘草/甘草饮片/甘草颗粒/胶囊/口服液/甘草酸/甘草甜素/甘草提取物/去甘草酸提取物/黄酮提取物/注射液,模块F为髓/皮层/形成层/皮孔/皱纹断面放大",
+          "效果": "米色背景,植物藤蔓装饰边框,「国老」「十方九草」文化标注"
         }
       ],
       "缺点": null,

+ 28 - 2
examples/process_pipeline/script/search_eval/fixed_query_eval/server.py

@@ -114,7 +114,7 @@ def run_extraction_task(q, folder_name, src_path, out_dir, engine, model):
 # 仍走 subprocess(tool_extract.py),让 LLM 重依赖留在子进程,server 本身保持轻量。
 TOOL_TASKS = {}   # {q: {"status", "case_ids", "error", "start_time"}}
 
-def run_tool_extraction_task(q, case_ids, force):
+def run_tool_extraction_task(q, case_ids, force, model=None):
     log_path = HERE / "runs_full" / q / "tools" / "_extract.log"
     try:
         log_path.parent.mkdir(parents=True, exist_ok=True)
@@ -122,6 +122,8 @@ def run_tool_extraction_task(q, case_ids, force):
                "--q", q, "--case-ids", ",".join(case_ids)]
         if force:
             cmd.append("--force")
+        if model:
+            cmd += ["--model", model]
         flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
         with open(log_path, "w", encoding="utf-8", buffering=1) as log_fh:
             proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
@@ -769,6 +771,17 @@ class H(BaseHTTPRequestHandler):
                 self._send(200, json.dumps({"content": content}, ensure_ascii=False), "application/json")
             except Exception as e:
                 self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        elif path == "/api/tool_prompt":
+            # 工具解构系统 prompt(prompts/tool_extract_system.md)原文,供前端「重新解构」弹框编辑
+            target_path = HERE / "prompts" / "tool_extract_system.md"
+            if not target_path.is_file():
+                self._send(404, json.dumps({"error": "tool prompt not found"}, ensure_ascii=False), "application/json")
+                return
+            try:
+                content = target_path.read_text(encoding="utf-8", errors="replace")
+                self._send(200, json.dumps({"content": content}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
         elif path == "/api/reeval_status":
             q = (params.get("q") or [""])[0].strip()
             if not q:
@@ -894,17 +907,30 @@ class H(BaseHTTPRequestHandler):
             q = (payload.get("q") or "").strip()
             case_ids = payload.get("case_ids") or []
             force = bool(payload.get("force"))
+            prompt = payload.get("prompt")
+            # 模型选择:仅允许白名单 choice key,传给 tool_extract.py --model
+            TOOL_MODEL_CHOICES = {"gemini-flash-lite", "gemini-3.5-flash", "sonnet"}
+            model = (payload.get("model") or "").strip() or None
+            if model and model not in TOOL_MODEL_CHOICES:
+                self._send(400, json.dumps({"error": f"bad model: {model!r}"}, ensure_ascii=False), "application/json"); return
             if not re.match(r"^q\d+$", q):
                 self._send(400, json.dumps({"error": f"bad q (expect 'qNN'): {q!r}"}, ensure_ascii=False), "application/json"); return
             if not isinstance(case_ids, list) or not case_ids:
                 self._send(400, json.dumps({"error": "case_ids must be a non-empty list"}, ensure_ascii=False), "application/json"); return
             if not (HERE / "runs_full" / q / "form_A.json").is_file():
                 self._send(404, json.dumps({"error": f"runs_full/{q}/form_A.json not found"}, ensure_ascii=False), "application/json"); return
+            # 前端「重新解构」弹框可带上编辑后的 prompt → 持久化到 prompts/tool_extract_system.md,
+            # tool_extract.py 子进程会在启动时重新读取该文件,于是按最新 prompt 解构。
+            if isinstance(prompt, str) and prompt.strip():
+                try:
+                    (HERE / "prompts" / "tool_extract_system.md").write_text(prompt, encoding="utf-8")
+                except Exception as e:
+                    self._send(500, json.dumps({"error": f"save prompt failed: {e}"}, ensure_ascii=False), "application/json"); return
             TOOL_TASKS[q] = {
                 "status": "running", "case_ids": case_ids,
                 "start_time": datetime.now().isoformat(), "pid": None, "error": None,
             }
-            t = threading.Thread(target=run_tool_extraction_task, args=(q, case_ids, force))
+            t = threading.Thread(target=run_tool_extraction_task, args=(q, case_ids, force, model))
             t.daemon = True
             t.start()
             self._send(200, json.dumps({

+ 5884 - 0
examples/process_pipeline/script/search_eval/mode_procedure/.cloudflared.log

@@ -0,0 +1,5884 @@
+2026-06-12T02:26:50Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee, are subject to the Cloudflare Online Services Terms of Use (https://www.cloudflare.com/website-terms/), and Cloudflare reserves the right to investigate your use of Tunnels for violations of such terms. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
+2026-06-12T02:26:50Z INF Requesting new quick Tunnel on trycloudflare.com...
+2026-06-12T02:26:53Z INF +--------------------------------------------------------------------------------------------+
+2026-06-12T02:26:53Z INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
+2026-06-12T02:26:53Z INF |  https://probability-land-pairs-matters.trycloudflare.com                                  |
+2026-06-12T02:26:53Z INF +--------------------------------------------------------------------------------------------+
+2026-06-12T02:26:53Z INF Cannot determine default configuration path. No file [config.yml config.yaml] in [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp /etc/cloudflared /usr/local/etc/cloudflared]
+2026-06-12T02:26:53Z INF Version 2026.6.0 (Checksum a13041d6ffff9d56f7df1629c24d9c0bacf4f73409d6cab0f5a1f60631ba9667)
+2026-06-12T02:26:53Z INF GOOS: darwin, GOVersion: go1.26.4, GoArch: amd64
+2026-06-12T02:26:53Z INF Settings: map[ha-connections:1 p:http2 protocol:http2 url:http://localhost:8771]
+2026-06-12T02:26:53Z INF cloudflared will not automatically update if installed by a package manager.
+2026-06-12T02:26:53Z INF Generated Connector ID: 4fd8489c-d909-4aa6-a293-1966420fbcb6
+2026-06-12T02:26:53Z INF Initial protocol http2
+2026-06-12T02:26:53Z INF ICMP proxy will use 192.168.81.52 as source for IPv4
+2026-06-12T02:26:53Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
+2026-06-12T02:26:53Z INF Created ICMP proxy listening on 192.168.81.52:0
+2026-06-12T02:26:53Z INF Created ICMP proxy listening on [::1]:0
+2026-06-12T02:26:53Z INF ICMP proxy will use 192.168.81.52 as source for IPv4
+2026-06-12T02:26:53Z INF ICMP proxy will use ::1 in zone lo0 as source for IPv6
+2026-06-12T02:26:53Z INF Starting metrics server on 127.0.0.1:20243/metrics
+2026-06-12T02:26:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T02:26:55Z INF Registered tunnel connection connIndex=0 connection=3d05b611-3ac8-4f01-ba0c-62d52ccbcdeb event=0 ip=198.41.200.53 location=lax01 protocol=http2
+2026-06-12T02:27:00Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T02:27:00Z INF |                               CONNECTIVITY PRE-CHECKS                               |
+2026-06-12T02:27:00Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T02:27:00Z INF |  COMPONENT         TARGET                     STATUS  DETAILS                       |
+2026-06-12T02:27:00Z INF |  DNS Resolution    region1.v2.argotunnel.com  PASS    DNS Resolved successfully     |
+2026-06-12T02:27:00Z INF |  DNS Resolution    region2.v2.argotunnel.com  PASS    DNS Resolved successfully     |
+2026-06-12T02:27:00Z INF |  UDP Connectivity  region1.v2.argotunnel.com  PASS    QUIC connection successful    |
+2026-06-12T02:27:00Z INF |  UDP Connectivity  region2.v2.argotunnel.com  PASS    QUIC connection successful    |
+2026-06-12T02:27:00Z INF |  TCP Connectivity  region1.v2.argotunnel.com  PASS    HTTP/2 connection successful  |
+2026-06-12T02:27:00Z INF |  TCP Connectivity  region2.v2.argotunnel.com  PASS    HTTP/2 connection successful  |
+2026-06-12T02:27:00Z INF |  Cloudflare API    api.cloudflare.com:443     PASS    API is reachable              |
+2026-06-12T02:27:00Z INF |                                                                                     |
+2026-06-12T02:27:00Z INF |  SUMMARY: Environment is healthy. cloudflared will use 'quic' as primary protocol.  |
+2026-06-12T02:27:00Z INF +-------------------------------------------------------------------------------------+
+2026-06-12T02:27:00Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region1.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="DNS Resolution" details="DNS Resolved successfully" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region2.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="UDP Connectivity" details="QUIC connection successful" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region1.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="UDP Connectivity" details="QUIC connection successful" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region2.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region1.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="TCP Connectivity" details="HTTP/2 connection successful" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=region2.v2.argotunnel.com
+2026-06-12T02:27:00Z INF precheck component="Cloudflare API" details="API is reachable" run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 status=pass target=api.cloudflare.com:443
+2026-06-12T02:27:00Z INF precheck complete hard_fail=false run_id=fd1ff4a4-2565-43cb-921a-d578429d2392 suggested_protocol=quic
+2026-06-12T12:41:25Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused" connIndex=0 event=1 ingressRule=0 originService=http://localhost:8771
+2026-06-12T12:41:25Z ERR failed to serve incoming request error="Failed to proxy HTTP: Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused"
+2026-06-12T12:41:25Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused" connIndex=0 event=1 ingressRule=0 originService=http://localhost:8771
+2026-06-12T12:41:25Z ERR failed to serve incoming request error="Failed to proxy HTTP: Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused"
+2026-06-12T12:41:44Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused" connIndex=0 event=1 ingressRule=0 originService=http://localhost:8771
+2026-06-12T12:41:44Z ERR failed to serve incoming request error="Failed to proxy HTTP: Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp [::1]:8771: connect: connection refused"
+2026-06-12T14:58:10Z INF Lost connection with the edge connIndex=0
+2026-06-12T14:58:10Z ERR failed to serve incoming request error="Error shutting down control stream: context canceled"
+2026-06-12T14:58:10Z ERR Serve tunnel error error="connection with edge closed" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:10Z INF Retrying connection in up to 1s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:11Z ERR Connection terminated error="connection with edge closed" connIndex=0
+2026-06-12T14:58:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:58:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:28Z INF Retrying connection in up to 4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T14:58:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:58:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:32Z INF Retrying connection in up to 8s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:58:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T14:59:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:59:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T14:59:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:59:20Z INF Retrying connection in up to 16s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T14:59:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:01:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:01:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:01:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:01:28Z INF Retrying connection in up to 32s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:01:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:04:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:04:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:04:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:04:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:04:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:08:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:08:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:08:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:08:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:08:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:11:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:11:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:11:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:11:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:12:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:16:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:16:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:16:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:16:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:17:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:21:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:21:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:21:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:21:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:21:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:26:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:26:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:26:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:26:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:26:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:28:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:28:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:28:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:28:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:29:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:34:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:34:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:34:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:34:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:35:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:37:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:37:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:37:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:37:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:37:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:40:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:40:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:40:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:40:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:40:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:45:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:45:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:45:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:45:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:45:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:47:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:47:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:47:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:47:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:47:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:48:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:48:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:48:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:48:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:48:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:51:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:51:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:51:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:51:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:52:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:56:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:56:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:56:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:56:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:56:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:57:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:57:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:57:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:57:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:58:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T15:59:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:59:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T15:59:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:59:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T15:59:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:04:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:04:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:04:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:04:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:04:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:06:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:06:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:06:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:06:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:06:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:08:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:08:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:08:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:08:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:08:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:09:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:09:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:09:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:09:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:09:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:11:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:11:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:11:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:11:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:12:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:17:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:17:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:17:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:17:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:17:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:21:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:21:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:21:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:21:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:21:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:25:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:25:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:25:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:25:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:25:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:28:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:28:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:28:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:28:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:28:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:33:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:33:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:33:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:33:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:33:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:35:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:35:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:35:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:35:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:35:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:38:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:38:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:38:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:38:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:38:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:40:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:40:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:40:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:40:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:40:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:42:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:42:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:42:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:42:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:42:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:45:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:45:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:45:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:45:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:45:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:46:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:47:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:47:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:47:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:47:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:49:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:49:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:49:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:49:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:50:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:51:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:51:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:51:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:51:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:52:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:57:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:57:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:57:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:57:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:57:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T16:58:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:58:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T16:58:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:58:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T16:58:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:00:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:00:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:00:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:00:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:00:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:04:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:04:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:04:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:04:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:04:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:08:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:08:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:08:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:08:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:09:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:12:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:12:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:12:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:12:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:12:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:17:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:17:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:17:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:17:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:18:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:19:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:19:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:19:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:19:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:19:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:24:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:24:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:24:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:24:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:24:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:26:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:26:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:26:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:26:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:26:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:30:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:30:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:30:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:30:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:31:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:35:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:35:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:35:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:35:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:36:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:40:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:40:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:40:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:40:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:40:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:43:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:43:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:43:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:43:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:43:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:47:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:47:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:47:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:47:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:47:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:51:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:51:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:51:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:51:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:51:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:53:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:53:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:53:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:53:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:53:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:56:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:56:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:56:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:56:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:56:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:57:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:57:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:57:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:57:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:57:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T17:59:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:59:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T17:59:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T17:59:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:00:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:04:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:04:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:04:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:04:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:04:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:09:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:09:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:09:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:09:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:09:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:13:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:13:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:13:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:13:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:13:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:16:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:16:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:16:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:16:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:17:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:21:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:21:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:21:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:21:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:21:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:22:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:22:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:22:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:22:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:22:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:26:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:26:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:26:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:26:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:26:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:28:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:28:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:28:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:28:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:29:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:30:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:30:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:30:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:30:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:30:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:32:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:32:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:32:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:32:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:32:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:34:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:34:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:34:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:34:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:34:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:35:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:35:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:35:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:35:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:36:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:38:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:38:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:38:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:38:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:38:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:42:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:42:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:42:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:42:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:42:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:45:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:45:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:45:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:45:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:45:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:48:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:48:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:48:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:48:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:48:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:51:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:51:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:51:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:51:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:51:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:56:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:56:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:56:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:56:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:57:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T18:58:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:58:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T18:58:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:58:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T18:59:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:00:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:00:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:00:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:00:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:00:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:01:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:01:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:01:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:01:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:01:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:03:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:03:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:03:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:03:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:04:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:04:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:04:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:04:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:04:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:04:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:09:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:09:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:09:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:09:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:09:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:15:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:15:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:15:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:15:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:15:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:16:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:16:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:16:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:16:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:17:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:17:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:17:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:17:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:17:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:17:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:22:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:22:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:22:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:22:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:22:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:26:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:26:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:26:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:26:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:26:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:31:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:31:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:31:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:31:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:31:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:34:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:34:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:34:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:34:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:34:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:39:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:39:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:39:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:39:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:40:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:40:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:40:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:41:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:41:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:41:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:41:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:42:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:42:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:42:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:42:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:47:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:47:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:47:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:47:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:47:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:51:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:51:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:51:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:51:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:51:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:56:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:56:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:56:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:56:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:56:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T19:59:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:59:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T19:59:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:59:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T19:59:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:00:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:00:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:00:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:00:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:01:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:02:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:02:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:02:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:02:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:02:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:03:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:03:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:03:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:03:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:03:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:05:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:05:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:05:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:05:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:06:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:06:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:06:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:06:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:06:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:06:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:09:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:09:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:09:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:09:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:09:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:13:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:13:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:13:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:13:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:13:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:15:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:15:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:15:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:15:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:15:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:17:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:17:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:17:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:17:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:18:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:23:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:23:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:23:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:23:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:23:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:25:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:25:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:25:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:25:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:25:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:29:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:29:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:29:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:29:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:29:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:35:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:35:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:35:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:35:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:35:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:37:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:37:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:37:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:37:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:37:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:41:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:41:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:41:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:41:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:42:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:43:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:43:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:43:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:43:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:43:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:44:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:44:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:44:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:44:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:44:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:46:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:46:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:46:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:46:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:46:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:51:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:51:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:51:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:51:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:51:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:53:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:53:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:53:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:53:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:54:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T20:57:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:57:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T20:57:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:57:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T20:57:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:03:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:03:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:03:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:03:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:03:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:06:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:07:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:07:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:07:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:07:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:09:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:09:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:09:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:09:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:10:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:13:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:13:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:13:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:13:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:13:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:16:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:16:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:16:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:16:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:17:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:20:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:20:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:20:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:20:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:20:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:25:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:25:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:25:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:25:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:25:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:25:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:25:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:25:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:25:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:26:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:28:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:28:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:28:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:28:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:28:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:30:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:30:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:30:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:30:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:30:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:31:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:31:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:31:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:31:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:32:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:35:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:35:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:35:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:35:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:35:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:39:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:39:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:39:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:39:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:39:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:42:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:42:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:42:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:42:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:43:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:47:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:47:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:47:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:47:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:48:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:51:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:51:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:51:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:51:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:51:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:52:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:52:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:52:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:52:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:52:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:56:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:56:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:56:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:56:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:56:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T21:59:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:59:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T21:59:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:59:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T21:59:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:03:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:03:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:03:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:03:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:04:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:09:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:09:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:09:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:09:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:09:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:14:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:14:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:14:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:14:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:14:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:17:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:17:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:17:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:17:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:18:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:22:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:22:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:22:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:22:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:22:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:25:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:25:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:25:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:25:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:25:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:26:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:26:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:26:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:26:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:26:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:28:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:28:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:28:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:28:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:28:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:33:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:33:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:33:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:33:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:34:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:37:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:37:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:37:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:37:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:38:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:40:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:40:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:40:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:40:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:41:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:42:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:42:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:42:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:42:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:43:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:43:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:43:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:43:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:43:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:44:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:49:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:49:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:49:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:49:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:49:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:53:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:53:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:53:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:53:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:53:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T22:57:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:57:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T22:57:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:57:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T22:57:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:02:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:02:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:02:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:02:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:02:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:06:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:06:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:06:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:06:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:06:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:10:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:10:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:10:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:10:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:11:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:12:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:12:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:12:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:12:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:12:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:15:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:15:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:15:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:15:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:15:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:19:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:19:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:19:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:19:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:19:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:21:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:21:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:21:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:21:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:21:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:22:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:22:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:22:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:22:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:22:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:25:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:25:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:25:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:25:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:25:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:30:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:30:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:30:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:30:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:31:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:31:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:31:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:31:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:31:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:32:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:37:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:37:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:37:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:37:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:37:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:40:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:40:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:40:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:40:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:40:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:45:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:45:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:45:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:45:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:45:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:48:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:49:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:49:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:49:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:49:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:54:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:54:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:54:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:54:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:54:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:55:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:55:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:55:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:55:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:55:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-12T23:59:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:59:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-12T23:59:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-12T23:59:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:00:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:02:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:02:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:02:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:02:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:02:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:04:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:04:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:04:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:04:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:05:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:08:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:08:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:08:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:08:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:08:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:11:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:11:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:11:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:11:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:11:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:15:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:15:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:15:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:15:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:15:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:19:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:19:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:19:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:19:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:19:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:21:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:21:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:21:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:21:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:22:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:24:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:24:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:24:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:24:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:24:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:29:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:29:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:29:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:29:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:29:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:32:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:32:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:32:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:32:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:32:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:35:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:35:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:35:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:35:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:36:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:37:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:37:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:37:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:37:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:37:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:42:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:42:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:42:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:42:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:42:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:45:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:45:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:45:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:45:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:45:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:49:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:49:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:49:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:49:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:49:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:52:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:52:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:52:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:52:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:52:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:55:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:55:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:55:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:55:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:56:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T00:58:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:58:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T00:58:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:58:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T00:59:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:01:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:01:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:01:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:01:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:01:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:06:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:06:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:06:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:06:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:06:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:09:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:09:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:09:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:09:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:10:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:14:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:14:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:14:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:14:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:14:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:19:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:19:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:19:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:19:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:19:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:22:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:22:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:22:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:22:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:22:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:24:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:24:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:24:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:24:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:25:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:29:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:29:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:29:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:29:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:29:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:33:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:33:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:33:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:33:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:33:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:34:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:34:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:34:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:34:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:35:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:39:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:39:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:39:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:39:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:39:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:43:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:43:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:43:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:43:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:44:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:47:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:47:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:47:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:47:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:47:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:47:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:47:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:47:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:47:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:48:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:48:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:48:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:48:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:48:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:49:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:52:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:52:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:52:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:52:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:52:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:56:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:56:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:56:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:56:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:56:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T01:57:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:57:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T01:57:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:57:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T01:57:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:02:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:02:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:02:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:02:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:03:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:03:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:04:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:04:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:04:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:04:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:08:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:08:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:08:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:08:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:09:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:12:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:12:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:12:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:12:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:12:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:14:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:14:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:14:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:14:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:14:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:17:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:17:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:17:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:17:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:18:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:18:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:18:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:18:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:18:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:19:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:23:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:23:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:23:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:23:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:24:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:29:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:29:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:29:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:29:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:29:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:32:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:32:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:32:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:32:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:32:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:33:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:33:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:33:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:33:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:34:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:37:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:37:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:37:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:37:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:38:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:39:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:39:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:39:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:39:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:39:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:41:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:41:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:41:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:41:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:42:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:47:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:47:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:47:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:47:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:47:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:48:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:48:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:48:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:48:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:48:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:53:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:53:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:53:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:53:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:53:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:53:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:53:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:53:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:53:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:54:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:55:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:55:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:55:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:55:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:55:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:58:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:58:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T02:58:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T02:58:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T02:58:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:03:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:03:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:03:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:03:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:04:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:04:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:04:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:04:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:04:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:04:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:05:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:05:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:05:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:05:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:06:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:09:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:09:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:09:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:09:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:09:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:13:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:13:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:13:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:13:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:14:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:15:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:15:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:15:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:15:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:15:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:19:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:19:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:19:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:19:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:19:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:21:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:21:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:21:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:21:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:21:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:23:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:23:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:23:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:23:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:23:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:25:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:25:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:25:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:25:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:26:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:26:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:26:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:26:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:26:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:26:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:31:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:31:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:31:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:31:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:31:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:36:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:36:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:36:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:36:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:36:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:40:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:40:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:40:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:40:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:40:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:43:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:43:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:43:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:43:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:44:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:48:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:48:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:48:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:48:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:49:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:54:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:54:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:54:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:54:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:54:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:55:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:56:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:56:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:56:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:56:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T03:57:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:57:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T03:57:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:57:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T03:58:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:02:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:02:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:02:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:02:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:03:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:04:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:04:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:04:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:04:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:04:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:05:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:05:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:05:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:05:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:05:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:07:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:07:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:07:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:07:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:08:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:13:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:13:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:13:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:13:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:13:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:13:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:14:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:14:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:14:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:14:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:18:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:18:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:18:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:18:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:18:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:23:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:23:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:23:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:23:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:23:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:23:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:23:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:23:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:23:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:24:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:28:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:28:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:28:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:28:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:28:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:33:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:33:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:33:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:33:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:33:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:36:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:36:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:36:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:36:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:36:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:36:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:36:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:36:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:36:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:37:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:41:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:41:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:41:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:41:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:42:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:44:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:44:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:44:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:44:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:45:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:48:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:48:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:48:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:48:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:48:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:48:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:48:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:48:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:48:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:49:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:54:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:54:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:54:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:54:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:55:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T04:57:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:57:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T04:57:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:57:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T04:57:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:02:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:02:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:02:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:02:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:02:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:04:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:04:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:04:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:04:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:05:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:08:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:08:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:08:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:08:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:08:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:11:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:11:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:11:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:11:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:11:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:12:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:12:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:12:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:12:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:12:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:17:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:17:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:17:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:17:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:17:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:21:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:21:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:21:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:21:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:22:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:23:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:23:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:23:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:23:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:23:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:28:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:28:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:28:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:28:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:28:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:29:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:29:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:29:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:29:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:29:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:31:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:31:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:31:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:31:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:31:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:35:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:35:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:35:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:35:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:35:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:38:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:38:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:38:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:38:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:38:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:43:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:43:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:43:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:43:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:44:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:44:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:44:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:44:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:44:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:44:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:45:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:45:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:45:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:45:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:45:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:47:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:47:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:47:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:47:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:47:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:51:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:51:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:51:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:51:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:52:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:52:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:52:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:53:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:53:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:53:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:54:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:54:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:54:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:54:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:54:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T05:56:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:56:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T05:56:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:56:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T05:56:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:01:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:01:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:01:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:01:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:01:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:04:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:04:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:04:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:04:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:04:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:05:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:05:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:05:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:05:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:05:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:09:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:09:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:09:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:09:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:09:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:11:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:11:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:11:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:11:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:12:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:16:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:16:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:16:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:16:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:16:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:21:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:22:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:22:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:22:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:22:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:26:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:26:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:26:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:26:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:26:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:31:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:31:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:31:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:31:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:31:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:34:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:34:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:34:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:34:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:35:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:49:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:49:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:49:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:49:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:49:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:52:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:52:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:52:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:52:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:53:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T06:56:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:56:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T06:56:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:56:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T06:56:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:00:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:00:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:00:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:00:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:00:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:01:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:01:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:01:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:01:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:01:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:01:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:01:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:01:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:01:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:02:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:06:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:06:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:06:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:06:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:06:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:10:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:10:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:10:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:10:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:10:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:12:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:12:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:12:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:12:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:13:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:15:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:15:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:15:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:15:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:16:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:16:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:16:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:16:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:16:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:16:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:21:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:21:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:21:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:21:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:21:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:25:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:25:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:25:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:25:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:26:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:28:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:28:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:28:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:28:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:29:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:31:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:31:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:31:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:31:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:32:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:35:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:35:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:35:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:35:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:35:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:36:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:36:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:36:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:36:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:36:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:40:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:40:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:40:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:40:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:40:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:43:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:43:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:43:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:43:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:43:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:45:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:45:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:45:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:45:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:45:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:49:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:49:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:49:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:49:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:49:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:53:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:53:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:53:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:53:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:53:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:57:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:57:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:57:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:57:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:58:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T07:58:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:58:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T07:58:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:58:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T07:58:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:01:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:01:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:01:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:01:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:01:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:03:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:03:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:03:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:03:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:03:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:04:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:04:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:04:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:04:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:04:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:05:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:05:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:05:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:05:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:05:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:10:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:10:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:10:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:10:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:10:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:12:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:12:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:12:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:12:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:12:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:15:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:15:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:15:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:15:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:15:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:16:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:16:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:16:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:16:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:17:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:20:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:20:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:20:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:20:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:20:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:22:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:22:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:22:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:22:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:22:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:26:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:26:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:26:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:26:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:27:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:30:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:30:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:30:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:30:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:31:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:35:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:35:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:35:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:35:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:35:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:39:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:39:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:39:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:39:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:40:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:41:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:41:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:41:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:41:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:41:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:45:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:45:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:45:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:45:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:45:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:47:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:47:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:47:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:47:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:47:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:50:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:50:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:50:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:50:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:50:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:54:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:54:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:54:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:54:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:54:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:55:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:55:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:55:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:55:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:55:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T08:57:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:57:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T08:57:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:57:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T08:57:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:02:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:02:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:02:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:02:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:02:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:04:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:04:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:04:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:04:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:04:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:05:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:05:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:05:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:05:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:06:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:10:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:10:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:10:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:10:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:11:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:12:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:12:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:12:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:12:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:12:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:15:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:15:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:15:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:15:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:15:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:18:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:18:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:18:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:18:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:19:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:20:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:20:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:20:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:20:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:21:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:23:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:23:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:23:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:23:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:23:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:28:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:28:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:28:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:28:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:29:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:31:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:31:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:31:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:31:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:31:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:36:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:36:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:36:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:36:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:36:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:41:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:41:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:41:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:41:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:41:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:42:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:42:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:42:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:42:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:42:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:45:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:46:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:46:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:46:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:46:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:50:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:50:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:50:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:50:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:51:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:51:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:51:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:51:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:51:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:52:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:53:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:53:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:53:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:53:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:53:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T09:56:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:56:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T09:56:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:56:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T09:56:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:01:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:01:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:01:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:01:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:01:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:06:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:06:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:06:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:06:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:06:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:09:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:09:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:09:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:09:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:10:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:14:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:14:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:14:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:14:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:14:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:19:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:19:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:19:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:19:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:20:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:20:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:20:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:20:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:20:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:21:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:25:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:25:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:25:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:25:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:25:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:30:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:30:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:30:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:30:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:30:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:34:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:34:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:34:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:34:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:34:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:38:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:39:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:39:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:39:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:39:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:40:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:40:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:40:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:40:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:40:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:42:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:42:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:42:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:42:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:42:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:43:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:43:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:43:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:43:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:43:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:44:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:44:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:44:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:44:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:45:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:47:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:47:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:47:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:47:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:47:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:50:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:51:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:51:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:51:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:51:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:55:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:55:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:55:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:55:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:55:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T10:58:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:58:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T10:58:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:58:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T10:58:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:01:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:01:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:01:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:01:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:01:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:05:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:05:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:05:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:05:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:05:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:10:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:10:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:10:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:10:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:11:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:12:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:12:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:12:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:12:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:12:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:13:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:13:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:13:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:13:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:13:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:13:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:13:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:13:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:13:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:14:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:15:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:15:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:15:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:15:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:15:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:17:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:17:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:17:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:17:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:18:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:18:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:18:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:18:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:18:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:19:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:22:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:22:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:22:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:22:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:23:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:28:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:28:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:28:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:28:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:28:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:32:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:32:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:32:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:32:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:33:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:35:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:36:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:36:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:36:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:36:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:36:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:37:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:37:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:37:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:37:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:40:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:40:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:40:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:40:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:40:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:45:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:45:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:45:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:45:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:45:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:46:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:46:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:46:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:46:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:46:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:46:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:46:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:47:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:47:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:47:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:49:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:49:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:49:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:49:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:49:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:52:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:52:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:52:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:52:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:52:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:55:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:55:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:55:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:55:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:56:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T11:56:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:56:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T11:56:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:56:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T11:56:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:00:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:00:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:00:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:00:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:00:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:01:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:01:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:01:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:01:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:01:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:05:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:05:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:05:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:05:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:05:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:09:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:09:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:09:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:09:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:10:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:14:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:14:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:14:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:14:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:14:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:18:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:18:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:18:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:18:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:19:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:19:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:19:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:19:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:19:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:20:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:20:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:20:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:20:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:20:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:20:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:25:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:25:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:25:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:25:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:25:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:29:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:29:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:29:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:29:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:29:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:32:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:32:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:32:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:32:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:33:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:34:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:34:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:34:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:34:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:34:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:36:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:36:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:36:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:36:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:36:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:37:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:37:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:37:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:37:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:37:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:41:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:41:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:41:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:41:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:41:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:45:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:45:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:45:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:45:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:45:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:50:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:50:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:50:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:50:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:51:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:53:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:53:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:53:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:53:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:53:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T12:55:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:55:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T12:55:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:55:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T12:55:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:01:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:01:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:01:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:01:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:01:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:01:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:01:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:01:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:01:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:02:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:06:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:06:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:06:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:06:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:07:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:10:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:10:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:10:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:10:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:10:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:11:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:11:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:11:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:11:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:12:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:13:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:13:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:13:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:13:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:13:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:14:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:14:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:14:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:14:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:14:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:18:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:18:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:18:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:18:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:18:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:23:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:23:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:23:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:23:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:23:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:28:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:28:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:28:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:28:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:28:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:28:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:28:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:28:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:28:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:29:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:29:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:29:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:29:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:29:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:30:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:34:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:34:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:34:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:34:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:34:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:37:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:37:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:37:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:37:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:37:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:38:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:38:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:38:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:38:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:38:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:43:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:43:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:43:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:43:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:44:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:46:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:46:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:46:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:46:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:46:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:50:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:50:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:50:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:50:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:51:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:53:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:53:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:53:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:53:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:54:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:58:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:58:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:58:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:58:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:58:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T13:59:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:59:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T13:59:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:59:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T13:59:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:01:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:02:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:02:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:02:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:02:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:05:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:05:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:05:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:05:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:05:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:08:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:08:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:08:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:08:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:09:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:13:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:13:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:13:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:13:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:13:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:17:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:17:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:17:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:17:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:17:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:21:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:21:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:21:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:21:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:21:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:25:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:25:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:25:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:25:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:25:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:28:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:28:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:28:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:28:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:29:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:32:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:32:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:32:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:32:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:32:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:33:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:33:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:33:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:33:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:33:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:38:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:38:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:38:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:38:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:38:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:41:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:41:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:41:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:41:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:41:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:45:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:45:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:45:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:45:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:45:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:49:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:49:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:49:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:49:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:49:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:53:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:53:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:53:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:53:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:53:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:56:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:56:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:56:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:56:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:56:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:59:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:59:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T14:59:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T14:59:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T14:59:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:04:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:04:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:04:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:04:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:04:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:08:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:08:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:08:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:08:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:08:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:13:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:13:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:13:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:13:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:13:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:14:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:14:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:14:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:14:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:14:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:15:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:15:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:15:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:15:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:15:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:16:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:16:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:16:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:16:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:17:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:18:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:18:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:18:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:18:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:18:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:24:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:24:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:24:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:24:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:24:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:26:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:26:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:26:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:26:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:26:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:29:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:29:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:29:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:29:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:29:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:32:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:32:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:32:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:32:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:32:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:36:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:36:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:36:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:36:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:37:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:41:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:41:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:41:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:41:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:41:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:44:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:44:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:44:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:44:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:44:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:46:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:46:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:46:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:46:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:46:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:50:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:50:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:50:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:50:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:51:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:53:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:53:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:53:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:53:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:53:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:55:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:55:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:55:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:55:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:56:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:57:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:57:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:57:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:57:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:57:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T15:58:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:58:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T15:58:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:58:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T15:58:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:02:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:02:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:02:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:02:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:03:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:04:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:04:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:04:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:04:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:04:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:09:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:09:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:09:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:09:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:09:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:14:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:14:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:14:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:14:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:14:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:15:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:15:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:15:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:15:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:15:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:19:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:19:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:19:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:19:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:20:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:21:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:21:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:21:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:21:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:21:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:26:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:26:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:26:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:26:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:26:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:27:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:27:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:27:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:27:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:27:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:31:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:31:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:31:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:31:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:32:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:37:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:37:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:37:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:37:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:37:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:42:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:42:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:42:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:42:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:43:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:47:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:47:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:47:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:47:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:47:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:50:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:50:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:50:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:50:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:50:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:51:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:51:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:51:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:51:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:51:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:55:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:55:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:55:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:55:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:55:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T16:59:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:59:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T16:59:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:59:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T16:59:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:04:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:04:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:04:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:04:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:04:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:07:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:07:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:07:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:07:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:08:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:11:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:11:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:11:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:11:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:11:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:14:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:14:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:14:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:14:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:15:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:18:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:18:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:18:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:18:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:19:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:20:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:20:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:20:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:20:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:21:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:24:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:25:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:25:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:25:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:25:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:30:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:30:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:30:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:30:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:30:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:31:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:31:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:31:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:31:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:31:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:36:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:36:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:36:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:36:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:36:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:39:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:39:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:39:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:39:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:39:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:41:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:41:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:41:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:41:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:42:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:46:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:46:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:46:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:46:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:46:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:48:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:48:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:48:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:48:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:48:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:53:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:53:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:53:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:53:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:53:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:56:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:56:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:56:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:56:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:56:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T17:58:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:58:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T17:58:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:58:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T17:58:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:01:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:01:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:01:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:01:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:01:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:06:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:06:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:06:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:06:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:07:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:10:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:10:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:10:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:10:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:11:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:14:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:14:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:15:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:15:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:15:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:18:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:18:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:18:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:18:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:18:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:23:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:23:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:23:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:23:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:23:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:25:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:25:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:25:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:25:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:26:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:26:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:26:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:26:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:26:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:26:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:28:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:28:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:28:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:28:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:29:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:31:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:31:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:31:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:31:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:32:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:33:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:33:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:33:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:33:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:33:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:37:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:37:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:37:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:37:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:38:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:42:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:42:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:42:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:42:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:42:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:43:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:43:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:43:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:43:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:44:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:44:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:44:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:44:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:44:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:44:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:45:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:45:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:45:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:45:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:46:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:47:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:47:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:47:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:47:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:47:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:52:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:52:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:52:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:52:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:53:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:58:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:58:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:58:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:58:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T18:58:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:00:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:00:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:00:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:00:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:00:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:05:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:05:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:05:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:05:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:06:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:08:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:08:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:08:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:08:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:09:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:10:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:10:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:10:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:10:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:11:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:16:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:16:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:16:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:16:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:16:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:19:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:19:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:19:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:19:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:19:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:22:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:22:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:22:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:22:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:22:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:23:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:23:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:23:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:23:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:24:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:25:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:25:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:25:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:25:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:25:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:27:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:27:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:27:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:27:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:27:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:30:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:30:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:30:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:30:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:30:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:33:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:33:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:33:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:33:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:34:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:38:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:38:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:38:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:38:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:39:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:42:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:42:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:42:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:42:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:42:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:44:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:44:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:44:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:44:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:44:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:47:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:47:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:47:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:47:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:48:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:53:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:53:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:53:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:53:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:53:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:54:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:54:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:54:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:54:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:54:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:56:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:56:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:56:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:56:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:56:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:59:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:59:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:59:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:59:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T19:59:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:01:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:01:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:01:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:01:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:01:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:03:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:03:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:03:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:03:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:03:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:06:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:06:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:06:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:06:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:06:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:11:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:11:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:11:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:11:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:12:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:15:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:15:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:15:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:15:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:15:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:18:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:18:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:18:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:18:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:18:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:22:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:22:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:22:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:22:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:22:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:26:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:26:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:26:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:26:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:26:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:28:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:28:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:28:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:28:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:29:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:33:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:33:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:33:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:33:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:34:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:39:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:39:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:39:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:39:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:39:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:42:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:42:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:42:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:42:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:42:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:44:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:44:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:44:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:44:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:44:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:46:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:46:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:46:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:46:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:46:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:48:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:48:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:48:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:48:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:48:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:53:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:53:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:53:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:53:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:53:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:59:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:59:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:59:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:59:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T20:59:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:02:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:02:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:02:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:02:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:02:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:04:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:04:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:04:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:04:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:04:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:10:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:10:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:10:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:10:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:10:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:14:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:14:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:14:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:14:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:14:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:16:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:16:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:16:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:16:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:16:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:19:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:19:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:19:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:19:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:20:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:20:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:20:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:20:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:20:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:20:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:23:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:23:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:23:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:23:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:23:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:26:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:26:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:26:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:26:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:26:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:27:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:27:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:27:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:27:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:27:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:30:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:30:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:30:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:30:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:30:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:35:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:35:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:35:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:35:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:35:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:36:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:36:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:36:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:36:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:36:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:39:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:39:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:39:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:39:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:39:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:41:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:41:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:41:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:41:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:41:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:43:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:43:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:43:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:43:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:43:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:46:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:46:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:46:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:46:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:46:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:51:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:51:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:51:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:51:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:51:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:56:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:56:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:56:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:56:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:56:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:59:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:59:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:59:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:59:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T21:59:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:03:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:03:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:03:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:03:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:03:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:04:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:04:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:04:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:04:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:05:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:09:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:09:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:09:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:09:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:09:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:14:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:14:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:14:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:14:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:14:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:16:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:16:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:16:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:16:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:16:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:21:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:21:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:21:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:21:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:21:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:24:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:24:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:24:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:24:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:24:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:27:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:27:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:27:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:27:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:28:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:28:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:28:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:28:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:28:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:29:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:32:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:32:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:32:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:32:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:32:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:35:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:35:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:35:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:35:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:35:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:38:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:38:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:38:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:38:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:39:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:42:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:43:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:43:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:43:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:43:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:44:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:44:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:44:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:44:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:44:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:48:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:48:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:48:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:48:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:48:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:50:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:50:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:50:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:50:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:50:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:50:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:50:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:50:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:50:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:51:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:55:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:55:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:55:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:55:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:56:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:59:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:59:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:59:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T22:59:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:00:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:05:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:05:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:05:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:05:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:05:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:09:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:09:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:09:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:09:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:09:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:13:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:13:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:13:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:13:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:13:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:14:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:14:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:14:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:14:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:14:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:19:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:19:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:19:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:19:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:19:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:23:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:23:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:23:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:23:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:24:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:29:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:29:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:29:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:29:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:29:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:30:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:30:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:30:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:30:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:31:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:35:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:35:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:35:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:35:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:36:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:39:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:39:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:39:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:39:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:40:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:41:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:41:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:41:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:41:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:41:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:46:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:46:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:46:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:46:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:46:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:48:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:48:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:48:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:48:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:48:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:49:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:49:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:49:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:49:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:49:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:54:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:54:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:54:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:54:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:54:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:54:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:54:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:54:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:54:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:55:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:59:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:59:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:59:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:59:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-13T23:59:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:04:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:04:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:04:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:04:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:04:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:05:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:05:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:05:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:05:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:06:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:06:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:06:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:06:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:06:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:06:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:11:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:11:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:11:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:11:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:11:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:14:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:14:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:14:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:14:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:14:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:18:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:18:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:18:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:18:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:19:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:21:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:21:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:21:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:21:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:21:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:24:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:24:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:24:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:24:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:24:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:28:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:28:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:28:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:28:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:29:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:32:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:32:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:32:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:32:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:32:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:36:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:36:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:36:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:36:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:36:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:38:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:38:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:38:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:38:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:39:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:42:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:42:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:42:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:42:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:42:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:44:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:44:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:44:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:44:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:45:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:46:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:46:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:46:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:46:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:46:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:46:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:47:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:47:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:47:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:47:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:51:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:51:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:51:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:51:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:51:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:55:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:55:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:55:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:55:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:55:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:59:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:59:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:59:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T00:59:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:00:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:05:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:05:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:05:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:05:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:05:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:06:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:06:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:06:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:06:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:06:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:08:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:08:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:08:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:08:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:08:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:12:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:12:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:12:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:12:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:12:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:16:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:16:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:16:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:16:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:16:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:20:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:20:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:20:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:20:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:21:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:26:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:26:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:26:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:26:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:26:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:30:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:30:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:31:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:31:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:31:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:36:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:36:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:36:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:36:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:36:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:37:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:38:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:38:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:38:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:38:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:41:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:41:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:41:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:41:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:41:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:46:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:46:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:46:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:46:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:46:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:50:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:50:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:50:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:50:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:50:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:50:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:51:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:51:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:51:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:51:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:53:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:53:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:53:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:53:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:53:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:58:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:58:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:58:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:58:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:58:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:59:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:59:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:59:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:59:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T01:59:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:00:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:00:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:00:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:00:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:00:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:01:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:01:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:01:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:01:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:02:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:06:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:06:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:06:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:06:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:07:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:07:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:07:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:07:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:07:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:08:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:08:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:08:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:08:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:08:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:08:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:13:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:13:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:13:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:13:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:13:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:18:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:18:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:18:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:18:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:18:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:23:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:23:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:23:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:23:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:24:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:25:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:25:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:25:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:25:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:25:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:26:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:26:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:26:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:26:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:26:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:29:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:29:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:29:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:29:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:29:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:34:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:34:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:34:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:34:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:34:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:37:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:37:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:37:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:37:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:38:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:41:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:41:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:41:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:41:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:41:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:43:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:43:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:43:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:43:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:43:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:44:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:44:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:44:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:44:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:44:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:45:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:45:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:45:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:45:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:45:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:50:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:50:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:50:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:50:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:50:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:51:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:51:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:51:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:51:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:52:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:53:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:53:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:53:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:53:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:54:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:54:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:54:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:54:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:54:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:55:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:57:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:57:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:57:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:57:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T02:57:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:00:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:00:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:00:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:00:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:00:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:01:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:01:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:01:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:01:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:02:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:04:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:04:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:04:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:04:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:05:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:06:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:06:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:06:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:06:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:06:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:11:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:11:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:11:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:11:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:12:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:14:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:14:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:14:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:14:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:14:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:19:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:19:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:19:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:19:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:19:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:21:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:21:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:21:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:21:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:22:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:24:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:24:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:24:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:24:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:24:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:28:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:28:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:28:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:28:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:29:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:31:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:31:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:31:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:31:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:31:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:34:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:34:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:34:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:34:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:34:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:38:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:38:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:38:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:38:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:39:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:41:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:41:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:41:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:41:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:42:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:42:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:42:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:42:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:42:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:43:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:43:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:43:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:43:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:43:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:43:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:48:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:48:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:49:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:49:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:49:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:52:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:52:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:52:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:52:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T03:53:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:17:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:17:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:17:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:17:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:17:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:20:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:20:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:20:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:20:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:21:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:26:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:26:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:26:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:26:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:26:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:29:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:29:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:29:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:29:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:29:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:32:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:32:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:32:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:32:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:32:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:35:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:35:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:35:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:35:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:35:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:39:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:39:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:39:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:39:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:39:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:40:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:40:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:40:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:40:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T04:56:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T09:01:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T09:01:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T09:01:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T09:01:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T09:18:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T12:07:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T12:07:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T12:07:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T12:07:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T12:07:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T13:19:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T13:19:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T13:19:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T13:19:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T13:28:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T16:50:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T16:50:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T16:50:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T16:50:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T17:41:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T18:27:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026/06/15 02:43:58 http2: server: error reading preface from client 198.41.200.53:7844: read tcp 192.168.0.106:61011->198.41.200.53:7844: read: connection reset by peer
+2026-06-14T18:43:58Z INF Lost connection with the edge connIndex=0
+2026-06-14T18:43:58Z ERR Serve tunnel error error="connection with edge closed" connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T18:43:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-14T19:00:34Z ERR Connection terminated error="connection with edge closed" connIndex=0
+2026-06-15T02:14:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:14:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:14:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:14:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:15:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:18:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:18:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:18:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:18:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:18:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:22:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:22:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:22:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:22:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:22:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:23:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:23:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:23:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:23:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:23:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:25:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:25:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:25:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:25:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:25:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:26:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:26:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:26:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:26:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:26:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:30:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:30:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:30:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:30:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:30:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:34:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:34:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:34:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:34:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:35:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:35:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:35:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:35:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:35:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:36:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:40:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:40:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:40:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:40:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:41:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:41:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:41:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:41:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:41:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:42:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:43:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:43:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:43:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:43:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:43:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:44:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:44:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:44:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:44:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:44:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:45:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:45:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:45:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:45:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:45:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:47:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:47:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:47:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:47:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:48:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:49:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:49:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:49:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:49:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:49:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:50:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:50:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:50:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:50:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:51:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:55:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:55:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:55:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:55:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:56:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:56:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:56:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:56:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:56:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:56:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:59:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:59:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:59:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T02:59:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:00:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:01:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:01:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:01:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:01:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:01:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:02:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:02:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:02:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:02:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:02:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:07:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:07:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:07:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:07:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:07:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:10:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:10:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:10:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:10:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:10:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:13:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:13:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:13:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:13:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:14:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:17:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:17:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:17:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:17:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:17:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:18:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:18:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:18:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:18:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:18:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:20:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:20:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:20:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:20:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:20:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:21:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:21:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:21:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:21:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:21:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:24:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:24:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:24:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:24:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:25:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:25:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:25:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:25:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:25:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:26:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:29:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:29:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:29:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:29:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:29:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:30:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:30:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:30:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:30:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:30:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:33:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:33:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:33:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:33:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:33:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:36:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:36:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:36:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:36:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:36:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:37:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:37:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:37:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:37:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:37:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:41:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:41:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:41:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:41:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:42:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:47:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:47:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:47:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:47:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:47:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:49:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:49:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:49:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:49:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:49:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:50:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:50:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:50:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:50:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:50:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:52:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:52:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:52:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:52:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:52:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:54:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:54:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:54:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:54:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:55:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:59:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:59:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:59:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:59:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T03:59:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:01:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:01:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:01:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:01:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:01:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:03:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:03:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:03:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:03:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:03:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:05:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:05:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:05:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:05:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:05:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:07:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:07:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:07:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:07:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:08:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:11:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:11:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:11:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:11:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:11:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:13:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:13:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:13:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:13:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:13:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:16:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:16:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:16:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:16:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:16:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:18:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:18:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:18:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:18:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:19:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:19:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:19:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:19:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:19:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:20:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:21:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:21:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:21:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:21:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:21:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:24:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:24:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:24:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:24:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:24:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:25:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:25:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:25:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:25:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:25:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:29:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:29:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:29:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:29:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:29:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:31:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:31:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:31:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:31:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:32:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:35:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:35:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:35:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:35:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:35:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:36:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:36:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:36:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:36:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:36:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:39:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:39:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:39:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:39:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:40:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:43:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:43:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:43:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:43:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:43:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:48:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:48:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:48:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:48:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:48:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:49:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:49:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:49:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:49:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:50:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:53:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:53:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:53:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:53:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:54:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:55:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:55:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:55:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:55:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:56:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:59:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:59:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:59:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:59:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T04:59:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:03:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:03:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:03:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:03:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:04:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:08:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:08:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:08:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:08:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:08:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:11:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:11:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:11:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:11:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:11:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:16:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:16:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:16:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:16:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:16:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:20:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:21:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:21:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:21:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:21:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:22:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:22:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:22:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:22:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:22:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:27:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:27:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:27:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:27:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:27:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:32:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:32:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:32:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:32:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:32:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:36:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:36:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:36:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:36:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:36:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:38:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:38:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:38:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:38:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:39:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:42:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:42:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:42:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:42:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:42:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:44:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:44:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:44:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:44:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:45:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:46:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:46:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:46:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:46:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:46:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:47:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:47:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:47:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:47:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:47:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:48:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:48:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:48:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:48:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:49:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:49:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:49:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:49:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:49:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:50:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:54:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:54:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:54:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:54:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T05:54:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:00:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:00:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:00:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:00:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:00:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:02:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:03:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:03:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:03:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:03:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:06:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:06:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:06:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:06:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:07:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:11:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:11:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:11:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:11:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:11:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:15:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:15:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:15:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:15:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:15:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:19:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:19:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:19:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:19:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:19:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:21:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:21:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:21:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:21:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:21:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:22:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:22:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:22:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:22:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:22:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:24:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:24:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:24:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:24:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:25:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:28:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:28:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:28:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:28:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:28:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:29:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:29:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:29:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:29:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:29:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:33:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:33:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:33:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:33:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:33:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:37:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:37:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:37:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:37:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:37:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:42:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:42:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:42:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:42:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:42:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:44:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:44:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:44:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:44:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:45:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:47:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:47:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:47:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:47:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:47:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:49:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:49:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:49:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:49:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:50:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:54:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:54:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:54:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:54:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:54:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:57:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:57:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:57:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:57:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:57:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:59:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:59:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:59:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T06:59:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:00:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:02:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:02:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:02:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:02:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:02:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:05:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:05:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:05:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:05:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:05:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:06:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:06:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:06:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:06:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:06:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:07:39Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:07:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:07:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:07:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:08:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:08:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:08:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:08:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:08:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:08:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:12:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:12:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:12:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:12:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:13:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:14:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:14:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:14:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:14:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:14:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:17:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:17:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:17:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:17:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:17:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:22:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:22:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:22:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:22:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:22:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:24:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:24:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:24:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:24:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:24:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:28:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:28:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:28:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:28:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:28:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:31:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:31:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:31:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:31:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:32:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:33:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:33:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:33:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:33:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:33:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:35:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:35:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:35:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:35:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:35:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:38:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:38:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:38:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:38:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:39:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:43:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:43:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:43:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:43:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:43:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:46:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:46:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:46:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:46:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.53
+2026-06-15T07:46:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+ from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:45:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:45:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:46:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:46:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:46:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:46:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:46:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:48:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:48:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:48:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:48:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:48:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:52:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:52:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:52:02Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:52:02Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:52:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:57:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:57:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:57:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T18:57:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T18:57:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T18:59:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:00:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:00:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:00:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:00:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:04:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:04:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:04:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:04:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:04:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:06:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:06:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:06:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:06:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:06:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:11:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:11:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:11:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:11:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:11:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:11:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:11:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:11:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:11:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:12:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:16:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:16:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:16:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:16:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:17:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:20:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:20:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:20:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:20:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:20:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:21:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:21:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:21:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:21:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:21:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:26:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:26:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:26:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:26:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:26:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:29:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:29:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:29:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:29:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:29:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:30:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:30:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:30:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:30:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:30:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:34:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:34:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:34:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:34:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:35:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:36:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:36:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:36:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:36:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:37:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:40:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:40:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:40:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:40:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:41:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:45:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:45:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:45:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:45:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:46:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:48:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:48:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:48:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:48:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:49:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:51:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:51:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:51:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:51:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:51:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T19:56:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:56:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T19:56:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:56:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T19:56:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:01:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:01:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:01:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:01:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:01:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:03:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:03:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:03:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:03:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:04:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:06:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:06:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:06:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:06:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:07:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:10:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:10:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:10:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:10:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:11:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:15:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:15:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:15:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:15:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:15:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:17:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:17:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:17:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:17:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:18:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:19:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:19:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:19:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:19:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:19:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:24:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:24:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:24:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:24:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:24:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:29:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:29:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:29:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:29:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:29:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:30:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:30:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:30:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:30:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:30:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:33:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:33:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:33:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:33:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:34:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:35:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:35:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:35:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:35:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:36:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:39:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:39:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:39:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:39:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:40:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:44:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:44:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:44:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:44:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:44:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:49:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:49:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:49:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:49:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:49:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:53:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:53:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:53:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:53:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:53:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T20:55:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:55:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T20:55:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:55:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T20:55:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:00:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:00:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:00:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:00:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:00:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:05:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:05:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:05:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:05:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:05:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:08:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:08:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:08:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:08:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:08:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:10:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:10:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:10:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:10:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:10:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:13:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:13:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:13:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:13:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:13:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:16:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:16:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:16:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:16:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:16:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:20:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:20:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:20:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:20:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:21:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:26:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:26:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:26:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:26:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:27:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:28:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:28:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:28:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:28:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:28:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:32:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:32:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:32:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:32:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:33:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:34:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:34:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:34:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:34:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:34:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:35:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:35:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:35:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:35:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:35:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:36:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:36:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:36:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:36:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:37:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:37:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:37:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:37:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:37:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:37:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:39:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:39:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:39:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:39:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:39:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:42:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:42:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:42:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:42:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:43:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:45:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:45:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:45:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:45:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:45:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:47:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:47:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:47:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:47:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:48:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:50:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:50:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:50:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:50:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:50:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:53:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:53:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:53:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:53:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:53:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:54:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:54:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:54:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:54:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:54:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T21:55:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:55:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T21:55:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:55:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T21:55:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:00:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:00:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:00:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:00:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:00:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:03:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:03:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:03:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:03:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:04:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:06:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:06:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:06:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:06:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:06:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:11:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:11:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:11:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:11:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:11:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:15:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:15:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:15:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:15:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:15:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:19:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:19:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:19:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:19:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:20:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:20:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:20:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:20:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:20:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:20:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:21:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:21:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:21:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:21:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:22:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:25:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:25:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:25:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:25:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:26:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:28:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:28:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:28:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:28:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:28:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:33:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:33:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:33:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:33:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:33:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:36:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:36:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:36:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:36:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:36:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:37:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:37:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:37:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:37:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:37:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:41:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:41:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:41:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:41:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:41:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:46:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:46:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:46:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:46:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:46:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:50:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:50:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:50:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:50:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:50:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:55:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:55:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:55:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:55:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:55:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T22:57:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:57:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T22:57:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:57:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T22:58:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:03:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:03:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:03:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:03:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:03:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:04:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:04:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:04:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:04:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:04:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:07:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:07:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:07:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:07:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:08:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:13:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:13:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:13:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:13:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:13:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:14:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:14:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:14:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:14:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:14:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:16:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:16:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:16:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:16:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:17:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:20:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:20:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:20:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:20:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:20:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:21:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:21:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:21:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:21:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:22:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:24:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:24:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:24:44Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:24:44Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:25:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:25:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:26:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:26:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:26:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:26:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:27:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:27:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:27:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:27:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:28:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:30:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:30:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:30:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:30:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:31:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:35:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:35:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:35:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:35:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:35:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:37:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:37:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:37:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:37:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:37:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:40:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:40:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:40:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:40:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:40:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:40:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:40:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:40:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:40:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:41:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:41:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:41:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:41:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:41:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:41:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:43:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:43:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:43:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:43:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:43:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:46:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:46:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:46:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:46:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:46:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:49:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:49:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:49:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:49:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:50:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:54:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:54:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:54:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:54:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:54:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:57:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:57:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:57:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:57:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:58:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-13T23:59:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:59:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-13T23:59:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-13T23:59:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:00:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:03:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:03:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:03:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:03:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:03:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:05:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:05:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:05:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:05:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:05:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:08:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:08:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:08:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:08:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:08:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:09:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:09:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:09:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:09:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:09:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:10:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:10:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:10:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:10:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:10:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:13:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:13:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:13:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:13:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:13:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:16:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:16:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:16:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:16:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:17:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:17:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:17:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:17:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:17:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:17:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:18:18Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:18:19Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:18:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:18:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:18:34Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:19:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:19:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:19:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:19:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:19:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:21:20Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:21:21Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:21:21Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:21:21Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:21:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:24:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:24:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:24:28Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:24:28Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:24:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:25:42Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:25:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:25:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:25:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:26:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:28:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:28:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:28:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:28:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:29:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:34:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:34:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:34:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:34:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:34:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:35:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:35:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:35:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:35:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:35:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:41:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:41:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:41:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:41:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:41:22Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:44:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:44:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:44:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:44:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:44:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:46:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:46:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:46:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:46:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:46:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:48:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:48:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:48:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:48:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:49:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:54:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:54:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:54:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:54:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:54:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T00:59:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:59:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T00:59:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:59:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T00:59:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:00:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:00:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:00:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:00:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:01:15Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:04:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:04:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:04:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:04:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:05:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:08:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:08:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:08:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:08:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:08:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:10:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:10:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:10:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:10:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:11:10Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:15:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:15:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:15:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:15:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:15:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:20:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:20:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:20:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:20:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:20:39Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:25:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:25:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:25:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:25:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:25:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:30:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:30:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:30:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:30:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:30:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:32:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:32:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:32:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:32:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:32:46Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:35:26Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:35:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:35:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:35:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:35:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:40:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:40:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:40:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:40:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:41:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:43:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:43:27Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:43:27Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:43:27Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:43:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:47:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:47:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:47:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:47:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:47:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:48:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:48:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:48:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:48:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:48:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:53:45Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:53:46Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:53:46Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:53:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:54:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:55:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:55:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:55:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:55:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:56:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T01:58:54Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:58:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T01:58:56Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:58:56Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T01:59:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:01:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:01:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:01:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:01:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:01:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:05:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:05:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:05:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:05:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:05:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:05:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:05:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:05:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:05:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:06:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:08:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:08:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:08:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:08:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:08:32Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:11:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:11:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:11:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:11:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:11:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:14:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:14:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:14:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:14:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:14:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:15:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:15:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:15:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:15:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:16:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:16:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:16:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:16:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:16:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:16:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:20:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:20:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:20:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:20:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:20:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:24:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:24:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:24:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:24:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:24:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:26:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:26:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:26:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:26:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:26:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:29:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:29:28Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:29:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:29:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:29:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:33:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:33:55Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:33:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:33:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:34:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:35:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:35:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:35:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:35:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:36:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:41:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:41:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:41:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:41:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:41:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:43:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:43:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:43:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:43:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:43:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:47:05Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:47:07Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:47:07Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:47:07Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:47:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:50:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:50:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:50:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:50:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:50:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:50:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:50:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:50:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:50:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:51:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:55:31Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:55:32Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:55:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:55:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:55:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T02:57:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:57:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T02:57:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:57:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T02:57:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:00:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:00:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:00:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:00:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:00:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:04:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:04:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:04:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:04:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:05:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:06:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:06:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:06:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:06:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:06:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:07:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:07:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:07:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:07:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:07:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:10:04Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:10:06Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:10:06Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:10:06Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:10:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:13:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:13:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:13:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:13:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:13:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:15:16Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:15:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:15:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:42Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:15:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:15:54Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:16:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:16:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:16:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:16:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:16:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:21:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:21:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:21:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:21:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:21:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:22:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:22:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:22:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:22:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:22:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:27:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:27:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:27:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:27:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:27:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:27:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:27:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:27:54Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:27:54Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:28:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:28:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:28:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:28:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:28:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:29:05Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:31:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:31:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:31:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:31:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:31:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:32:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:32:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:32:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:32:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:33:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:38:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:38:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:38:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:38:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:38:21Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:42:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:42:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:42:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:42:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:42:38Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:47:41Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:47:43Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:47:43Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:47:43Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:48:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:53:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:53:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:53:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:53:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:53:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T03:55:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:55:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T03:55:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:55:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T03:55:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:19:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:19:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:19:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:19:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:20:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:20:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:20:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:20:18Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:20:18Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:20:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:24:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:24:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:24:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:24:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:24:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:27:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:27:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:27:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:27:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:27:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:29:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:29:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:29:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:29:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:29:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:31:06Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:31:08Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:31:08Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:31:08Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:31:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:35:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:36:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:36:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:36:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:36:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:39:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:39:39Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:39:39Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:39:39Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:39:49Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:40:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:40:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T04:40:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:40:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T04:41:13Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T04:41:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T05:06:22Z ERR Unable to establish connection with Cloudflare edge error="TLS handshake with edge error: read tcp 192.168.0.106:57168->198.41.200.63:7844: i/o timeout" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T05:06:22Z ERR Serve tunnel error error="TLS handshake with edge error: read tcp 192.168.0.106:57168->198.41.200.63:7844: i/o timeout" connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T05:06:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.63
+2026-06-14T05:38:04Z ERR Connection terminated error="TLS handshake with edge error: read tcp 192.168.0.106:57168->198.41.200.63:7844: i/o timeout" connIndex=0
+2026-06-14T09:01:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T09:01:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T09:01:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T09:01:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T09:01:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T12:07:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T12:07:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T12:07:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T12:07:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T12:41:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-14T16:33:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T16:33:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-14T16:33:42Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T16:33:42Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-14T16:33:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:13:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:13:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:13:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:13:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:14:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:18:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:18:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:18:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:18:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:19:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:21:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:21:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:21:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:21:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:21:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:26:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:26:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:26:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:26:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:26:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:27:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:27:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:27:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:27:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:27:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:30:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:30:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:30:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:30:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:30:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:34:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:34:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:34:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:34:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:35:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:37:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:37:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:37:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:37:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:38:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:41:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:41:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:41:49Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:41:49Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:42:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:45:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:45:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:45:52Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:45:52Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:46:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:46:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:46:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:46:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:46:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:46:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:48:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:48:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:48:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:48:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:48:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:49:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:49:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:49:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:49:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:49:42Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:50:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:50:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:50:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:50:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:50:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T02:54:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:54:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T02:54:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:54:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T02:54:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:00:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:00:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:00:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:00:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:00:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:04:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:04:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:04:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:04:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:04:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:08:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:08:15Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:15Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:08:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:08:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:08:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:13:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:13:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:13:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:13:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:13:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:17:07Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:17:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:17:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:17:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:17:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:19:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:19:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:19:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:19:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:19:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:23:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:23:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:23:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:23:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:23:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:26:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:26:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:26:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:26:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:27:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:29:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:29:15Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:29:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:29:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:29:33Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:34:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:34:25Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:34:25Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:34:25Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:34:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:35:27Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:35:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:35:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:35:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:35:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:40:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:40:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:40:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:40:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:40:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:41:12Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:41:13Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:41:13Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:41:13Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:41:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:45:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:45:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:45:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:45:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:46:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:48:00Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:48:01Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:48:01Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:48:01Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:48:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:53:23Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:53:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:53:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:53:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:53:51Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T03:58:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:58:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T03:58:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:58:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T03:59:18Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:00:47Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:00:48Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:00:48Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:00:48Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:00:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:05:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:05:11Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:05:11Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:05:11Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:05:23Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:10:19Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:10:20Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:10:20Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:10:20Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:10:45Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:11:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:11:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:11:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:11:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:11:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:14:40Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:14:41Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:14:41Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:14:41Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:15:11Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:17:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:17:17Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:17:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:17:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:17:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:20:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:20:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:20:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:20:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:20:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:22:17Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:22:18Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:22:19Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:22:19Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:22:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:26:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:26:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:26:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:26:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:26:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:27:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:27:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:27:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:27:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:28:07Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:29:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:29:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:29:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:29:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:29:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:30:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:30:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:30:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:30:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:30:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:35:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:35:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:35:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:35:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:35:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:39:44Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:39:45Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:39:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:39:46Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:40:00Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:43:25Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:43:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:43:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:43:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:43:56Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:45:29Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:45:30Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:45:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:45:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:46:01Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:50:10Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:50:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:50:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:50:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:50:17Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:51:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:51:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:51:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:51:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:51:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:54:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:54:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:54:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:54:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:55:04Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T04:57:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:57:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T04:57:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:57:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T04:58:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:03:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:03:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:03:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:03:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:03:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:07:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:07:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:07:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:07:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:07:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:08:55Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:08:56Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:08:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:08:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:09:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:14:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:14:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:14:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:14:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:14:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:16:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:16:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:16:37Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:16:37Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:17:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:22:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:22:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:22:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:22:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:22:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:24:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:24:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:24:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:24:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:24:41Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:28:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:28:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:28:32Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:28:32Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:28:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:32:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:32:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:32:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:32:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:33:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:34:48Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:34:49Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:34:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:34:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:34:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:35:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:35:09Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:09Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:29Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:35:32Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:33Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:35:33Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:33Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:35:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:36:30Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:36:31Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:36:31Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:36:31Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:37:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:41:52Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:41:53Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:41:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:41:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:41:58Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:46:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:46:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:46:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:46:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:46:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:50:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:50:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:51:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:51:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:51:24Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:54:35Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:54:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:54:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:54:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:54:44Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:55:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:55:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:55:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:55:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:55:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:57:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:57:30Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:30Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T05:57:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:35Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T05:57:35Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:35Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T05:57:40Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:02:58Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:02:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:02:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:02:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:03:12Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:03:36Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:03:37Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:03:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:03:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:03:53Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:07:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:07:04Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:07:04Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:07:04Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:07:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:10:34Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:10:36Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:10:36Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:10:36Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:11:06Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:11:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:11:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:11:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:11:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:11:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:13:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:13:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:13:22Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:13:22Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:13:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:18:11Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:18:12Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:18:12Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:18:12Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:18:36Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:23:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:23:02Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:23:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:23:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:23:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:24:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:25:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:25:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:25:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:25:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:27:49Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:27:50Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:27:50Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:27:50Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:28:14Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:32:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:32:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:32:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:32:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:32:52Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:33:03Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:33:05Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:33:05Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:33:05Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:33:28Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:35:56Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:35:57Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:35:57Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:35:57Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:36:09Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:40:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:40:58Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:40:58Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:40:58Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:41:26Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:43:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:43:23Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:43:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:43:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:43:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:48:01Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:48:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:48:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:48:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:48:16Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:51:13Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:51:14Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:51:14Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:51:14Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:51:43Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:54:15Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:54:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:54:17Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:54:17Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:54:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:58:21Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:22Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:58:23Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:23Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:35Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:58:51Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:52Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:58:53Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:53Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:58:57Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T06:59:22Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:59:24Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T06:59:24Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:59:24Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T06:59:25Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:02:59Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:03:00Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:03:00Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:03:00Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:03:03Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:06:38Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:06:40Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:06:40Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:06:40Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:07:08Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:09:50Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:09:51Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:09:51Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:09:51Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:10:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:13:43Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:13:44Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:13:45Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:13:45Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:14:02Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:16:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:16:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:16:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:16:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:17:30Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:19:28Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:19:29Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:19:29Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:19:29Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:19:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:20:09Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:20:10Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:20:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:20:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:20:27Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:24:33Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:24:34Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:24:34Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:24:34Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:24:48Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:29:08Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:29:09Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:29:10Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:29:10Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:29:20Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:30:57Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:30:59Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:30:59Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:30:59Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:31:19Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:33:37Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:33:38Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:33:38Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:33:38Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:33:47Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:34:14Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:34:16Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:34:16Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:34:16Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:34:37Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:36:53Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:36:54Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:36:55Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:36:55Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:36:55Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:40:24Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:40:26Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:40:26Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:40:26Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:40:50Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:41:46Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:41:47Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:41:47Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:41:47Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:41:59Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0
+2026-06-15T07:46:02Z INF Tunnel connection curve preferences: [X25519MLKEM768 CurveID(65074) CurveP256] connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:46:03Z ERR failed to serve incoming request error="Unauthorized: Tunnel not found"
+2026-06-15T07:46:03Z ERR Register tunnel error from server side error="Unauthorized: Tunnel not found" connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:46:03Z INF Retrying connection in up to 1m4s connIndex=0 event=0 ip=198.41.200.73
+2026-06-15T07:46:31Z ERR Connection terminated error="Unauthorized: Tunnel not found" connIndex=0

+ 1 - 0
examples/process_pipeline/script/search_eval/mode_procedure/.cloudflared.pid

@@ -0,0 +1 @@
+86090

+ 132 - 0
examples/process_pipeline/script/search_eval/mode_procedure/README.md

@@ -0,0 +1,132 @@
+# mode_procedure · 新模式 + 直写版工序解构
+
+> 自包含文件夹,跑「new 模式界面 + procedure 直写版工序解构」。
+> 打法同 `fixed_query_eval`:**引擎全复用父目录 `search_eval/` 原件,本目录只放改造后的 server + 前端**。
+
+---
+
+## 这是什么
+
+把 `search_eval/server.py --mode new` + `run_cyber.py --skill procedure` 这一套固化进一个文件夹:
+- **new 模式**:读写 `runs_new/`、前端用 `new_query.html`、query 用自由中文名(非 q0000)。
+- **procedure 直写版**:工序解构走 `run_cyber.py --skill procedure`(读 `procedure-dsl/procedure/SKILL.md`,强模型一次 write 出 `workflow.json`),而不是默认的 spec 三阶段版。
+
+完整原理分析见同目录 `mode_procedure_分析.md`。
+
+**想改提取逻辑/词表**:直接改 `procedure-dsl/procedure/SKILL.md`(提取规范+内嵌词表)、`procedure-dsl/procedure/tools/vocab.py`(合法词表)、`validate.py`(校验规则)——都是本地副本,改完即生效,不碰别人那份。
+
+---
+
+## 文件结构
+
+```
+mode_procedure/
+├── server.py        ← 后端枢纽(new 模式 + 双引擎接线 + 版本/DB + procedure_versions)
+├── new_query.html   ← 前端操作台(两个工序子 tab + 版本下拉)
+├── db.py            ← 共享持久层:agent_dsl / mode_dsl 双表(每版本一行)
+├── procedure-dsl/   ← ★ 【Agent 工序】引擎(run_cyber 直写版 + 渲染器)
+│   ├── run_cyber.py / run_procedure_dsl.py / plan_tool.py
+│   ├── procedure/            直写版 skill(SKILL.md + tools/{validate,wf-patch,render,vocab}.py)
+│   └── spec/                 渲染基础设施(renderer.py + taxonomy,两种工序共用)
+├── mode-dsl/        ← ★ 【大模型工序】全部(与 procedure-dsl 并列)
+│   ├── procedure_model_extract.py   单帖:一次大模型直出 workflow.json + 渲染
+│   ├── batch_model_extract.py       批量:一个 query 全部帖 + 写 mode_dsl
+│   └── prompts/procedure_extract_system.md   提取 prompt(可单独迭代)
+├── runs_new/        ← 产出目录(每个 query 一个中文名子目录;含 _model/ + history/)
+├── mode_procedure_分析.md   ← 原理分析
+└── README.md
+```
+
+> **`procedure-dsl/`(Agent 工序)vs `mode-dsl/`(大模型工序)** 是两条并列的提取引擎;`db.py` / `server.py` / `new_query.html` / `runs_new/` 是两者共享。大模型工序的渲染复用 `procedure-dsl/` 的 render.py + spec/renderer(不重复造)。
+
+**两类依赖,分清楚:**
+- **工序提取引擎 → 本地副本**(`mode_procedure/procedure-dsl/`):`run_cyber.py` + 依赖 + `procedure/` 直写 skill。**这套是你的,随便改**(改 SKILL.md / 词表 / 校验规则都行),不影响 `../procedure-dsl/` 那份共享的。
+- **搜索 / 评分 / 重评 → 复用父目录 `../`**(不复制):`search_and_evaluate.py`、`batch_3forms.py`、`build_workflows.py`、`batch_extract_procedures.py`、`evaluation/`(taxonomy)。
+
+> **`spec/` 也复制了**(不是为了那个「三阶段」skill,而是 **`procedure/tools/render.py` 渲染 HTML 时复用 `spec/tools/renderer.py` + `spec/taxonomy/`**)。不复制 spec/ 的话,workflow.json 能生成但**最后渲染 HTML 会失败** → 界面看不到结果。你不用改 spec/,它只是渲染基础设施。
+>
+> 前端「Claude SDK」引擎在本目录可用(spec/ 已在),但本目录定位是 `cyber_runner` + `procedure` 直写版。
+
+> **cwd 说明**:server 起 run_cyber 时把 cwd 设成 `procedure-dsl/`(run_cyber 假设的工作目录),否则 agent 找 `procedure/SKILL.md` 会瞎试浪费回合。
+
+---
+
+## 相对原版 server.py 的改造(5 处)
+
+| # | 改动 | 说明 |
+|---|------|------|
+| 1 | `MODE = "new"` 写死、端口默认 8771 | 不用再传 `--mode new` |
+| 2 | `SE = HERE.parent` + `sys.path.insert(SE)` | 复用兄弟模块 `batch_extract_procedures` / `build_workflows` |
+| 3 | 所有引擎脚本/`procedure-dsl` 路径 `HERE/…` → `SE/…` | 引擎在父目录 search_eval |
+| 4 | 4 个 subprocess 的 `cwd=str(HERE)` → `str(SE)` | 与原版运行目录一致 |
+| 5 | 两处 run_cyber 命令加 `--skill procedure` | 用直写版 skill(单帖 + 批量) |
+
+> `EVALDIR` 靠原有 fallback 自动落到 `search_eval/evaluation`(taxonomy),无需改。
+
+---
+
+## 怎么跑
+
+```bash
+cd examples/process_pipeline/script/search_eval/mode_procedure
+python server.py            # 默认 8771,写死 new 模式
+# 浏览器开 http://0.0.0.0:8771
+```
+
+界面流程(new_query.html):
+1. 选维度/输自由 query + 勾平台 → 「搜索并评估」→ `runs_new/{query}/form_A.json`
+2. 看帖卡片 → 单帖「生成工序」或「批量生成工序」→ `run_cyber.py --skill procedure` → `procedures/{folder}/workflow.json` + `case-*.html`
+3. 可「重新评估」
+
+**模型**:工序提取默认 `google/gemini-3.1-flash-lite`(界面可改)。
+> 注意:procedure 直写版 SKILL 较复杂,gemini-flash-lite 可能一次写不全;要质量更稳可在界面切强模型(如 `anthropic/claude-sonnet-4.6`)。
+
+---
+
+## 详情页两种工序提取方式(分两个子 tab)
+
+帖子详情「对应工序」下分 **🛠️ Agent 工序** / **⚡ 大模型工序** 两个子 tab,**各自独立显示结果、互不覆盖**:
+
+- 存储分离:Agent → `procedures/{folder}/`;大模型 → `procedures/{folder}/_model/`(各有自己的 workflow.json / case-*.html / _extract.log)。
+- 状态/日志接口加了 `variant=agent|model` 参数路由到对应目录;`task_key` 用 `{q}/{folder}` vs `{q}/{folder}/_model` 区分。
+- 切到某个子 tab 就触发该方式的提取按钮 + 显示该方式的结果。
+
+两种提取方式:
+
+| 按钮 | 走什么 | 流程 | 特点 |
+|------|--------|------|------|
+| **开始提取工序** | `run_cyber.py --skill procedure`(agent) | 读 SKILL.md → 写 → validate 校验 → 修 → 渲染 | 多轮、有自我校验修错,质量稳,慢/贵 |
+| **🤖 模型提取** | `mode-dsl/procedure_model_extract.py`(单次大模型) | 一次大模型调用(帖子文本+配图 → workflow.json)→ 渲染 | 无 agent / 无 validate 循环,快/便宜(~$0.004),不保证字段全合规 |
+
+**大模型工序相关全部在 `mode-dsl/`**(与 Agent 引擎 `procedure-dsl/` 并列):
+- `mode-dsl/prompts/procedure_extract_system.md` — 提取 prompt(可单独迭代,不动代码)
+- `mode-dsl/procedure_model_extract.py` — 单次多模态调用 → workflow.json → 复用 `../procedure-dsl` 的 render.py 出 HTML
+- `mode-dsl/batch_model_extract.py` — 批量:一个 query 下所有帖逐个跑 + 写 `mode_dsl` 表
+- server `/api/extract_procedure_model` 端点 + `run_model_extraction_task`(调 `mode-dsl/procedure_model_extract.py`)
+- new_query.html 「🤖 模型提取」按钮 + `startModelExtraction()`
+
+模型默认 `gemini-3.1-flash-lite`,用详情页「AI 模型」下拉选中的模型。两个按钮都复用同一套 `procedure_status` / 日志 / 版本 / 展示逻辑。
+
+### 持久化 + 版本
+- `db.py`(根目录,共享):`agent_dsl` / `mode_dsl` 两张表,每帖每版本一行(`version = v_月日时分`,保留历史)。`python db.py init` 建表。
+- 每次重新生成 → 新版本写 DB + `_meta.json`,旧版本进 `history/{版本}/`;详情页「重新生成」旁的版本下拉可切换历史版本。
+
+---
+
+## 依赖
+
+同 `fixed_query_eval`:需 `pip install -e '.[browser,server,feishu]'` + `Pillow`/`filelock`(`run_cyber` 触发 `agent.tools.builtin` 全链)。`server.py` 本身轻量(提取走 subprocess),缺这些也能起、能看已有产出。
+
+环境变量:`OPEN_ROUTER_API_KEY`(提取/评分/OCR 都走 OpenRouter)。
+
+---
+
+## 已验证
+
+- ✅ server 启动、服务 new_query.html、`/api/data` 正常、矩阵从 `search_eval/evaluation` 加载
+- ✅ `from batch_extract_procedures` / `import build_workflows` 从 `SE` 解析成功
+- ✅ `/api/generate_procedure` 触发 → `run_cyber.py --skill procedure` 正确启动(OCR 配图、调 OpenRouter 200、无路径错误)
+
+---
+
+*实现:复制 ../server.py + ../new_query.html + ../procedure-dsl 的工序提取引擎(run_cyber/run_procedure_dsl/plan_tool/procedure)。server 改造:写死 new 模式 + 工序引擎指本地 procedure-dsl + 搜索/重评仍指父目录 + run_cyber 加 --skill procedure。引擎是 DSL_ROOT 自相对路径,复制后内部无需改。*

+ 191 - 0
examples/process_pipeline/script/search_eval/mode_procedure/db.py

@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+"""mode_procedure · MySQL 持久化(工序解构结果双写:本地文件 + 数据库)
+================================================================================
+
+读 .env 的 MYSQL_* 连接 MySQL(pymysql)。两张表,结构相同:
+  agent_dsl —— Agent 工序解构结果(run_cyber,每版本一行)
+  mode_dsl  —— 大模型工序解构结果(单次大模型直出,每版本一行)
+
+设计原则(沿用 fixed_query_eval/db.py):
+- **失败不阻断**:写库 try/except 包,DB 挂了不影响本地文件(文件是主存储)。
+- **保留历史**:(q, case_id, version) 每版本一行;同版本重跑先删本版本再插(幂等)。
+- workflow.json 嵌套深(procedures→steps→io),整份存 LONGTEXT,不拆关系行。
+建表:跑 `python db.py init`。
+"""
+import os
+import json
+import sys
+from pathlib import Path
+from datetime import datetime
+
+PROJECT_ROOT = Path(__file__).resolve().parents[5]
+sys.path.insert(0, str(PROJECT_ROOT))
+
+from dotenv import load_dotenv
+load_dotenv()
+
+try:
+    import pymysql
+    from pymysql.cursors import DictCursor
+except ImportError:
+    pymysql = None
+
+TABLES = ("agent_dsl", "mode_dsl")   # 白名单:表名不能用占位符,必须校验
+
+
+def _enabled() -> bool:
+    return pymysql is not None and bool(os.getenv("MYSQL_HOST"))
+
+
+def _conn():
+    return pymysql.connect(
+        host=os.getenv("MYSQL_HOST"),
+        port=int(os.getenv("MYSQL_PORT", 3306)),
+        user=os.getenv("MYSQL_USER"),
+        password=os.getenv("MYSQL_PASSWORD"),
+        database=os.getenv("MYSQL_DATABASE"),
+        charset="utf8mb4",
+        cursorclass=DictCursor,
+        autocommit=True,
+        connect_timeout=10,
+    )
+
+
+# ── DDL ──────────────────────────────────────────────────────────────────────
+
+def _ddl(table, comment):
+    return f"""
+CREATE TABLE IF NOT EXISTS {table} (
+  id              BIGINT AUTO_INCREMENT PRIMARY KEY,
+  q               VARCHAR(255)  NOT NULL COMMENT 'query 目录名(自由中文)',
+  case_id         VARCHAR(128)  NOT NULL COMMENT 'platform_channelContentId',
+  platform        VARCHAR(32)   NULL,
+  post_title      VARCHAR(512)  NULL,
+  source_link     VARCHAR(1024) NULL,
+  model           VARCHAR(64)   NULL     COMMENT '提取模型',
+  version         VARCHAR(16)   NULL     COMMENT 'v_MMDDHHMM(每次生成;保留历史多版本共存)',
+  procedure_count INT           NULL     COMMENT '工序数',
+  workflow_json   LONGTEXT      NULL     COMMENT '整份 workflow.json',
+  source_json     LONGTEXT      NULL     COMMENT '_source.json(喂给模型的帖子源)',
+  created_time    VARCHAR(64)   NULL,
+  KEY idx_q_case_ver (q(128), case_id, version)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{comment}';
+"""
+
+
+def init_tables():
+    """建表(幂等)。"""
+    if not _enabled():
+        print("⚠️ MySQL 未启用(缺 pymysql 或 MYSQL_HOST),跳过建表")
+        return False
+    conn = _conn()
+    try:
+        with conn.cursor() as cur:
+            cur.execute(_ddl("agent_dsl", "Agent 工序解构结果(每版本一行)"))
+            cur.execute(_ddl("mode_dsl", "大模型工序解构结果(每版本一行)"))
+        print("✅ 建表完成:agent_dsl, mode_dsl")
+        return True
+    finally:
+        conn.close()
+
+
+# ── 写入 ─────────────────────────────────────────────────────────────────────
+
+def upsert_dsl(table, q, case_id, version, model, workflow, source=None,
+               platform=None, post_title=None, source_link=None):
+    """写入一帖某版本的工序解构结果。**保留历史**:只删本 (q,case_id,version) 旧行再插。
+    table 必须是 'agent_dsl' / 'mode_dsl'。失败返回 0(不阻断本地文件)。"""
+    if not _enabled():
+        return 0
+    if table not in TABLES:
+        raise ValueError(f"非法表名: {table}")
+    procs = (workflow or {}).get("procedures") or []
+    try:
+        conn = _conn()
+        try:
+            with conn.cursor() as cur:
+                cur.execute(f"DELETE FROM {table} WHERE q=%s AND case_id=%s AND version=%s",
+                            (q, case_id, version))
+                cur.execute(f"""
+                INSERT INTO {table}
+                  (q, case_id, platform, post_title, source_link, model, version,
+                   procedure_count, workflow_json, source_json, created_time)
+                VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
+                """, (
+                    q, case_id, platform, (post_title or "")[:500], source_link, model, version,
+                    len(procs),
+                    json.dumps(workflow, ensure_ascii=False) if workflow is not None else None,
+                    json.dumps(source, ensure_ascii=False) if source is not None else None,
+                    datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+                ))
+            return 1
+        finally:
+            conn.close()
+    except Exception as ex:
+        print(f"⚠️ {table} 写库失败(不影响本地文件):{ex}")
+        return 0
+
+
+# ── 读取 ─────────────────────────────────────────────────────────────────────
+
+def fetch_versions(table, q, case_id):
+    """列出某帖所有版本(DESC,最新在前)。返回 [{version, model, procedure_count, created_time}]。"""
+    if not _enabled() or table not in TABLES:
+        return []
+    try:
+        conn = _conn()
+        try:
+            with conn.cursor() as cur:
+                cur.execute(f"""SELECT version, model, procedure_count, created_time
+                                FROM {table} WHERE q=%s AND case_id=%s
+                                ORDER BY version DESC""", (q, case_id))
+                return list(cur.fetchall())
+        finally:
+            conn.close()
+    except Exception as ex:
+        print(f"⚠️ {table} 读版本失败:{ex}")
+        return []
+
+
+def fetch_dsl(table, q, case_id, version=None):
+    """取某帖某版本的 workflow(version=None 取最新)。返回 dict 或 None。"""
+    if not _enabled() or table not in TABLES:
+        return None
+    try:
+        conn = _conn()
+        try:
+            with conn.cursor() as cur:
+                if version:
+                    cur.execute(f"SELECT * FROM {table} WHERE q=%s AND case_id=%s AND version=%s",
+                                (q, case_id, version))
+                else:
+                    cur.execute(f"""SELECT * FROM {table} WHERE q=%s AND case_id=%s
+                                    ORDER BY version DESC LIMIT 1""", (q, case_id))
+                row = cur.fetchone()
+                if row and row.get("workflow_json"):
+                    row["workflow"] = _loads(row["workflow_json"])
+                return row
+        finally:
+            conn.close()
+    except Exception as ex:
+        print(f"⚠️ {table} 读取失败:{ex}")
+        return None
+
+
+def _loads(v, default=None):
+    if v is None:
+        return default
+    if isinstance(v, (list, dict)):
+        return v
+    try:
+        return json.loads(v)
+    except Exception:
+        return default
+
+
+if __name__ == "__main__":
+    cmd = sys.argv[1] if len(sys.argv) > 1 else "init"
+    if cmd == "init":
+        init_tables()
+    else:
+        print(f"用法: python db.py init")

+ 138 - 0
examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/batch_model_extract.py

@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+"""批量大模型工序提取
+================================================================================
+
+对一个 query 目录下 form_A.json 的所有帖子,逐个跑「大模型工序提取」(单次直出),
+产物写各帖的 _model/ 子目录,并写入数据库 mode_dsl 表(带版本号 v_MMDDHHMM)。
+
+与详情页「⚡ 大模型工序」走的是同一条路径(procedure_model_extract.py),只是批量 + 并发。
+
+用法:
+  python batch_model_extract.py "AI 信息 版面设计 图片 怎么做" --model google/gemini-3.5-flash --workers 4
+"""
+import argparse
+import json
+import subprocess
+import sys
+from concurrent.futures import ThreadPoolExecutor, as_completed
+from datetime import datetime
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent       # mode_procedure/mode-dsl/
+MP = HERE.parent                              # mode_procedure/(db.py、runs_new 在这)
+sys.path.insert(0, str(HERE))
+sys.path.insert(0, str(MP))                   # 复用 db
+sys.path.insert(0, str(MP.parent))            # 复用 batch_extract_procedures(search_eval)
+
+from batch_extract_procedures import _short_case, _source_to_dsl_input, _write_meta, _composite_score
+import db
+
+RUNS_DIR = MP / "runs_new"
+MODEL_EXTRACT = HERE / "procedure_model_extract.py"
+
+
+def _gen_version():
+    return "v_" + datetime.now().strftime("%m%d%H%M")
+
+
+def _read_meta_version(out_dir):
+    try:
+        return json.loads((out_dir / "_meta.json").read_text(encoding="utf-8")).get("version")
+    except Exception:
+        return None
+
+
+def _backup_history(out_dir):
+    """旧产物按版本号归档到 history/{旧版本}/。"""
+    if not out_dir.is_dir():
+        return
+    files = [f for f in out_dir.iterdir() if f.is_file()]
+    if not files:
+        return
+    import shutil
+    label = _read_meta_version(out_dir) or datetime.now().strftime("%Y%m%d_%H%M%S")
+    vdir = out_dir / "history" / label
+    vdir.mkdir(parents=True, exist_ok=True)
+    for f in files:
+        try:
+            shutil.move(str(f), str(vdir / f.name))
+        except Exception:
+            pass
+
+
+def _process_one(q, result, model, redo=False):
+    case_id = result.get("case_id")
+    if not case_id:
+        return (None, "no case_id")
+    folder = f"A_{_short_case(case_id)}"
+    out_dir = RUNS_DIR / q / "procedures" / folder / "_model"
+    if not redo and (out_dir / "workflow.json").is_file():
+        return (case_id, "skip(已完成)")
+    try:
+        _backup_history(out_dir)
+        out_dir.mkdir(parents=True, exist_ok=True)
+        src_path = out_dir / "_source.json"
+        src = _source_to_dsl_input(result)
+        src_path.write_text(json.dumps(src, ensure_ascii=False, indent=2), encoding="utf-8")
+        _write_meta(out_dir, case_id=case_id, from_q=q, form="A",
+                    score=_composite_score(result.get("llm_evaluation") or {}))
+        version = _gen_version()
+        # 盖版本号进 _meta
+        meta = json.loads((out_dir / "_meta.json").read_text(encoding="utf-8"))
+        meta["version"] = version
+        (out_dir / "_meta.json").write_text(json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8")
+
+        log_path = out_dir / "_extract.log"
+        cmd = [sys.executable, "-u", str(MODEL_EXTRACT), str(src_path),
+               "--out-dir", str(out_dir), "--model", model, "--case-id", folder]
+        with open(log_path, "w", encoding="utf-8") as lf:
+            r = subprocess.run(cmd, stdout=lf, stderr=subprocess.STDOUT, cwd=str(HERE))
+        if r.returncode != 0:
+            return (case_id, f"extract exit {r.returncode}")
+
+        # 写库 mode_dsl
+        wf = json.loads((out_dir / "workflow.json").read_text(encoding="utf-8"))
+        platform = case_id.split("_")[0] if "_" in case_id else None
+        db.upsert_dsl("mode_dsl", q, case_id, version, model, wf, source=src,
+                      platform=platform, post_title=src.get("title"), source_link=src.get("link"))
+        n = len(wf.get("procedures", []))
+        return (case_id, f"ok · {n}工序 · {version}")
+    except Exception as ex:
+        return (case_id, f"error: {ex}")
+
+
+def main():
+    p = argparse.ArgumentParser(description="批量大模型工序提取(写 _model/ + mode_dsl 表)")
+    p.add_argument("query", help="runs_new 下的 query 目录名")
+    p.add_argument("--model", default="anthropic/claude-sonnet-4-6")
+    p.add_argument("--workers", type=int, default=4)
+    p.add_argument("--form", default="A")
+    p.add_argument("--redo", action="store_true", help="重做已完成的(默认跳过已有 workflow.json 的帖)")
+    args = p.parse_args()
+
+    form_file = RUNS_DIR / args.query / f"form_{args.form}.json"
+    if not form_file.is_file():
+        print(f"❌ 找不到 {form_file}")
+        return 1
+    results = json.loads(form_file.read_text(encoding="utf-8")).get("results", [])
+    print(f"📋 query: {args.query} · {len(results)} 帖 · 模型 {args.model} · 并发 {args.workers}{' · 重做全部' if args.redo else ' · 跳过已完成'}")
+    print(f"🗄️  数据库: {'已启用' if db._enabled() else '未启用(仅写本地文件)'}\n")
+
+    ok = fail = skip = 0
+    with ThreadPoolExecutor(max_workers=args.workers) as ex:
+        futs = {ex.submit(_process_one, args.query, r, args.model, args.redo): r.get("case_id") for r in results}
+        for i, fut in enumerate(as_completed(futs), 1):
+            case_id, msg = fut.result()
+            if (msg or "").startswith("skip"):
+                skip += 1; continue
+            mark = "✅" if (msg or "").startswith("ok") else "❌"
+            if mark == "✅": ok += 1
+            else: fail += 1
+            print(f"[{i}/{len(results)}] {mark} {case_id} — {msg}")
+
+    print(f"\n🎉 完成:成功 {ok} · 失败 {fail} · 跳过(已完成) {skip} · 共 {len(results)}")
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 211 - 0
examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/procedure_model_extract.py

@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*-
+"""模型提取 · 单次大模型直出 workflow.json
+================================================================================
+
+和 run_cyber.py(agent + SKILL.md + validate 循环)完全不同:
+**只用一次大模型调用**,喂「帖子正文 + 配图」+ prompts/procedure_extract_system.md,
+让模型直接输出完整 workflow.json,再渲染成 HTML。无 agent、无 validate 修错循环。
+
+- 模型默认 google/gemini-3.1-flash-lite,可 --model 换(界面下拉传入)
+- prompt 从 prompts/procedure_extract_system.md 读(可单独迭代)
+- 多模态:配图下载成 base64(绕防盗链)随文本一起发
+- 渲染:复用 procedure-dsl/procedure/tools/render.py 出 case-*.html
+
+用法(一般由 server.py 起子进程调):
+  python procedure_model_extract.py <_source.json> --out-dir <目录> --model <模型> --case-id <id>
+"""
+import argparse
+import asyncio
+import base64
+import json
+import subprocess
+import sys
+from pathlib import Path
+
+PROJECT_ROOT = Path(__file__).resolve().parents[6]   # …/Agent(本文件在 mode_procedure/mode-dsl/ 下,比原来深一层)
+sys.path.insert(0, str(PROJECT_ROOT))
+
+from dotenv import load_dotenv
+load_dotenv()
+
+from examples.process_pipeline.script.llm_helper import call_llm_with_retry
+
+
+def _detect_image_mime(data: bytes):
+    """从字节 magic number 判真实图片格式(不靠 URL 扩展名)。
+    修复:小红书图按 jpeg 标但实际是 webp → Claude 严格校验 400。未知格式(如 SVG)返回 None 跳过。"""
+    if not data or len(data) < 12:
+        return None
+    if data[:3] == b"\xff\xd8\xff":
+        return "image/jpeg"
+    if data[:8] == b"\x89PNG\r\n\x1a\n":
+        return "image/png"
+    if data[:4] == b"RIFF" and data[8:12] == b"WEBP":
+        return "image/webp"
+    if data[:6] in (b"GIF87a", b"GIF89a"):
+        return "image/gif"
+    return None
+
+
+async def _fetch_data_url(url, sem):
+    """下载图片转 base64 data URL,media type 按真实字节判定(绕防盗链用项目 _download_image)。"""
+    from agent.tools.builtin.file.image_cdn import _download_image
+    async with sem:
+        try:
+            data = await _download_image(url)
+        except Exception:
+            return None
+    mime = _detect_image_mime(data)
+    if mime is None:
+        return None   # 未知/不支持格式(SVG 等)跳过,避免供应商 400
+    return f"data:{mime};base64,{base64.b64encode(data).decode()}"
+
+HERE = Path(__file__).resolve().parent                # mode_procedure/mode-dsl/
+MP = HERE.parent                                       # mode_procedure/(procedure-dsl 渲染器在这)
+PROMPT_FILE = HERE / "prompts" / "procedure_extract_system.md"
+RENDER_PY = MP / "procedure-dsl" / "procedure" / "tools" / "render.py"
+DEFAULT_MODEL = "anthropic/claude-sonnet-4-6"
+MAX_IMAGES = 8
+
+
+def _validate_wf(data):
+    """最小结构校验:顶层对象 + procedures 数组(不卡字段,模型提取不做 validate 循环)。"""
+    if not isinstance(data, dict):
+        return "顶层必须是 JSON 对象"
+    if "procedures" not in data:
+        return '缺少 "procedures" 字段'
+    if not isinstance(data["procedures"], list):
+        return '"procedures" 必须是数组'
+    return None
+
+
+def _sanitize_workflow(data):
+    """确定性结构清洗(非 LLM 校验循环):丢掉模型偶发产出的非法结构
+    (steps 里混入字符串、io 项不是对象、procedure 不是对象等),让 render 不崩。
+    返回 (清洗后的 data, 丢弃计数)。"""
+    dropped = {"procedures": 0, "steps": 0, "io": 0}
+    procs = data.get("procedures")
+    if not isinstance(procs, list):
+        return data, dropped
+    clean_procs = []
+    for p in procs:
+        if not isinstance(p, dict):
+            dropped["procedures"] += 1
+            continue
+        steps = p.get("steps")
+        if isinstance(steps, list):
+            kept = []
+            for s in steps:
+                if not isinstance(s, dict):
+                    dropped["steps"] += 1
+                    continue
+                for io in ("inputs", "outputs"):
+                    if isinstance(s.get(io), list):
+                        before = len(s[io])
+                        s[io] = [x for x in s[io] if isinstance(x, dict)]
+                        dropped["io"] += before - len(s[io])
+                kept.append(s)
+            p["steps"] = kept
+        if not isinstance(p.get("declarations"), dict):
+            p.pop("declarations", None)
+        if not isinstance(p.get("type_registry"), dict):
+            p.pop("type_registry", None)
+        clean_procs.append(p)
+    data["procedures"] = clean_procs
+    return data, dropped
+
+
+async def _collect_images(urls, max_images, concurrency):
+    """配图下载成 base64 data URL(带 Referer/UA 绕防盗链)。失败的跳过。"""
+    urls = [u for u in urls if isinstance(u, str) and u][:max_images]
+    if not urls:
+        return []
+    sem = asyncio.Semaphore(concurrency)
+    results = await asyncio.gather(*[_fetch_data_url(u, sem) for u in urls])
+    return [d for d in results if d]
+
+
+async def run(args):
+    src = json.loads(Path(args.source).read_text(encoding="utf-8"))
+    title = src.get("title", "") or ""
+    body = src.get("body_text", "") or ""
+    images = src.get("images") or []
+
+    system = PROMPT_FILE.read_text(encoding="utf-8")
+    post_text = f"【标题】{title}\n【来源】{src.get('link', '')}\n【正文】\n{body}"
+
+    data_urls = [] if args.no_images else await _collect_images(images, args.max_images, args.max_concurrent)
+    print(f"🖼️  配图 {len(data_urls)}/{len(images)} 张(base64 多模态)")
+
+    if data_urls:
+        user_content = [{"type": "text", "text": post_text}]
+        for u in data_urls:
+            user_content.append({"type": "image_url", "image_url": {"url": u}})
+        messages = [{"role": "system", "content": system}, {"role": "user", "content": user_content}]
+    else:
+        messages = [{"role": "system", "content": system}, {"role": "user", "content": post_text}]
+
+    from agent.llm.openrouter import create_openrouter_llm_call
+    llm_call = create_openrouter_llm_call(model=args.model)
+    print(f"🤖 模型提取(单次大模型直出)· 模型 {args.model}")
+
+    data, cost = await call_llm_with_retry(
+        llm_call=llm_call, messages=messages, model=args.model,
+        temperature=0.2, max_tokens=args.max_tokens,
+        validate_fn=_validate_wf, task_name="ProcModelExtract",
+    )
+    if not data:
+        print("❌ 模型提取失败(重试耗尽,未得到合法 workflow.json)")
+        return 1
+
+    data, dropped = _sanitize_workflow(data)
+    if any(dropped.values()):
+        print(f"🧹 结构清洗:丢弃非法 procedure {dropped['procedures']} / step {dropped['steps']} / io {dropped['io']}(模型偶发畸形,已剔除以免渲染崩溃)")
+
+    out_dir = Path(args.out_dir)
+    out_dir.mkdir(parents=True, exist_ok=True)
+    wf_path = out_dir / "workflow.json"
+    wf_path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
+    n = len(data.get("procedures", []))
+    print(f"✅ workflow.json 写出 · {n} 个工序 · ${cost:.4f} → {wf_path}")
+
+    # 渲染 HTML(复用 procedure 的 render.py;失败不阻断,workflow.json 已落盘)
+    if not args.no_render:
+        case_id = args.case_id or out_dir.name
+        out_html = out_dir / f"case-{case_id}.html"
+        try:
+            r = subprocess.run(
+                [sys.executable, str(RENDER_PY), "--workflow", str(wf_path),
+                 "--source-input", str(Path(args.source).resolve()), "--page-title", (title or case_id)[:60],
+                 "--case-id", case_id, "--out", str(out_html)],
+                capture_output=True, text=True, encoding="utf-8", errors="replace",
+                cwd=str(MP / "procedure-dsl"), timeout=120,
+            )
+            if r.returncode == 0:
+                print(f"✅ HTML → {out_html}")
+            else:
+                err = ((r.stdout or "") + "\n" + (r.stderr or "")).strip()
+                print(f"⚠️ 渲染失败(workflow.json 已生成,可手动重渲):{err[-500:]}")
+        except Exception as e:
+            print(f"⚠️ 渲染异常(workflow.json 已生成):{e}")
+    return 0
+
+
+def main():
+    p = argparse.ArgumentParser(description="模型提取:单次大模型直出 workflow.json(无 agent / 无 validate 循环)")
+    p.add_argument("source", help="_source.json 路径(server 写好的帖子源)")
+    p.add_argument("--out-dir", required=True, help="产出目录(写 workflow.json + case-*.html)")
+    p.add_argument("--model", default=DEFAULT_MODEL, help=f"模型(默认 {DEFAULT_MODEL},界面下拉传入)")
+    p.add_argument("--case-id", default=None, help="case_id(用于 HTML 文件名/标题)")
+    p.add_argument("--max-images", type=int, default=MAX_IMAGES)
+    p.add_argument("--max-concurrent", type=int, default=4)
+    p.add_argument("--max-tokens", type=int, default=8000,
+                   help="输出 token 上限(OpenRouter 按此预扣额度;额度紧就调小,默认 8000)")
+    p.add_argument("--no-images", action="store_true", help="不发配图(纯文本提取)")
+    p.add_argument("--no-render", action="store_true", help="只出 workflow.json,不渲染 HTML")
+    args = p.parse_args()
+    raise SystemExit(asyncio.run(run(args)))
+
+
+if __name__ == "__main__":
+    main()

+ 236 - 0
examples/process_pipeline/script/search_eval/mode_procedure/mode-dsl/prompts/procedure_extract_system.md

@@ -0,0 +1,236 @@
+# 工序提取 · procedure
+
+读一篇 AI 创作教程/案例,把它背后的"做法"还原成工序表,**直接输出完整的 `workflow.json`**。
+
+---
+
+## 提取判断
+
+### 有几个工序
+
+判断单位是"一条完整的 输入→最终产物 链",不是原文段落。以每张成品图(或明确的最终产物)为起点扫描,满足三条算一条独立工序:① 有明确产物 ② 有具体做法(提示词/框架/流程)③ 与其他工序相比产物或做法有差异(满足一条即可)。
+
+### 什么算一个步骤
+
+**步骤 = 对已有数据执行某个操作,产生一份之前不存在的新产物。** 判断口诀:把这步去掉、把它的内容挪进下一步的 inputs——什么都没丢,它就不是步骤,是输入。
+
+❌ 不是步骤:引入外部资源(写进使用它的步骤 inputs 或 `declarations.inputs`);原文直接给出的提示词(**哪怕给了多个例子**,也只作为对应生成步的 inputs,不拆 `via=human` 预处理步);提示词多层展开(那是「写提示词」一步的输出 value 内容);纯展示/预览。  
+✅ 是步骤:AI 工具生成图/视频、后期工具调色排版。
+
+### 循环 / 并行
+
+展开成控制块 + 子步,不要硬压成一步:
+
+```json
+{ "id": "s5", "kind": "block", "via": "-",
+  "inputs": [{ "type": "分镜脚本", "value": "…", "anchor": "← s4o1" }],
+  "outputs": [{ "id": "s5o1", "type": "分镜图列表", "value": "…", "anchor": "→ s6" }] },
+{ "id": "s5.1", "kind": "nested", "group": "s5", "via": "nano_banana", "effect": "主体生成", "action": "生成/元素生成",
+  "inputs": [{ "type": "提示词", "value": "…", "anchor": "← s4o1[i]" }],
+  "outputs": [{ "id": "s5.1o1", "type": "分镜图", "value": "…", "anchor": "→ 分镜图列表.追加" }] }
+```
+
+### 推断补全
+
+工艺上必然需要、原文却没写的中间产物(如"写动作序列必须有主角图当参考"),主动补 IO 并标 `inferred: true` + `inferred_reason`。原文细节没写全的不算(那是信息缺失,不是推断)。
+
+---
+
+## workflow.json 结构
+
+```json
+{
+  "source": {
+    "platform": "",
+    "author": "",
+    "date": "",
+    "url": null,
+    "title": "",
+    "excerpt": "1-2 句概括这篇教程的流水线"
+  },
+  "procedures": [
+    {
+      "id": "p1",
+      "name": "工序名称",
+      "purpose": "一句话说明该工序在做什么",
+      "category": "产物创造|资产建设|自动化|分析|学习",
+      "platform": "",
+      "author": "",
+      "declarations": {
+        "inputs": [{ "type": "参考图", "name": "产品图", "desc": "用户提供" }],
+        "resources": [],
+        "returns": { "type": "成品图" }
+      },
+      "type_registry": {
+        "主角图": { "extends": "参考图", "desc": "本案例的女主肖像" }
+      },
+      "steps": [
+        {
+          "id": "s1",
+          "kind": "step",
+          "via": "(AI 生图工具)",
+          "effect": "主体生成",
+          "action": "生成/元素生成",
+          "substance": "人物、产品",
+          "form": null,
+          "directive": "比例 2:3",
+          "intent": "{via:AI 生图工具}{act:元素生成}{in-type:提示词}生成成品图",
+          "inputs": [{ "type": "提示词", "value": "原文逐字给出的整段提示词", "anchor": "← 工序输入" }],
+          "outputs": [{ "id": "s1o1", "type": "成品图", "value": "<画面整段具体描述>", "anchor": "→ 交付" }]
+        }
+      ]
+    }
+  ]
+}
+```
+
+### 字段规范
+
+| 字段                 | 规范                                                                                                                          |
+| -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| step `id`            | `s1`、`s2`;控制块子步用点号 `s5.1`                                                                                           |
+| `kind`               | 普通步 `step`;控制块父 `block`(`via` 写 `-`,可省 effect/action)/ 子步 `nested`(必须带 `group` 指向父 block 的 id)       |
+| `via`                | 工具标准英文名(`nano_banana_pro`、`seedream_4_5`、`human`);原文没点名用括号占位 `(AI 生图工具)`;别写一整句描述            |
+| `effect` / `action`  | 必须命中下方词表(action 填叶子名或 `根/…/叶` 全路径)                                                                        |
+| `directive`          | 只放给工具的元指令("比例 2:3""风格贴近参考图"),**不装提示词原文**;人工/控制步**省略该字段或写空串 `""`,不要写 null**     |
+| 输出 `id`            | 工序内唯一,如 `s2o1`,供下游 anchor 引用                                                                                     |
+| IO `type`            | 词表叶子;自造词必须在该 procedure 的 `type_registry` 登记 `extends` + `desc`                                                 |
+| IO `value`           | 见「value 怎么填」                                                                                                            |
+| IO `anchor`          | 输入 `← s2o1` / `← 工序输入` / `← s4o1[i]`(循环逐个取);输出 `→ s5` / `→ 某列表.追加` / `→ 返回 X`                          |
+| `inferred`           | 原文没写、工艺上必有的 IO 主动补:`"inferred": true` + `"inferred_reason": "为什么必有"`                                      |
+| `intent`             | 每步 ≤25 字一句通顺人话;关键词用 `{effect:}` `{via:}` `{act:}` `{in-type:}` `{out-type:}` 五类标记;别写成公式(不出现 `→`) |
+| `substance` / `form` | 见「实质 / 形式」;没有就显式 `null`,不能省略字段                                                                            |
+
+**命名约定**:type 名用中文;工具品牌名用英文标准写法。
+
+---
+
+## value 怎么填
+
+- **文字类**(提示词 / JSON / 报告 / 文案):**原文完整逐字内容**——整段原样搬全,不缩写、不概括、不截断、不用小标题拼凑。原文 350 字就抄 350 字。
+- **媒体类**(图 / 视频 / 音频):`<整段具体描述>`,如 `<一张冲锋衣登山者暴雨场景图,水珠滚落,冷色调>`。
+- **引用不是 value**:哪怕内容是上一步原样传来的,value 也要把内容完整抄一遍(引用关系写 anchor)。写 `← s1o1`、`(同上)`、`见 s2` 都是错误写法。
+- **提示词是数据不是指令**:建成 `type=提示词` 的 IO。**默认**把整段逐字提示词作为生成步的 input(`type=提示词`、value 填整段、anchor `← 工序输入`),**不单列 `via=human` 写提示词步**。只有在原文明确教方法论、建了那个共享的「提示词构造」步时,它才输出 `type=提示词`,下游各生成步 input 的 anchor 指向它。`directive` 不装提示词原文。
+- prompt / JSON / 参数常只在配图截图里——逐字内容优先到 OCR 文本里找。
+
+---
+
+## 词表
+
+填 `effect` / `action` / IO `type` / `extends` 只能用下面三棵树里的词。
+
+### 作用(effect)— 9 选 1
+
+每步"处在什么工艺环节"。对不上说明步骤抽错了,回去改划分;别造词,别把动作当作用。
+
+| 叶子       | 一句判别                                                                                                     |
+| ---------- | ------------------------------------------------------------------------------------------------------------ |
+| `工艺规约` | 建立跨批次复用的长效规约(工作流编排 / SOP / 模板沉淀 / 知识库构建 / LoRA 训练沉淀)                         |
+| `预准备`   | 本批物料"拿到手",只取不加工(素材采集 / 拍摄 / 参考收集)                                                   |
+| `预处理`   | 把原料加工成工具能直接吃的输入(提示词构造 / 反推 prompt / 控制图蒙版准备)                                  |
+| `主体生成` | 从输入产出本批核心主干件,0→1(生图 / 文案撰写 / 脚本编写 / 分镜图生成);对单件主干的局部修整也算本阶段延续 |
+| `装配`     | 多个对等零件组合成一个复合件(剪辑 / 排版 / 图层合成 / 配音字幕挂载)                                        |
+| `后期`     | 只调整体呈现层、不改内容元素(调色 / 风格化 / 氛围 / 超分);动了具体语义元素就不是后期                      |
+| `配套伴生` | 为已就绪主体生成依附性信息(标题 / 配文 / 标签 / 元数据)                                                    |
+| `检验`     | 只评估不改造,产出审查结论(质检 / 终审 / 小样测试)                                                         |
+| `交付`     | 推向终态对外(导出 / 发布 / 定稿 / 成品多视图展示)                                                          |
+
+边界速查:跨批复用→工艺规约,本批一次性→预准备/预处理;"去拿料"→预准备,"把料加工成输入"→预处理;单件 0→1→主体生成,多件→一件→装配;改呈现层→后期,改内容元素→主体生成延续。
+
+### 动作(action)
+
+填叶子名或全路径(如 `解构` 或 `提取/化学提取/解构`)。
+
+```json
+{
+  "获取": {
+    "搜索": ["检索", "下载"],
+    "查询": ["调取"],
+    "录入": ["上传", "拍摄", "录音", "键入"],
+    "引用": ["选取"]
+  },
+  "提取": {
+    "物理提取": ["裁切", "抠取", "抽帧"],
+    "化学提取": ["识别", "反推", "解构"]
+  },
+  "生成": ["元素生成", "关系生成", "数组生成", "结构生成"],
+  "修改": {
+    "增": ["添加", "叠加"],
+    "删": ["抹除", "剪除"],
+    "变": ["重述", "风格化", "转换", "替换", "调整", "增强"]
+  },
+  "存储": {
+    "暂存": ["缓存"],
+    "沉淀": ["入库"],
+    "归档": ["存档"]
+  }
+}
+```
+
+⚠ **反推 vs 解构**:从文字/教程里提炼框架、要点(信息显式可见)→ `解构`;从图片推回 prompt 或隐含结构(信息不可直接看到)→ `反推`。"梳理教程结构""提取风格要素"几乎都是 `解构`。
+
+### 类型(type)
+
+候选词直接命中叶子就用;没命中挑最近叶子挂靠,在该 procedure 的 `type_registry` 登记 `{"extends": "叶子", "desc": "说明"}`。不允许自造词不登记。
+
+```json
+{
+  "程序控制类型": {
+    "指令": ["提示词", "负向提示词", "描述"],
+    "参数": ["生成参数", "规格参数", "模型权重"],
+    "评估": ["评分", "评语"],
+    "流程": ["工作流", "批处理"]
+  },
+  "内容类型": {
+    "素材": {
+      "化学变化": [
+        "参考图",
+        "参考视频",
+        "参考音频",
+        "对标内容",
+        "分镜图",
+        "转场",
+        "蒙版",
+        "控制图",
+        "运动轨迹",
+        "滤镜",
+        "构图布局"
+      ],
+      "物理变化": ["截图", "视频片段", "转场片段", "关键帧", "音效", "特效"]
+    },
+    "半成品": {
+      "序列": ["大纲", "脚本", "分镜脚本", "剪辑脚本", "配音文案"],
+      "原子": ["底图", "样图", "分镜视频"],
+      "组合": ["图层组合", "拼图"]
+    },
+    "准成品": ["歌词", "配音", "BGM", "字幕", "标题", "正文"],
+    "成品": ["成品图", "视频成品", "合成图"]
+  },
+  "数据复用类型": {
+    "原子": ["数字人", "版式"],
+    "序列": ["模板"]
+  },
+  "知识类型": ["知识库"]
+}
+```
+
+### 实质 / 形式(substance / form)
+
+只描述最终产物**画面内容的视觉维度**,与步骤处理什么数据类型无关。
+
+- **substance**(画面里有什么):图片内容元素,可多个用顿号并列,如 `美女`、`人物、风景`、`信息图表`、`产品、白底`。❌ 不填 `风格`(那是 form)、不填 `提示词/描述/框架`(数据类型)。即使这步产出文字,也填它面向的画面内容。
+- **form**(画面长什么样):视觉风格调性,可多个用顿号并列,如 `超现实主义`、`古风、写实`。❌ 不填 `JSON/表格`(技术格式)。方法不限风格 → `null`。
+
+先判断作者意图:**通用方法文**(有"换个题材也能套"类泛化表述)→ substance 填方法的作用对象大类(`人物`、`产品`、`信息图表`、`实拍图`);**具体案例文** → 填案例实际视觉内容元素与具体风格。判断不清偏具体案例。没有特别涉及就 `null`。
+
+---
+
+## 输出前自查
+
+输出 JSON 之前逐项确认:
+
+- 每个章节/段落都被某工序认领,无遗漏
+- 所有文字类 value 均为原文逐字内容,未缩写或概括
+- 每步 intent 是一句通顺人话(≤25 字),未出现 `→`
+- effect / action / type 均命中词表
+- anchor 链路完整,无悬空引用

+ 215 - 0
examples/process_pipeline/script/search_eval/mode_procedure/mode_procedure_分析.md

@@ -0,0 +1,215 @@
+# mode_procedure 分析与复刻方案
+
+> 目标:把 `server.py --mode new` + `run_cyber.py --skill procedure` 这一套「自由 query → 搜索评估 → 工序解构(直写版)→ 可视化」的能力,复刻到自包含的 `search_eval/mode_procedure/` 文件夹里。
+>
+> 本文先讲清**三块东西各自是什么、怎么串起来、依赖哪些文件**,最后给**复刻清单**。
+
+---
+
+## 0. 一张图看懂全局
+
+```
+                    new_query.html  (前端,96KB)
+                         │  用户:选维度/输自由 query → 搜评 → 看帖 → 批量/单帖工序解构
+                         ▼
+        python server.py 8771 --mode new   (HTTP 后端)
+          读写 runs_new/   serve new_query.html   异步起子进程
+                         │
+        ┌────────────────┼─────────────────────────┐
+        ▼                ▼                          ▼
+ search_and_evaluate.py  batch_3forms.py      run_cyber.py  ← 提取引擎
+ (搜索+LLM评分)          (--reeval 重评)       └─ --skill procedure → 读 procedure/SKILL.md(直写版)
+        │                                          └─ --skill dsl(默认)→ 读 spec/(三阶段版)
+        ▼                                          │
+ runs_new/{query}/form_A.json              runs_new/{query}/procedures/{folder}/workflow.json + case-*.html
+                                                   │
+                                                   ▼  build_workflows.py 合并 post+workflow
+                                            runs_new/{query}/procedures(前端展示)
+```
+
+**三个独立的概念,别混:**
+1. **提取引擎** = `run_cyber.py`(怎么把一篇帖子变成 workflow.json)。
+2. **提取规范(skill)** = `procedure/`(直写版)或 `spec/`(三阶段版),由 `run_cyber.py --skill` 选择。
+3. **运行模式(mode)** = `server.py --mode new/legacy`,决定**读哪个目录、用哪个前端、q 命名规则**,和上面两个正交。
+
+> ⚠️ 现状:`server.py --mode new` 的批量/单帖工序提取调 `run_cyber.py` 时**没传 `--skill`**,所以默认走 `spec/` 三阶段版。你要「mode_procedure」用直写版的话,复刻时给 run_cyber 加上 `--skill procedure` 即可(见 §6)。
+
+---
+
+## 1. `procedure/` 是什么(强模型直写版 skill)
+
+路径:`procedure-dsl/procedure/`。它是一个**自包含的「工序提取规范」**,给强模型(claude-sonnet 等)看,让它**一次 write_file 直接写出完整 `workflow.json`**,再校验。
+
+```
+procedure/
+├── SKILL.md          ★ 规范全文(13KB):流程 + workflow.json 结构 + 字段规范 + 完整词表(effect/action/type 三棵树内联)+ 批量修错
+└── tools/
+    ├── validate.py   ★ 校验器:检查 workflow.json 字段合法性、anchor 闭合、value 是否逐字命中原文;带 --fix-verbatim 自动回填原文
+    ├── wf-patch.py    批量改错:--set / --patch 清单,写入即校验,路径语法如 p1.s2.effect
+    ├── render.py      渲染 workflow.json → case-*.html(可视化工序表)
+    └── vocab.py       词表数据(effect/action/type 的合法值,validate/wf-patch 共用)
+```
+
+**procedure(直写)vs spec(三阶段)的区别**:
+
+| | `procedure/`(直写版) | `spec/`(三阶段版,默认) |
+|---|---|---|
+| 流程 | 通读 → **一次 write 完整 workflow.json** → validate 修 | Phase1 骨架(plan_procedures) → Phase2 填值(wf-patch) → Phase3 lint+render |
+| 适合模型 | 强模型(claude-sonnet-4.x) | 弱/中模型也能跑(分步降难度) |
+| 工具 | validate.py + render.py(2 个) | plan/wf-patch/lint-case/verify-io/render-case(多个) |
+| 规范文件 | 单文件 SKILL.md(含完整词表) | spec/README.md + 分阶段 md + taxonomy/*.json |
+| 产物 | workflow.json(+ 收尾自动 render HTML) | workflow.json + understanding.md + HTML |
+
+**SKILL.md 核心约定**(复刻时这套规则不用改,照搬):
+- workflow.json 结构:`source` + `procedures[]`,每个 procedure 有 `steps[]`,每步含 `via`(工具)/`effect`(作用)/`action`(动作)/`substance`(实质)/`form`(形式)/`inputs[]`/`outputs[]`/`intent`。
+- `effect` 9 选 1、`action`/`type` 命中内联词表;自造 type 在 `type_registry` 登记。
+- value 填**原文逐字内容**(不概括),引用关系写 `anchor`(如 `← s2o1`)。
+- 完成条件:`validate.py` 0 错误。
+
+---
+
+## 2. `run_cyber.py` 提取引擎 + `--skill` 机制
+
+路径:`procedure-dsl/run_cyber.py`(~1000 行)。它是**用 cyber-agent 的 `AgentRunner` 跑一个 LLM agent** 来做工序解构,支持多 provider(OpenRouter / Qwen)。
+
+### 2.1 `--skill` 怎么选规范
+- `spec_name` 变量决定读哪个 skill 目录:`DSL_ROOT / spec_name`。
+- `--skill dsl`(默认)→ `procedure-dsl/spec/`(三阶段)。
+- `--skill procedure` → `procedure-dsl/procedure/`(直写)。
+- 目录不存在直接报错。
+
+### 2.2 procedure 模式怎么跑(`--skill procedure`)
+- **起手 prompt**:`_build_procedure_prompt`(~line 523)独立硬编码——只引 `procedure/SKILL.md`,给 agent 钉死路径(SKILL.md、tools/validate.py、`<case_dir>/workflow.json`),把帖子正文内联 + 配图 base64 多模态塞进去 + OCR 文本。
+- **agent 工具**:`RunConfig.tool_groups=["core","system"]`(read/write/edit/glob/grep + bash_command);`exclude_tools` 去掉 plan_procedures、agent、evaluate(单 agent,无子 agent)。
+- **校验环节**:agent 自己用 `bash_command` 跑 `validate.py`,引擎逐条 execute;引擎从 stdout 抓 `✗` 行判断完成度(`_completion_gaps_procedure`,~line 159)。没过会自动 nudge 续跑(同一 trace)。
+- **收尾**:validate 全过后引擎自动 `validate.py --fix-verbatim`(逐字回填原文)+ `render.py` 渲染 `case-*.html`(`_finalize_procedure`,~line 945)。
+- **产物**:`workflow.json`(唯一主产物)+ `case-*.html` + `_trace_cyber.md`。
+
+### 2.3 底层引擎 + 模型
+```python
+from agent.core.runner import AgentRunner, RunConfig, KnowledgeConfig
+from agent.trace import FileSystemTraceStore
+from agent.llm import create_openrouter_llm_call, create_qwen_llm_call
+```
+- `--model`(OpenRouter 全名如 `anthropic/claude-sonnet-4.6` / `google/gemini-3.1-flash-lite`;有别名 `flash`/`flash-lite`)。
+- `--provider openrouter|qwen`。
+- `RunConfig`:temperature 0.3、max_iterations 300、`goal_compression="none"`、知识提取关。
+- trace 存仓库根 `.trace/`。
+
+### 2.4 `--batch` 批量模式
+- 输入 `batch_posts.json`(`{"results":[{case_id, post:{...}}, ...]}`)。
+- `--batch-workers N`:N=1 进程内串行;N>1 每帖起子进程(隔离,各自 `_extract.log`)。
+- out-dir 下**每帖一个子目录** `{case_id}/`,含 `_source.json`/`_meta.json`/`workflow.json`/`case-*.html`/`_scratch/ocr.txt`。
+- 已有 `*.html` 的子目录跳过(`--batch-redo` 强制)。
+
+### 2.5 依赖
+- `procedure/SKILL.md` + `procedure/tools/{validate,render,wf-patch,vocab}.py`
+- `run_procedure_dsl.py`(`_load_sibling_module` 复用其起手 prompt/图片处理/case_id 推导函数)
+- `plan_tool.py`(仅 spec 模式用 plan_procedures)
+- cyber-agent:`agent.core.runner` / `agent.trace` / `agent.llm`
+- 环境:`OPEN_ROUTER_API_KEY`(或 `QWEN_API_KEY`+`QWEN_BASE_URL`)、PIL、httpx
+
+---
+
+## 3. `python server.py 8771 --mode new` 具体干什么
+
+`server.py` 是查看/操作界面的 HTTP 后端。`--mode new` 相对 legacy 改了这些:
+
+| 维度 | legacy | **new** | 代码 |
+|------|--------|---------|------|
+| 数据目录 | `runs_full/` | **`runs_new/`** | line 30 `RUNS_DIR_NAME` |
+| 前端 html | `index.html` | **`new_query.html`** | line 653 |
+| query 命名 | 强制 `q0000` 正则 | **自由中文名**(仅清非法字符) | line 871、971、1038 `MODE != "new"` 跳过校验 |
+| 列表排序 | 按数字 | **按修改时间倒序**(新 query 在前) | line 609-615 |
+| HTML 路径 | 硬编码 `runs_full/` | 动态换成 `runs_new/` | line 570 |
+
+**端口**:`server.py 8771 --mode new` = 在 **8771 端口**起 new 模式服务(默认端口 8770;这里手动指定 8771,避免和 legacy 的 8770 冲突)。
+
+### new 模式提供的能力(前端 new_query.html 驱动)
+1. **搜索+评估**:`POST /api/run_search_eval {query, platforms}` → 起 `search_and_evaluate.py` 子进程 → 产 `runs_new/{query}/form_A.json`。前端实时轮询日志/状态。
+2. **单帖工序解构**:`POST /api/generate_procedure {q, form, case_id, engine, model}` → 起 `run_cyber.py` → `procedures/{folder}/workflow.json`+html。
+3. **批量工序解构**:`POST /api/batch_generate_procedure {q, concurrency}` → 过滤 report 帖 → 起 `run_cyber.py --batch` → 多帖工序。
+4. **重评**:`POST /api/reeval {q}` → `batch_3forms.py --reeval`(备份旧 form 到 history/)。
+5. **状态/日志查询**:`/api/*_status`、`/api/*_log` 一堆轮询端点。
+6. **静态文件**:`GET /runs_new/...` serve 产出的 html/json/图。
+7. **spec 在线编辑**:`/api/save_spec`。
+
+任务用 4 个字典跟踪:`ACTIVE_TASKS`/`ACTIVE_REEVALS`/`ACTIVE_SEARCH_EVALS`/`ACTIVE_BATCH_TASKS`。
+
+### `new_query.html` 前端(96KB)
+一整套操作台:左侧 query 列表(按时间倒序)、维度选择器(taxonomy 三级联选拼 query)、平台勾选+数量、「搜索并评估」按钮+实时控制台、统计卡片、帖子卡片网格、单帖详情 modal(图/文/评分/「生成工序」「批量生成工序」按钮)。
+
+---
+
+## 4. `runs_new/{query}/` 目录结构
+
+```
+runs_new/
+└── 人像 真实感 图片 生成 怎么做/        ← 自由中文 query 名(非 q0000)
+    ├── form_A.json                     搜索+评分结果(results[]:post + llm_evaluation)
+    ├── evaluated.json                  search_and_evaluate 的中间产物
+    ├── _search_eval.log
+    ├── history/{时间戳}/form_A.json     重评时备份
+    └── procedures/
+        ├── _batch_extract.log
+        └── {form}_{平台}_{case_id前8}/   如 A_xhs_6a040130/
+            ├── _source.json            喂给 run_cyber 的输入帖
+            ├── _meta.json              case_id / from_q / form / score
+            ├── workflow.json           ★ 工序表
+            ├── case-*.html             ★ 可视化
+            ├── _trace_cyber.md
+            └── _scratch/ocr.txt
+```
+
+---
+
+## 5. 完整文件依赖清单(各文件角色)
+
+| 文件 | 角色 |
+|------|------|
+| `server.py` | HTTP 后端枢纽:路由、起子进程、跟踪任务、serve 静态/前端 |
+| `new_query.html` | new 模式前端操作台 |
+| `search_and_evaluate.py` | 搜索 + LLM 逐条评分 → form_A.json |
+| `batch_3forms.py` | 三形式 / 重评(`--reeval`) |
+| `build_workflows.py` | 合并 post + workflow.json(`write_one`/`write_run`) |
+| `batch_extract_procedures.py` | server 复用其 `_short_case`/`_source_to_dsl_input`/`_write_meta`/`_composite_score` |
+| `run_cyber.py` | ★ 工序解构引擎(AgentRunner) |
+| `run_procedure_dsl.py` | 被 run_cyber 复用纯函数(也可独立做 Claude SDK 提取) |
+| `procedure/SKILL.md` + `procedure/tools/*` | ★ 直写版工序规范 + 校验/渲染工具 |
+| `spec/` | 三阶段版规范(默认 skill) |
+| `evaluation/judged_matrix.json` 等 | taxonomy + 评分配置(前端维度选择器、评分用) |
+
+---
+
+## 6. 在 `mode_procedure/` 复刻的方案
+
+目标:一个自包含文件夹,跑 **new 模式界面 + procedure 直写版提取**。参考 `fixed_query_eval/` 的「复用引擎、复制外壳」打法。
+
+### 要点
+1. **复用(import,不复制)**:搜索/评估引擎 `search_and_evaluate.py`、`run_cyber.py`、`procedure/` skill、`build_workflows.py`、`agent.*` ——都用绝对路径 import 或 subprocess 调,别拷贝。
+2. **复制改造的外壳**:
+   - `server.py` → 复制一份,**写死 `--mode new` 行为**(`RUNS_DIR = HERE/"runs_new"`、serve `new_query.html`、自由 q 命名),并加 `sys.path.insert(0, HERE.parent)` 复用兄弟模块(同 fixed_query_eval 的做法)。
+   - `new_query.html` → 复制进来(前端)。
+3. **关键改动:让工序提取走 procedure 直写版**——在 server 起 `run_cyber.py` 的两处(单帖 `run_extraction_task` ~line 117、批量 `run_batch_extraction` ~line 1154)的 cmd 里**加 `"--skill", "procedure"`**,并把 `--model` 默认改成强模型(如 `anthropic/claude-sonnet-4.6`,直写版需要强模型)。
+4. **路径修正**:`run_cyber.py` 在 `procedure-dsl/` 下,cwd 要对(subprocess 的 `cwd=HERE` 需指到能找到 `procedure-dsl/` 的位置;或传绝对路径)。procedure skill 目录 `DSL_ROOT/procedure` 是相对 run_cyber 自身定位的,不受影响。
+5. **目录**:`mode_procedure/runs_new/`(产出)、复用 `../evaluation/`(taxonomy,前端维度选择器要)、`../procedure-dsl/`(引擎+skill)。
+
+### 复刻清单(建议结构)
+```
+search_eval/mode_procedure/
+├── server.py        ← 复制 ../server.py,写死 new 模式 + sys.path + run_cyber 加 --skill procedure
+├── new_query.html   ← 复制 ../new_query.html
+├── runs_new/        ← 产出目录
+└── README.md
+```
+> 引擎类(search_and_evaluate / run_cyber / procedure skill / build_workflows / batch_extract_procedures)**全部 import/subprocess 复用 `../` 下的原件**,不复制,保持单一实现。
+
+### 起服务
+```bash
+cd search_eval/mode_procedure
+python server.py 8771      # 写死 new 模式后,不用再传 --mode
+```
+
+---
+
+*本文基于对 procedure/SKILL.md、run_cyber.py、server.py(--mode new)、new_query.html 的源码分析(含 2 路并行深读)。如与代码冲突以代码为准。*

+ 2818 - 0
examples/process_pipeline/script/search_eval/mode_procedure/new_query.html

@@ -0,0 +1,2818 @@
+<!doctype html>
+<html lang="zh-CN">
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <meta name="referrer" content="no-referrer">
+  <title>新 Query 搜索与评估 · 案例总览</title>
+  <style>
+    :root {
+      --ink: #24211d;
+      --muted: #6f6961;
+      --line: #ded8ce;
+      --paper: #fbfaf7;
+      --panel: #ffffff;
+      --mint: #1f8a70;
+      --rose: #b24b63;
+      --amber: #b87918;
+      --cyan: #2a6f8f;
+      --soft-mint: #e9f5f0;
+      --soft-rose: #f8e9ee;
+      --soft-amber: #fff2d9;
+      --soft-cyan: #e7f2f7;
+      --shadow: 0 18px 45px rgba(41, 35, 28, .08);
+    }
+
+    * {
+      box-sizing: border-box;
+    }
+
+    body {
+      margin: 0;
+      color: var(--ink);
+      background: var(--paper);
+      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
+      line-height: 1.55;
+    }
+
+    header {
+      padding: 30px 24px 18px;
+      border-bottom: 1px solid var(--line);
+      background: linear-gradient(180deg, #fff 0%, #fbfaf7 100%);
+    }
+
+    .wrap {
+      max-width: 1440px;
+      margin: 0 auto;
+    }
+
+    .eyebrow {
+      display: flex;
+      gap: 8px;
+      align-items: center;
+      color: var(--mint);
+      font-size: 13px;
+      font-weight: 700;
+      text-transform: uppercase;
+      letter-spacing: 0;
+    }
+
+    h1 {
+      margin: 8px 0 4px;
+      font-size: clamp(24px, 3.5vw, 36px);
+      line-height: 1.1;
+      letter-spacing: 0;
+    }
+
+    .lede {
+      color: var(--muted);
+      font-size: 14.5px;
+    }
+
+    /* Layout for two-column structure */
+    .app-container {
+      max-width: 1440px;
+      margin: 0 auto;
+      padding: 24px;
+      display: grid;
+      grid-template-columns: 320px 1fr;
+      gap: 24px;
+      align-items: start;
+    }
+
+    @media (max-width: 1024px) {
+      .app-container {
+        grid-template-columns: 1fr;
+      }
+    }
+
+    /* Sidebar Styles */
+    .sidebar {
+      background: var(--panel);
+      border: 1px solid var(--line);
+      border-radius: 12px;
+      padding: 20px;
+      box-shadow: var(--shadow);
+      height: fit-content;
+      max-height: calc(100vh - 180px);
+      overflow-y: auto;
+      position: sticky;
+      top: 24px;
+    }
+
+    .sidebar h3 {
+      margin-top: 0;
+      font-size: 15px;
+      font-weight: 700;
+      border-bottom: 1px solid var(--line);
+      padding-bottom: 10px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+
+    .sidebar-list {
+      display: flex;
+      flex-direction: column;
+      gap: 8px;
+      margin-top: 12px;
+    }
+
+    .sidebar-item {
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 10px 12px;
+      background: #fff;
+      cursor: pointer;
+      transition: all 0.15s ease;
+      font-size: 13px;
+      font-weight: 500;
+      display: flex;
+      flex-direction: column;
+      gap: 4px;
+    }
+
+    .sidebar-item:hover {
+      border-color: #bbb;
+      background: #fafaf9;
+    }
+
+    .sidebar-item.active {
+      border-color: var(--mint);
+      background: var(--soft-mint);
+      color: var(--ink);
+      font-weight: 700;
+      box-shadow: inset 3px 0 0 var(--mint);
+    }
+
+    .sidebar-item .q-text {
+      word-break: break-all;
+      line-height: 1.35;
+    }
+
+    .sidebar-item .meta {
+      font-size: 11px;
+      color: var(--muted);
+      display: flex;
+      justify-content: space-between;
+      margin-top: 2px;
+    }
+
+    .sidebar-item .meta strong {
+      color: var(--mint);
+    }
+
+    /* Builder Card styling */
+    .builder-card {
+      background: var(--panel);
+      border: 1px solid var(--line);
+      border-radius: 12px;
+      padding: 20px;
+      box-shadow: var(--shadow);
+    }
+
+    .builder-card h3 {
+      margin-top: 0;
+      margin-bottom: 16px;
+      font-size: 15px;
+      font-weight: 700;
+      border-bottom: 1px solid var(--line);
+      padding-bottom: 10px;
+    }
+
+    .dimensions {
+      display: flex;
+      flex-direction: column;
+    }
+
+    .dim-group {
+      padding: 4px 0;
+      border-bottom: 1px solid #f2f2f2;
+    }
+
+    .dim-group:last-child {
+      border-bottom: none;
+    }
+
+    .level-row {
+      display: flex;
+      align-items: flex-start;
+      padding: 7px 0;
+      gap: 10px;
+    }
+
+    .level-row.indent {
+      margin-left: 78px;
+    }
+
+    .dim-label {
+      font-size: 12.5px;
+      color: #999;
+      min-width: 68px;
+      padding-top: 6px;
+      flex-shrink: 0;
+      display: flex;
+      align-items: center;
+      gap: 3px;
+    }
+
+    .dim-label::before {
+      content: '·';
+      color: #bbb;
+    }
+
+    .sub-label {
+      font-size: 11.5px;
+      color: #bbb;
+      min-width: 56px;
+      padding-top: 6px;
+      flex-shrink: 0;
+    }
+
+    .chips-wrap {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 7px;
+      align-items: center;
+      flex: 1;
+    }
+
+    .chip {
+      padding: 4px 12px;
+      border-radius: 20px;
+      font-size: 12.5px;
+      cursor: pointer;
+      border: 1.5px solid #e2e2e2;
+      background: #fff;
+      color: #666;
+      transition: all .12s;
+      user-select: none;
+      white-space: nowrap;
+      line-height: 1.4;
+    }
+
+    .chip:hover {
+      border-color: #c0c0c0;
+      color: #333;
+    }
+
+    .chip.none-active {
+      background: #1a1a1a;
+      border-color: #1a1a1a;
+      color: #fff;
+      font-weight: 500;
+    }
+
+    .chip.none-active:hover {
+      background: #333;
+      border-color: #333;
+    }
+
+    .chip.selected {
+      background: var(--mint);
+      border-color: var(--mint);
+      color: #fff;
+      font-weight: 500;
+    }
+
+    .chip.selected:hover {
+      opacity: 0.9;
+    }
+
+    .placeholder-text {
+      font-size: 12.5px;
+      color: #ccc;
+      font-style: italic;
+      padding: 6px 0;
+    }
+
+    .preview-section {
+      margin-top: 18px;
+      padding: 14px 18px;
+      background: #fafafa;
+      border-radius: 8px;
+      border: 1.5px solid #ebebeb;
+    }
+
+    .preview-header {
+      font-size: 11px;
+      color: #aaa;
+      font-weight: 600;
+      text-transform: uppercase;
+      letter-spacing: 0.08em;
+      margin-bottom: 10px;
+    }
+
+    .preview-tags {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 6px;
+      min-height: 34px;
+      align-items: center;
+      margin-bottom: 10px;
+    }
+
+    .preview-tag {
+      background: #1a1a1a;
+      color: #fff;
+      padding: 4px 11px;
+      border-radius: 7px;
+      font-size: 13px;
+    }
+
+    .preview-sep {
+      color: #d0d0d0;
+      font-size: 14px;
+      font-weight: 300;
+    }
+
+    .preview-empty {
+      color: #ccc;
+      font-size: 13px;
+    }
+
+    .preview-path {
+      font-size: 12px;
+      color: #bbb;
+      margin-bottom: 12px;
+      min-height: 18px;
+      font-family: monospace;
+      letter-spacing: 0.01em;
+    }
+
+    .btn-row {
+      display: flex;
+      gap: 8px;
+      flex-wrap: wrap;
+    }
+
+    .btn {
+      border: 1px solid var(--line);
+      background: #fff;
+      color: var(--ink);
+      border-radius: 8px;
+      padding: 8px 12px;
+      font: inherit;
+      cursor: pointer;
+      font-size: 13px;
+      transition: all 0.15s;
+    }
+
+    .btn:hover {
+      background: #f5f5f5;
+    }
+
+    .btn.active {
+      color: #fff;
+      background: var(--ink);
+      border-color: var(--ink);
+    }
+
+    .btn-dark {
+      background: #1a1a1a;
+      color: #fff;
+      border-color: #1a1a1a;
+    }
+
+    .btn-dark:hover {
+      background: #333;
+      border-color: #333;
+    }
+
+    /* Console logger styling */
+    .exec-console {
+      background: #181512;
+      color: #dcd3c3;
+      border: 1px solid #3d352e;
+      border-radius: 12px;
+      padding: 16px;
+      font-family: ui-monospace, Menlo, Monaco, Consolas, monospace;
+      box-shadow: var(--shadow);
+      display: flex;
+      flex-direction: column;
+      height: 320px;
+    }
+
+    .exec-console-head {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      border-bottom: 1px solid #3d352e;
+      padding-bottom: 8px;
+      margin-bottom: 8px;
+      font-size: 12px;
+      color: #a3968d;
+    }
+
+    .exec-console-output {
+      flex: 1;
+      margin: 0;
+      padding: 4px;
+      overflow-y: auto;
+      white-space: pre-wrap;
+      word-break: break-all;
+      font-size: 13px;
+      line-height: 1.45;
+      color: #e5d8c5;
+    }
+
+    /* Stats container styling */
+    .stats {
+      display: grid;
+      grid-template-columns: repeat(4, 1fr);
+      gap: 12px;
+      margin-top: 16px;
+    }
+
+    .stat {
+      background: var(--panel);
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 14px;
+      box-shadow: var(--shadow);
+      min-height: 86px;
+    }
+
+    .stat strong {
+      display: block;
+      font-size: 26px;
+      line-height: 1.1;
+    }
+
+    .stat span {
+      color: var(--muted);
+      font-size: 13px;
+    }
+
+    /* Filters and Grid */
+    .toolbar {
+      display: flex;
+      gap: 10px;
+      align-items: center;
+      justify-content: space-between;
+      margin-top: 20px;
+      margin-bottom: 18px;
+      flex-wrap: wrap;
+    }
+
+    .filters {
+      display: flex;
+      gap: 8px;
+      flex-wrap: wrap;
+    }
+
+    select {
+      border: 1px solid var(--line);
+      background: #fff;
+      color: var(--ink);
+      border-radius: 8px;
+      padding: 9px 12px;
+      font: inherit;
+      min-width: 150px;
+    }
+
+    .grid {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 16px;
+    }
+
+    @media (max-width: 768px) {
+      .grid {
+        grid-template-columns: 1fr;
+      }
+    }
+
+    /* Results cards */
+    .result {
+      min-height: 480px;
+      background: var(--panel);
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      overflow: hidden;
+      box-shadow: var(--shadow);
+      display: flex;
+      flex-direction: column;
+      position: relative;
+      transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.25s ease;
+    }
+
+    .result:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 22px 50px rgba(41, 35, 28, .12);
+    }
+
+    .result.discard {
+      border-color: rgba(178, 75, 99, 0.15);
+    }
+
+    .discard-overlay {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      background: rgba(251, 250, 247, 0.85);
+      backdrop-filter: blur(5px);
+      -webkit-backdrop-filter: blur(5px);
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      padding: 20px;
+      text-align: center;
+      z-index: 5;
+      opacity: 1;
+      transition: opacity 0.25s ease;
+      pointer-events: none;
+    }
+
+    .result.discard:hover .discard-overlay {
+      opacity: 0;
+    }
+
+    .discard-badge {
+      background: var(--soft-rose);
+      color: var(--rose);
+      border: 1px solid rgba(178, 75, 99, 0.25);
+      padding: 6px 16px;
+      border-radius: 999px;
+      font-size: 13px;
+      font-weight: 700;
+      text-transform: uppercase;
+      letter-spacing: 1px;
+      margin-bottom: 12px;
+      box-shadow: 0 2px 8px rgba(178, 75, 99, 0.1);
+    }
+
+    .discard-reason {
+      color: var(--muted);
+      font-size: 13px;
+      line-height: 1.6;
+      max-width: 90%;
+      margin: 0 auto;
+      display: -webkit-box;
+      -webkit-line-clamp: 6;
+      -webkit-box-orient: vertical;
+      overflow: hidden;
+      font-weight: 500;
+    }
+
+    .thumbs {
+      display: grid;
+      grid-template-columns: repeat(3, 1fr);
+      gap: 2px;
+      height: 140px;
+      background: #eee7dc;
+      overflow: hidden;
+    }
+
+    .thumbs img {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      display: block;
+      background: #eee7dc;
+    }
+
+    .thumbs img:first-child:nth-last-child(1) {
+      grid-column: 1 / -1;
+    }
+
+    .body {
+      padding: 15px;
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+    }
+
+    .meta {
+      display: flex;
+      justify-content: space-between;
+      gap: 10px;
+      color: var(--muted);
+      font-size: 12px;
+      margin-bottom: 8px;
+    }
+
+    .platform {
+      color: #fff;
+      border-radius: 999px;
+      padding: 2px 8px;
+      font-weight: 700;
+      white-space: nowrap;
+    }
+
+    .p-xhs { background: var(--rose); }
+    .p-gzh { background: var(--mint); }
+    .p-zhihu { background: var(--cyan); }
+    .p-x { background: var(--cyan); }
+    .p-bili { background: #e06d93; }
+    .p-douyin { background: #24211d; }
+    .p-sph { background: #07c160; }
+    .p-youtube { background: #c4302b; }
+    .p-github { background: #24292e; }
+    .p-toutiao { background: #f04142; }
+    .p-weibo { background: #e6162d; }
+
+    h2 {
+      margin: 0 0 8px;
+      font-size: 17px;
+      line-height: 1.3;
+      letter-spacing: 0;
+    }
+
+    .excerpt {
+      color: var(--muted);
+      font-size: 13px;
+      display: -webkit-box;
+      -webkit-line-clamp: 4;
+      -webkit-box-orient: vertical;
+      overflow: hidden;
+      margin-bottom: 10px;
+    }
+
+    .tags {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 6px;
+      margin: 10px 0;
+    }
+
+    .tag {
+      background: #f2eee7;
+      border-radius: 999px;
+      padding: 2px 8px;
+      font-size: 11.5px;
+      color: #514a42;
+    }
+
+    .scorebar {
+      margin-top: auto;
+    }
+
+    .overall {
+      display: flex;
+      align-items: end;
+      justify-content: space-between;
+      border-top: 1px solid var(--line);
+      padding-top: 10px;
+    }
+
+    .score {
+      font-size: 32px;
+      line-height: .9;
+      font-weight: 800;
+    }
+
+    .decision {
+      color: var(--mint);
+      font-weight: 800;
+    }
+
+    .decision.discard {
+      color: var(--amber);
+    }
+
+    .group-snapshot {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
+      gap: 5px;
+      margin-top: 8px;
+    }
+
+    .group-pill {
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 5px 6px;
+      background: #fff;
+      min-width: 0;
+    }
+
+    .group-pill span {
+      display: block;
+      color: var(--muted);
+      font-size: 11px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+
+    .group-pill strong {
+      display: block;
+      font-size: 14px;
+      line-height: 1.1;
+    }
+
+    .actions {
+      display: flex;
+      gap: 8px;
+      margin-top: 12px;
+    }
+
+    .actions a,
+    .actions button {
+      flex: 1;
+      text-align: center;
+      text-decoration: none;
+      color: var(--ink);
+      background: #fff;
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 8px 10px;
+      font-size: 13px;
+    }
+
+    /* Dialog styling */
+    dialog {
+      width: min(980px, calc(100vw - 28px));
+      max-height: calc(100vh - 32px);
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 0;
+      box-shadow: 0 28px 90px rgba(0, 0, 0, .25);
+    }
+
+    dialog::backdrop {
+      background: rgba(38, 33, 27, .42);
+    }
+
+    dialog.fullscreen {
+      width: 100vw !important;
+      max-width: 100vw !important;
+      height: 100vh !important;
+      max-height: 100vh !important;
+      border: none !important;
+      border-radius: 0 !important;
+      margin: 0 !important;
+      top: 0 !important;
+      left: 0 !important;
+    }
+
+    dialog.fullscreen #modalContentProcedure {
+      height: calc(100vh - 120px) !important;
+      max-height: none !important;
+    }
+
+    dialog.fullscreen #modalContentDetail {
+      height: calc(100vh - 120px) !important;
+      max-height: none !important;
+      overflow-y: auto !important;
+    }
+
+    .modal-head {
+      position: sticky;
+      top: 0;
+      background: #fff;
+      border-bottom: 1px solid var(--line);
+      padding: 16px;
+      z-index: 2;
+      display: flex;
+      justify-content: space-between;
+      gap: 14px;
+      align-items: start;
+    }
+
+    .modal-head h3 {
+      margin: 0;
+      font-size: 20px;
+      line-height: 1.25;
+    }
+
+    .modal-content {
+      display: grid;
+      grid-template-columns: 1.1fr .9fr;
+      gap: 18px;
+      padding: 16px;
+    }
+
+    .modal-content > section,
+    .modal-content > aside {
+      min-width: 0;
+    }
+
+    .section-title {
+      margin: 18px 0 8px;
+      font-weight: 800;
+    }
+
+    .raw {
+      white-space: pre-wrap;
+      background: #faf7f1;
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      padding: 12px;
+      max-height: 330px;
+      overflow: auto;
+      color: #3d3831;
+      font-size: 13px;
+    }
+
+    .images {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 8px;
+    }
+
+    .images img {
+      width: 100%;
+      max-height: 260px;
+      object-fit: contain;
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      background: #f1ece4;
+    }
+
+    .scores {
+      display: grid;
+      gap: 12px;
+    }
+
+    .score-group {
+      border: 1px solid var(--line);
+      border-radius: 8px;
+      background: #fff;
+      overflow: hidden;
+    }
+
+    .score-group-head {
+      display: flex;
+      justify-content: space-between;
+      gap: 10px;
+      align-items: center;
+      padding: 10px 11px;
+      background: #faf7f1;
+      border-bottom: 1px solid var(--line);
+      font-size: 13px;
+      font-weight: 800;
+    }
+
+    .score-group-head small {
+      color: var(--muted);
+      font-weight: 700;
+      white-space: nowrap;
+    }
+
+    .score-group-body {
+      display: grid;
+      gap: 8px;
+      padding: 10px;
+    }
+
+    .score-row {
+      display: grid;
+      grid-template-columns: 128px 1fr 34px;
+      gap: 10px;
+      align-items: center;
+      font-size: 13px;
+    }
+
+    .score-row.missing {
+      color: #a39b91;
+    }
+
+    .score-row.missing .meter span {
+      display: none;
+    }
+
+    .meter {
+      height: 9px;
+      border-radius: 999px;
+      background: #eee7dc;
+      overflow: hidden;
+    }
+
+    .meter span {
+      display: block;
+      height: 100%;
+      width: calc(var(--v) * 20%);
+      background: var(--rose);
+    }
+
+    .rubric-note {
+      background: var(--soft-cyan);
+      border-left: 4px solid var(--cyan);
+      padding: 10px 12px;
+      color: #254c5d;
+      border-radius: 4px;
+      font-size: 13px;
+    }
+
+    .modal-tabs {
+      display: flex;
+      gap: 4px;
+      padding: 0 16px;
+      border-bottom: 1px solid var(--line);
+      background: #faf7f1;
+    }
+    .modal-tab {
+      background: transparent;
+      border: none;
+      border-bottom: 3px solid transparent;
+      border-radius: 0;
+      padding: 10px 16px;
+      font-size: 14px;
+      font-weight: 600;
+      color: var(--muted);
+      cursor: pointer;
+      transition: all 0.2s ease;
+    }
+    .modal-tab:hover {
+      color: var(--ink);
+      background: rgba(0, 0, 0, 0.02);
+    }
+    .modal-tab.active {
+      color: var(--mint);
+      border-bottom-color: var(--mint);
+    }
+
+    /* Rating card styling */
+    .sc-card {
+      background: #fff;
+      border: 1px solid var(--line);
+      border-radius: 12px;
+      padding: 16px 20px;
+      margin-bottom: 16px;
+      box-shadow: 0 4px 15px rgba(0,0,0,0.02);
+    }
+    
+    .sc-card-head {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 14px;
+      border-bottom: 1px solid #f3f0ea;
+      padding-bottom: 10px;
+    }
+    
+    .sc-card-head .title {
+      font-size: 15px;
+      font-weight: 700;
+      display: flex;
+      align-items: center;
+      gap: 8px;
+    }
+    
+    .sc-card-head .badge {
+      background: #eef2ff;
+      color: #2563eb;
+      font-size: 11px;
+      padding: 2px 6px;
+      border-radius: 4px;
+      font-weight: 700;
+    }
+    
+    .sc-card-head .avg-score {
+      font-size: 13.5px;
+      color: var(--muted);
+      font-weight: 600;
+    }
+    
+    .sc-card-head .avg-score strong {
+      font-size: 24px;
+      color: #2563eb;
+      font-weight: 800;
+      margin-left: 4px;
+    }
+    
+    .sc-sub-header {
+      font-size: 12px;
+      color: var(--muted);
+      font-weight: 700;
+      margin: 14px 0 8px;
+      border-bottom: 1px dashed #f0ebd8;
+      padding-bottom: 4px;
+      text-transform: uppercase;
+      letter-spacing: 0.5px;
+    }
+    
+    .sc-row {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 6px 0;
+      font-size: 13px;
+      gap: 10px;
+    }
+    
+    .sc-row .label {
+      color: var(--ink);
+      font-weight: 500;
+      flex: 1;
+      min-width: 100px;
+      word-break: break-all;
+    }
+    
+    .sc-row .bar-wrap {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      width: 160px;
+      flex-shrink: 0;
+    }
+    
+    .sc-row .bar {
+      height: 6px;
+      background: #eee7dc;
+      border-radius: 999px;
+      flex: 1;
+      overflow: hidden;
+    }
+    
+    .sc-row .bar-fill {
+      height: 100%;
+      background: #2563eb;
+      border-radius: 999px;
+      width: calc(var(--v) * 10%);
+    }
+    
+    .sc-row .value {
+      font-weight: 700;
+      font-size: 13px;
+      width: 20px;
+      text-align: right;
+    }
+    
+    .sc-row .info-icon {
+      cursor: pointer;
+      color: #9ca3af;
+      transition: color 0.15s ease;
+      font-size: 13px;
+      user-select: none;
+    }
+    
+    .sc-row .info-icon:hover {
+      color: #3b82f6;
+    }
+  </style>
+</head>
+
+<body>
+  <header>
+    <div class="wrap">
+      <div class="eyebrow">Content Search · runs_new/ 实时 · 维度构建器</div>
+      <h1>新 Query 搜索与评估</h1>
+      <p class="lede" id="lede">正在扫描 runs_new/ 目录...</p>
+    </div>
+  </header>
+
+  <main class="app-container">
+    <!-- Sidebar: previously searched queries -->
+    <aside class="sidebar">
+      <h3>
+        <span>已检索 Query 列表</span>
+        <button class="btn" onclick="loadData(true)" style="padding: 3px 8px; font-size: 11px;">刷新</button>
+      </h3>
+      <div class="sidebar-list" id="querySidebarList">
+        <!-- Dynamic sidebar items -->
+      </div>
+    </aside>
+
+    <!-- Main Workspace -->
+    <div style="display: flex; flex-direction: column; gap: 24px; min-width: 0;">
+      <!-- Query Builder Panel -->
+      <section class="builder-card">
+        <h3>Query 词组织器</h3>
+        <div class="dimensions" id="dimensions"></div>
+
+        <div class="preview-section">
+          <div class="preview-header">Query 预览</div>
+          <div class="preview-tags" id="previewTags">
+            <span class="preview-empty">(请选择维度标签)</span>
+          </div>
+          <div class="preview-path" id="previewPath"></div>
+          
+          <div style="display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; border-top: 1px solid var(--line); padding-top: 12px; margin-top: 12px;">
+            <div style="display: flex; flex-direction: column; gap: 8px; align-items: flex-start;">
+              <div style="display: flex; align-items: center; gap: 16px;">
+                <span style="font-size: 13.5px; font-weight: 700; color: var(--muted);">检索渠道:</span>
+                <div style="display: flex; gap: 10px; flex-wrap: wrap;" id="platformCheckboxes">
+                  <!-- 小红书 -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="xhs" checked onchange="togglePlatformInput(this)"> 小红书
+                    </label>
+                    <input type="number" name="platform_count" data-platform="xhs" min="1" max="100" value="20" style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink);">
+                  </div>
+                  <!-- 知乎 -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="zhihu" checked onchange="togglePlatformInput(this)"> 知乎
+                    </label>
+                    <input type="number" name="platform_count" data-platform="zhihu" min="1" max="100" value="20" style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink);">
+                  </div>
+                  <!-- 公众号 -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s; opacity: 0.6;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="gzh" onchange="togglePlatformInput(this)"> 公众号
+                    </label>
+                    <input type="number" name="platform_count" data-platform="gzh" min="1" max="100" value="20" disabled style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink); opacity: 0.4;">
+                  </div>
+                  <!-- 抖音 -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s; opacity: 0.6;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="douyin" onchange="togglePlatformInput(this)"> 抖音
+                    </label>
+                    <input type="number" name="platform_count" data-platform="douyin" min="1" max="100" value="20" disabled style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink); opacity: 0.4;">
+                  </div>
+                  <!-- 视频号 -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s; opacity: 0.6;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="sph" onchange="togglePlatformInput(this)"> 视频号
+                    </label>
+                    <input type="number" name="platform_count" data-platform="sph" min="1" max="100" value="20" disabled style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink); opacity: 0.4;">
+                  </div>
+                  <!-- YouTube -->
+                  <div style="display: inline-flex; align-items: center; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; transition: opacity 0.15s; opacity: 0.6;">
+                    <label style="font-size: 13.5px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; font-weight: 500;">
+                      <input type="checkbox" name="platform" value="youtube" onchange="togglePlatformInput(this)"> YouTube
+                    </label>
+                    <input type="number" name="platform_count" data-platform="youtube" min="1" max="100" value="20" disabled style="width: 38px; border: 1px solid #d1d5db; border-radius: 4px; padding: 1px 3px; font-size: 11.5px; text-align: center; font-weight: bold; outline: none; color: var(--ink); opacity: 0.4;">
+                  </div>
+                </div>
+              </div>
+              <div id="channelCountsRow" style="font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 8px; flex-wrap: wrap;"></div>
+            </div>
+            <div class="btn-row">
+              <button class="btn btn-dark" id="searchBtn" onclick="runSearchAndEvaluate()" style="background: var(--mint); color: #fff; border-color: var(--mint); font-weight: 700; padding: 6px 18px;">⚡ 搜索并评估</button>
+              <button class="btn" onclick="clearAll()">清空</button>
+            </div>
+          </div>
+        </div>
+      </section>
+
+      <!-- Subprocess log card -->
+      <section class="exec-console" id="execConsoleCard" style="display: none;">
+        <div class="exec-console-head">
+          <span id="consoleTitle">🚀 搜索并评估任务控制台 - 准备就绪</span>
+          <span id="consoleStatus" style="font-weight: bold; color: var(--amber);">idle</span>
+        </div>
+        <pre class="exec-console-output" id="consoleOutput"></pre>
+      </section>
+
+      <!-- Grid Cards Area -->
+      <div id="resultsArea" style="display: none;">
+        <div class="stats" id="stats"></div>
+
+        <div class="toolbar">
+          <div class="filters" id="platformFilterWrap"></div>
+          
+          <div style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
+            <div class="threshold-control">
+              <span style="color: var(--muted); font-size: 12px; font-weight: 700;">相关性过滤阈值:</span>
+              <input type="number" id="relThreshold" min="0" max="10" step="0.5" value="4.0" 
+                     oninput="renderGrid(); renderHead();" 
+                     style="width: 55px; border: 1px solid #d1d5db; border-radius: 4px; padding: 2px 6px; font-weight: 700; text-align: center; color: #2563eb; outline: none;">
+            </div>
+
+            <button id="reevalBtn" class="btn" onclick="reevalCurrentQuery()" style="background: #faf7f1; color: var(--amber); border-color: rgba(184, 121, 24, 0.3);">♻️ 重新评估当前结果</button>
+            <button id="editSpecBtn" class="btn" onclick="openSpecEditor()" style="background: #f0f7f6; color: var(--cyan); border-color: rgba(42, 111, 143, 0.3);">📝 编辑 Spec 提示词</button>
+            
+            <div style="display: flex; align-items: center; gap: 4px; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; font-size: 13px; font-weight: 600; box-shadow: var(--shadow); height: 38px;">
+              <span style="color: var(--muted); font-size: 12px; font-weight: 700;">提取并发:</span>
+              <input type="number" id="batchConcurrency" min="1" max="16" value="4" 
+                     style="width: 40px; border: 1px solid #d1d5db; border-radius: 4px; padding: 2px 4px; font-weight: 700; text-align: center; color: var(--ink); outline: none;">
+            </div>
+            <button id="batchProcBtn" class="btn" onclick="batchExtractProcedures()" style="background: #f0fdf4; color: var(--mint); border-color: rgba(31, 138, 112, 0.3); font-weight: 600; height: 38px;">⚡ 一键提取工序</button>
+            
+            <select id="sort" onchange="renderGrid()">
+              <option value="score">按综合分排序</option>
+              <option value="date">按发布时间排序</option>
+              <option value="platform">按平台排序</option>
+            </select>
+          </div>
+        </div>
+
+        <div class="grid" id="grid"></div>
+      </div>
+    </div>
+  </main>
+
+  <!-- Details Dialog Modal -->
+  <dialog id="detailDialog">
+    <div class="modal-head">
+      <div>
+        <div id="modalMeta" class="meta"></div>
+        <h3 id="modalTitle"></h3>
+      </div>
+      <div style="display: flex; gap: 8px; align-items: center;">
+        <button id="toggleFullscreenBtn" class="btn" onclick="toggleModalFullscreen()" style="padding: 5px 12px; font-weight: 600; font-size: 12.5px;">📺 全屏</button>
+        <button class="btn" onclick="detailDialog.close()">关闭</button>
+      </div>
+    </div>
+    
+    <div class="modal-tabs" id="modalTabs" style="display: none;">
+      <button class="modal-tab active" onclick="switchModalTab('detail')" id="tabDetailBtn">帖子详情</button>
+      <button class="modal-tab" onclick="switchModalTab('procedure')" id="tabProcedureBtn">对应工序</button>
+    </div>
+
+    <div class="modal-content" id="modalContentDetail">
+      <section>
+        <div class="rubric-note" id="modalReason"></div>
+        <div class="section-title">抓取文本节选</div>
+        <div class="raw" id="modalText"></div>
+        <div class="section-title">图片预览</div>
+        <div class="images" id="modalImages"></div>
+      </section>
+      <aside>
+        <div class="section-title" style="display: flex; justify-content: space-between; align-items: center;">
+          <span>评分详情</span>
+          <span id="modalOverallScore" style="font-size: 13px; font-weight: 700; color: var(--muted); display: flex; align-items: center; gap: 4px; background: #faf7f1; border: 1px solid var(--line); padding: 3px 10px; border-radius: 6px;">
+            综合评分 <strong style="font-size: 19px; color: #2563eb; font-weight: 900; line-height: 1;" id="modalOverallScoreVal">—</strong>
+          </span>
+        </div>
+        <div class="scores" id="modalScores"></div>
+        <div class="section-title">类型 / 命中 query</div>
+        <div class="tags" id="modalTags"></div>
+      </aside>
+    </div>
+
+    <div id="modalContentProcedure" style="display: none; min-height: 500px; height: calc(100vh - 180px); max-height: 700px; padding: 16px; box-sizing: border-box; flex-direction: column;">
+      <div id="procSubTabs" style="display:flex; gap:6px; margin-bottom:12px; flex-shrink:0;">
+        <button class="modal-tab active" id="subTabAgent" onclick="switchProcSubTab('agent')">🛠️ Agent 工序</button>
+        <button class="modal-tab" id="subTabModel" onclick="switchProcSubTab('model')">⚡ 大模型工序</button>
+      </div>
+      <div id="procActionBar" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--line); flex-shrink: 0;">
+        <div style="font-size: 14px; font-weight: bold; color: var(--ink);" id="procStatusText">工序状态: 检测中...</div>
+        <div style="display: flex; gap: 8px;" id="procActionBtns"></div>
+      </div>
+      
+      <div style="flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column;">
+        <div id="procSetupPanel" style="display: none; flex-direction: column; align-items: center; justify-content: center; text-align: center; height: 100%; padding: 40px 20px;">
+          <div style="font-size: 36px; margin-bottom: 16px;">✨</div>
+          <h4 style="margin: 0 0 10px; font-size: 18px;">提取本帖工序</h4>
+          <p id="procSetupHint" style="color: var(--muted); font-size: 14px; max-width: 500px; margin: 0 0 24px;">该帖子目前尚未生成对应的结构化工序。请在下方选择提取引擎和模型,点击开始提取。</p>
+
+          <div style="display: flex; gap: 16px; margin-bottom: 24px; text-align: left; background: #fff; border: 1px solid var(--line); padding: 16px; border-radius: 8px; box-shadow: var(--shadow);">
+            <div id="procEngineWrap">
+              <label style="display: block; font-size: 12px; font-weight: bold; margin-bottom: 6px; color: var(--muted);">提取引擎 (Engine)</label>
+              <select id="procEngineSelect" style="min-width: 180px; padding: 6px 10px;" onchange="onProcEngineChange()">
+                <option value="cyber_runner">Cyber Runner (自研/OpenRouter)</option>
+                <option value="claude_sdk">Claude SDK (OAuth)</option>
+              </select>
+            </div>
+            <div>
+              <label style="display: block; font-size: 12px; font-weight: bold; margin-bottom: 6px; color: var(--muted);">AI 模型 (Model)</label>
+              <select id="procModelSelect" style="min-width: 240px; padding: 6px 10px;"></select>
+            </div>
+          </div>
+          
+          <div style="display:flex; gap:12px; align-items:center; justify-content:center;">
+            <button id="startProcBtn" class="btn btn-dark" onclick="startProcedureExtraction()" style="background: var(--mint); border-color: var(--mint); padding: 10px 24px; font-size: 15px; font-weight: bold;">开始提取工序</button>
+            <button id="startModelBtn" class="btn" onclick="startModelExtraction()" title="单次大模型直出 workflow.json(不走 agent/validate 循环),用上方下拉选的模型" style="background:#1f6feb; color:#fff; border-color:#1f6feb; padding: 10px 24px; font-size: 15px; font-weight: bold;">🤖 模型提取</button>
+          </div>
+        </div>
+        
+        <div id="procConsolePanel" style="display: none; flex-direction: column; height: 100%; min-height: 0; background: #1e1b18; border: 1px solid #3d352e; border-radius: 8px; overflow: hidden;">
+          <div style="background: #2b2520; padding: 6px 12px; border-bottom: 1px solid #3d352e; display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; font-family: monospace; font-size: 12px; color: #a3968d;">
+            <span>TERMINAL CONSOLE</span>
+            <span id="procConsoleStatus">idle</span>
+          </div>
+          <pre id="procConsoleOutput" style="flex: 1; margin: 0; padding: 12px; overflow: auto; font-family: ui-monospace, Menlo, Monaco, Consolas, monospace; font-size: 13px; line-height: 1.45; color: #cbbba9; background: #1e1b18; white-space: pre-wrap; word-break: break-all;"></pre>
+        </div>
+        
+        <iframe id="procedureIframe" style="display: none; width: 100%; height: 100%; border: 1px solid var(--line); border-radius: 8px; background: #fff;" referrerpolicy="no-referrer"></iframe>
+      </div>
+    </div>
+  </dialog>
+
+  <!-- Spec Prompt Editor Dialog -->
+  <dialog id="specEditorDialog" style="width: 850px; max-width: 95%; border: 1px solid var(--line); border-radius: 12px; padding: 0; box-shadow: var(--shadow); background: var(--panel);">
+    <div style="display: flex; justify-content: space-between; align-items: center; background: #faf7f1; border-bottom: 1px solid var(--line); padding: 16px 20px;">
+      <h3 style="margin: 0; font-size: 18px; color: var(--ink); font-weight: 800;">📝 编辑 Spec 提示词规范</h3>
+      <button onclick="document.getElementById('specEditorDialog').close()" class="btn" style="padding: 5px 14px; font-weight: 600; font-size: 12px;">关闭</button>
+    </div>
+    <div style="padding: 20px;">
+      <div style="margin-bottom: 16px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">
+        <span style="font-size: 13.5px; font-weight: 700; color: var(--ink);">选择提示词文件:</span>
+        <select id="specFileSelect" onchange="loadSpecFileContent()" style="padding: 6px 12px; border-radius: 8px; border: 1px solid #d1d5db; outline: none; min-width: 320px; font-family: monospace; font-size: 13px; font-weight: 600;">
+        </select>
+        <span id="specLoadStatus" style="font-size: 13px; font-weight: 600;"></span>
+      </div>
+      <div style="position: relative; margin-bottom: 20px;">
+        <textarea id="specContentTextarea" style="width: 100%; height: 500px; font-family: ui-monospace, Menlo, Monaco, Consolas, monospace; font-size: 13.5px; line-height: 1.55; padding: 14px; border: 1px solid #d1d5db; border-radius: 8px; box-sizing: border-box; outline: none; background: #fafaf9; color: #1f2937; resize: vertical; border-left: 4px solid var(--cyan);"></textarea>
+      </div>
+      <div style="display: flex; justify-content: flex-end; gap: 12px; align-items: center; border-top: 1px solid var(--line); padding-top: 16px;">
+        <span id="specSaveStatus" style="font-size: 13.5px; font-weight: 700; margin-right: auto;"></span>
+        <button onclick="document.getElementById('specEditorDialog').close()" class="btn" style="background: #f3f4f6;">取消</button>
+        <button onclick="saveSpecFileContent()" class="btn" style="background: var(--mint); color: #fff; border-color: var(--mint); font-weight: bold;">💾 保存修改</button>
+      </div>
+    </div>
+  </dialog>
+
+  <script>
+    const DIMS = [
+      {
+        "id": "tool_type",
+        "label": "工具类型",
+        "type": "flat",
+        "items": ["AI", "桌面 APP", "云端 Web", "API·CLI", "插件扩展"]
+      },
+      {
+        "id": "substance",
+        "label": "实质",
+        "type": "flat",
+        "items": ["人像", "信息"]
+      },
+      {
+        "id": "form",
+        "label": "形式",
+        "type": "flat",
+        "items": ["真实感", "写实风格", "实景拍摄", "版面设计", "版面解构"]
+      },
+      {
+        "id": "modality",
+        "label": "模态",
+        "type": "flat",
+        "items": ["图片", "视频"]
+      },
+      {
+        "id": "action",
+        "label": "动作",
+        "type": "hierarchical",
+        "data": {
+          "获取": {
+            "搜索": ["检索", "下载"],
+            "查询": ["调取"],
+            "录入": ["上传", "拍摄", "录音", "键入"],
+            "引用": ["选取"]
+          },
+          "提取": {
+            "物理提取": ["裁切", "抠取", "抽帧"],
+            "化学提取": ["识别", "反推", "解构"]
+          },
+          "生成": {
+            "元素生成": ["元素生成"],
+            "关系生成": ["数组生成", "结构生成"]
+          },
+          "修改": {
+            "增": ["添加", "叠加"],
+            "删": ["抹除", "剪除"],
+            "变": ["重述", "风格化", "转换", "替换", "调整", "增强"]
+          }
+        }
+      },
+      {
+        "id": "type",
+        "label": "类型",
+        "type": "hierarchical",
+        "data": {
+          "程序控制类型": {
+            "指令": ["提示词", "负向提示词", "描述"],
+            "参数": ["生成参数", "规格参数", "模型权重"],
+            "评估": ["评分", "评语"],
+            "流程": ["工作流", "批处理"]
+          },
+          "数据复用类型": {
+            "原子": ["数字人", "版式"],
+            "序列": ["模板"]
+          },
+          "内容类型": {
+            "素材/化学变化": ["参考图", "参考视频", "参考音频", "对标内容", "分镜图", "转场", "蒙版", "控制图", "运动轨迹", "滤镜", "构图布局"],
+            "素材/物理变化": ["截图", "视频片段", "转场片段", "关键帧", "音效", "特效"],
+            "半成品/序列": ["大纲", "脚本", "分镜脚本", "剪辑脚本", "配音文案"],
+            "半成品/原子": ["底图", "样图", "分镜视频"],
+            "半成品/组合": ["图层组合", "拼图"],
+            "准成品": ["歌词", "配音", "BGM", "字幕", "标题", "正文"],
+            "成品": ["成品图", "视频成品", "合成图"]
+          },
+          "知识类型": {
+            "知识库": ["知识库"]
+          }
+        }
+      },
+      {
+        "id": "suffix",
+        "label": "后缀",
+        "type": "flat",
+        "default": null,
+        "items": ["怎么做"]
+      }
+    ];
+
+    const builderState = {};
+    DIMS.forEach(d => { builderState[d.id] = { l0: d.default !== undefined ? d.default : null, l1: null, l2: null }; });
+
+    let DATA = { queries: [], actions: [], types: [], matrix: [] };
+    let st = { qi: -1, fi: 0, channel: "all", sort: "score" };
+    let VIEW = [];
+    
+    let currentProcTask = null;
+    let procPollInterval = null;
+    let isLogViewActive = false;
+    let searchPollInterval = null;
+    let reevalPollIntervals = {};
+
+    // Chip Rendering functions
+    function makeRow(indent) {
+      const el = document.createElement('div');
+      el.className = 'level-row' + (indent ? ' indent' : '');
+      return el;
+    }
+
+    function makeLabel(text, small) {
+      const el = document.createElement('span');
+      el.className = small ? 'sub-label' : 'dim-label';
+      el.textContent = text;
+      return el;
+    }
+
+    function makeChipsWrap() {
+      const el = document.createElement('div');
+      el.className = 'chips-wrap';
+      return el;
+    }
+
+    function makeChip(label, cls, onClick) {
+      const btn = document.createElement('button');
+      btn.className = 'chip ' + cls;
+      btn.textContent = label;
+      btn.addEventListener('click', onClick);
+      return btn;
+    }
+
+    function renderDim(dimId) {
+      const dim = DIMS.find(d => d.id === dimId);
+      const grp = document.querySelector('.dim-group[data-id="' + dimId + '"]');
+      grp.innerHTML = '';
+      const sel = builderState[dimId];
+
+      if (dim.type === 'flat') {
+        const row = makeRow(false);
+        row.appendChild(makeLabel(dim.label, false));
+        if (!dim.items || !dim.items.length) {
+          const ph = document.createElement('span');
+          ph.className = 'placeholder-text';
+          ph.textContent = '(待填写)';
+          row.appendChild(ph);
+        } else {
+          const chips = makeChipsWrap();
+          chips.appendChild(makeChip('无', sel.l0 == null ? 'none-active' : '', () => {
+            builderState[dimId].l0 = null; renderDim(dimId); updateQueryPreview();
+          }));
+          dim.items.forEach(item => {
+            chips.appendChild(makeChip(item, sel.l0 === item ? 'selected' : '', () => {
+              builderState[dimId].l0 = item; renderDim(dimId); updateQueryPreview();
+            }));
+          });
+          row.appendChild(chips);
+        }
+        grp.appendChild(row);
+        return;
+      }
+
+      if (dim.type === 'hierarchical') {
+        const row0 = makeRow(false);
+        row0.appendChild(makeLabel(dim.label, false));
+        const chips0 = makeChipsWrap();
+        chips0.appendChild(makeChip('无', sel.l0 == null ? 'none-active' : '', () => {
+          builderState[dimId] = { l0: null, l1: null, l2: null }; renderDim(dimId); updateQueryPreview();
+        }));
+        Object.keys(dim.data).forEach(key => {
+          chips0.appendChild(makeChip(key, sel.l0 === key ? 'selected' : '', () => {
+            builderState[dimId] = { l0: key, l1: null, l2: null }; renderDim(dimId); updateQueryPreview();
+          }));
+        });
+        row0.appendChild(chips0);
+        grp.appendChild(row0);
+
+        if (sel.l0 && dim.data[sel.l0]) {
+          const L1keys = Object.keys(dim.data[sel.l0]);
+          const row1 = makeRow(true);
+          row1.appendChild(makeLabel(sel.l0, true));
+          const chips1 = makeChipsWrap();
+          chips1.appendChild(makeChip('无', sel.l1 == null ? 'none-active' : '', () => {
+            builderState[dimId].l1 = null; builderState[dimId].l2 = null; renderDim(dimId); updateQueryPreview();
+          }));
+          L1keys.forEach(key => {
+            chips1.appendChild(makeChip(key, sel.l1 === key ? 'selected' : '', () => {
+              builderState[dimId].l1 = key; builderState[dimId].l2 = null; renderDim(dimId); updateQueryPreview();
+            }));
+          });
+          row1.appendChild(chips1);
+          grp.appendChild(row1);
+        }
+
+        if (sel.l0 && sel.l1 && dim.data[sel.l0] && dim.data[sel.l0][sel.l1]) {
+          const L2items = dim.data[sel.l0][sel.l1];
+          const row2 = makeRow(true);
+          row2.appendChild(makeLabel(sel.l1, true));
+          const chips2 = makeChipsWrap();
+          chips2.appendChild(makeChip('无', sel.l2 == null ? 'none-active' : '', () => {
+            builderState[dimId].l2 = null; renderDim(dimId); updateQueryPreview();
+          }));
+          L2items.forEach(item => {
+            chips2.appendChild(makeChip(item, sel.l2 === item ? 'selected' : '', () => {
+              builderState[dimId].l2 = item; renderDim(dimId); updateQueryPreview();
+            }));
+          });
+          row2.appendChild(chips2);
+          grp.appendChild(row2);
+        }
+      }
+    }
+
+    function getSelections() {
+      return DIMS.map(dim => {
+        const sel = builderState[dim.id];
+        if (dim.type === 'flat') {
+          return sel.l0 ? { dim: dim.label, path: [sel.l0], val: sel.l0 } : null;
+        }
+        if (dim.type === 'hierarchical') {
+          const path = [sel.l0, sel.l1, sel.l2].filter(Boolean);
+          if (!path.length) return null;
+          return { dim: dim.label, path, val: path[path.length - 1] };
+        }
+        return null;
+      }).filter(Boolean);
+    }
+
+    function updateQueryPreview() {
+      const sels = getSelections();
+      const tagsEl = document.getElementById('previewTags');
+      const pathEl = document.getElementById('previewPath');
+      tagsEl.innerHTML = '';
+      pathEl.textContent = '';
+
+      if (!sels.length) {
+        tagsEl.innerHTML = '<span class="preview-empty">(请选择维度标签)</span>';
+        return;
+      }
+
+      sels.forEach((s, i) => {
+        if (i > 0) {
+          const sep = document.createElement('span');
+          sep.className = 'preview-sep';
+          sep.textContent = '·';
+          tagsEl.appendChild(sep);
+        }
+        const tag = document.createElement('span');
+        tag.className = 'preview-tag';
+        tag.textContent = s.val;
+        tagsEl.appendChild(tag);
+      });
+
+      pathEl.textContent = sels.map(s => '[' + s.dim + '] ' + s.path.join(' › ')).join('   ');
+    }
+
+    function getQueryText() {
+      return getSelections().map(s => s.val).join(' ');
+    }
+
+    function clearAll() {
+      DIMS.forEach(d => { builderState[d.id] = { l0: null, l1: null, l2: null }; });
+      DIMS.forEach(d => renderDim(d.id));
+      updateQueryPreview();
+    }
+
+    // Sidebar navigation functions
+    function renderSidebar() {
+      const list = document.getElementById("querySidebarList");
+      list.innerHTML = "";
+      if (!DATA.queries.length) {
+        list.innerHTML = `<div style="color: #ccc; font-size: 13px; text-align: center; padding: 24px 0;">(暂无检索记录,请在上方组织新 Query 进行搜索)</div>`;
+        document.getElementById("resultsArea").style.display = "none";
+        return;
+      }
+      DATA.queries.forEach((q, i) => {
+        const div = document.createElement("div");
+        div.className = "sidebar-item" + (st.qi === i ? " active" : "");
+        div.innerHTML = `
+          <div class="q-text">${esc(q.original_q)}</div>
+          <div class="meta">
+            <span>采纳/命中: <strong>${q.hits}</strong></span>
+            <span>总帖数: ${q.tot}</span>
+          </div>
+        `;
+        div.onclick = () => {
+          st.qi = i;
+          st.fi = 0;
+          st.channel = "all";
+          renderSidebar();
+          renderGrid();
+          renderHead();
+          document.getElementById("resultsArea").style.display = "block";
+        };
+        list.appendChild(div);
+      });
+    }
+
+    function togglePlatformInput(chk) {
+      const parent = chk.closest('div');
+      if (!parent) return;
+      const numInput = parent.querySelector('input[type="number"]');
+      if (!numInput) return;
+      if (chk.checked) {
+        numInput.disabled = false;
+        numInput.style.opacity = "1";
+        parent.style.opacity = "1";
+      } else {
+        numInput.disabled = true;
+        numInput.style.opacity = "0.4";
+        parent.style.opacity = "0.6";
+      }
+    }
+
+    // Search and evaluation trigger & log polling
+    function runSearchAndEvaluate() {
+      const q = getQueryText();
+      if (!q) {
+        alert("请先选择标签,组成要检索的 Query 词!");
+        return;
+      }
+      
+      const checkboxes = document.querySelectorAll('input[name="platform"]:checked');
+      if (checkboxes.length === 0) {
+        alert("请至少选择一个目标检索渠道!");
+        return;
+      }
+      const platforms = Array.from(checkboxes).map(c => {
+        const parent = c.closest('div');
+        const numInput = parent ? parent.querySelector('input[type="number"]') : null;
+        const count = numInput ? parseInt(numInput.value) : 20;
+        return `${c.value}:${count}`;
+      }).join(",");
+      
+      const searchBtn = document.getElementById("searchBtn");
+      searchBtn.disabled = true;
+      searchBtn.textContent = "⌛ 正在启动...";
+      
+      const consoleCard = document.getElementById("execConsoleCard");
+      consoleCard.style.display = "flex";
+      const consoleOutput = document.getElementById("consoleOutput");
+      consoleOutput.textContent = "⏳ 正在向服务器提交搜索评估任务...\n";
+      
+      const statusSpan = document.getElementById("consoleStatus");
+      statusSpan.textContent = "starting";
+      statusSpan.style.color = "var(--amber)";
+      document.getElementById("consoleTitle").textContent = `🚀 搜索并评估任务控制台 - [${q}]`;
+      
+      fetch("/api/run_search_eval", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ query: q, platforms: platforms })
+      })
+      .then(r => r.json().then(d => ({ ok: r.ok, d })))
+      .then(({ ok, d }) => {
+        if (!ok) {
+          searchBtn.disabled = false;
+          searchBtn.textContent = "⚡ 搜索并评估";
+          statusSpan.textContent = "failed";
+          statusSpan.style.color = "var(--rose)";
+          consoleOutput.textContent += `❌ 启动失败: ${d.error || "未知错误"}\n`;
+          return;
+        }
+        
+        statusSpan.textContent = "running";
+        statusSpan.style.color = "#00ff00";
+        consoleOutput.textContent += `✓ 搜评流程异步启动完成,正在获取实时日志...\n`;
+        
+        startSearchPolling(q);
+      })
+      .catch(err => {
+        searchBtn.disabled = false;
+        searchBtn.textContent = "⚡ 搜索并评估";
+        statusSpan.textContent = "failed";
+        statusSpan.style.color = "var(--rose)";
+        consoleOutput.textContent += `❌ 请求失败: ${err}\n`;
+      });
+    }
+
+    function startSearchPolling(q) {
+      if (searchPollInterval) clearInterval(searchPollInterval);
+      
+      const statusSpan = document.getElementById("consoleStatus");
+      const consoleOutput = document.getElementById("consoleOutput");
+      const searchBtn = document.getElementById("searchBtn");
+      
+      const poll = () => {
+        fetch(`/api/search_eval_status?q=${encodeURIComponent(q)}`)
+          .then(r => r.json())
+          .then(d => {
+            if (d.status === "success") {
+              clearInterval(searchPollInterval);
+              searchPollInterval = null;
+              
+              statusSpan.textContent = "success";
+              statusSpan.style.color = "var(--mint)";
+              searchBtn.disabled = false;
+              searchBtn.textContent = "⚡ 搜索并评估";
+              
+              consoleOutput.textContent += "\n🎉 搜评流程全部成功执行完毕,已保存于 runs_new 下!\n";
+              consoleOutput.scrollTop = consoleOutput.scrollHeight;
+              
+              loadData(true);
+            } else if (d.status === "failed") {
+              clearInterval(searchPollInterval);
+              searchPollInterval = null;
+              
+              statusSpan.textContent = "failed";
+              statusSpan.style.color = "var(--rose)";
+              searchBtn.disabled = false;
+              searchBtn.textContent = "⚡ 搜索并评估";
+              
+              consoleOutput.textContent += `\n❌ 搜评任务执行失败: ${d.error || "未知原因"}\n`;
+              consoleOutput.scrollTop = consoleOutput.scrollHeight;
+              
+              loadData(true);
+            }
+          });
+          
+        fetch(`/api/search_eval_log?q=${encodeURIComponent(q)}`)
+          .then(r => r.json())
+          .then(d => {
+            if (d.log) {
+              consoleOutput.textContent = d.log;
+              consoleOutput.scrollTop = consoleOutput.scrollHeight;
+            }
+          });
+      };
+      
+      poll();
+      searchPollInterval = setInterval(poll, 1500);
+    }
+
+    // Grid rendering logic
+    function curForm() {
+      return st.qi === -1 ? null : (DATA.queries[st.qi] ? DATA.queries[st.qi].forms[st.fi] : null);
+    }
+
+    function isItemDiscarded(it) {
+      if (it.anomaly) return false;
+      const input = document.getElementById("relThreshold");
+      const userThreshold = input ? parseFloat(input.value) : 4.0;
+      
+      let isDiscard = false;
+      const relVal = it.production_relevance !== null && it.production_relevance !== undefined ? parseFloat(it.production_relevance) : null;
+      if (relVal !== null && !isNaN(relVal)) {
+        if (relVal < userThreshold) {
+          isDiscard = true;
+        }
+      }
+      
+      if (it.recency_hard !== null && it.recency_hard !== undefined && it.recency_hard < 2) {
+        isDiscard = true;
+      }
+      
+      if (it.overall !== null && it.overall !== undefined) {
+        if (it.overall < 6.0) {
+          isDiscard = true;
+        }
+      }
+      return isDiscard;
+    }
+
+    function updateThresholdLimits() {
+      const input = document.getElementById("relThreshold");
+      if (input) {
+        input.max = "10";
+        input.value = "4.0";
+        input.step = "0.5";
+      }
+    }
+
+    function updateChannelCounts() {
+      const f = curForm();
+      const div = document.getElementById("channelCountsRow");
+      if (!div) return;
+      if (!f || !f.results || f.results.length === 0) {
+        div.innerHTML = "";
+        return;
+      }
+      const counts = {};
+      f.results.forEach(r => {
+        const pk = r.platformKey || "other";
+        counts[pk] = (counts[pk] || 0) + 1;
+      });
+      const parts = [];
+      const sortedKeys = Object.keys(counts).sort((a, b) => counts[b] - counts[a]);
+      sortedKeys.forEach(pk => {
+        const name = PLATC[pk] || pk;
+        parts.push(`
+          <span style="background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 2px 8px; display: inline-flex; align-items: center; gap: 6px; font-weight: 500; font-size: 11.5px; box-shadow: 0 1px 3px rgba(0,0,0,0.02);">
+            <span class="platform p-${pk}" style="width: 7px; height: 7px; border-radius: 50%; display: inline-block; padding: 0; margin-right: 0;"></span>
+            <span style="color: var(--muted);">${name}</span>
+            <strong style="color: var(--ink); font-weight: 700;">${counts[pk]}</strong>
+          </span>
+        `);
+      });
+      div.innerHTML = `<span style="font-weight: 700; color: var(--muted); margin-right: 4px; font-size: 12px;">已收录帖数:</span>` + parts.join("");
+    }
+
+    function renderHead() {
+      const f = curForm();
+      const div = document.getElementById("stats");
+      if (!f) {
+        div.innerHTML = "";
+        const cDiv = document.getElementById("channelCountsRow");
+        if (cDiv) cDiv.innerHTML = "";
+        return;
+      }
+      
+      const total = f.results.length;
+      const report = f.results.filter(r => !r.anomaly && !isItemDiscarded(r)).length;
+      const discard = f.results.filter(r => !r.anomaly && isItemDiscarded(r)).length;
+      const failed = f.results.filter(r => r.anomaly).length;
+
+      div.innerHTML = `
+        <div class="stat"><strong>${total}</strong><span>平台抓取总数</span></div>
+        <div class="stat" style="color:var(--mint)"><strong>${report}</strong><span>采纳上报案例</span></div>
+        <div class="stat" style="color:var(--amber)"><strong>${discard}</strong><span>不符过滤弃用</span></div>
+        <div class="stat" style="color:var(--rose)"><strong>${failed}</strong><span>评估失败/异常</span></div>
+      `;
+      updateChannelCounts();
+    }
+
+    function renderGrid() {
+      const f = curForm();
+      const grid = document.getElementById("grid");
+      if (!f) { grid.innerHTML = `<div style="grid-column:1/-1;text-align:center;color:#999;padding:40px 0;">暂无数据</div>`; return; }
+      
+      // Filter platforms checkboxes and render buttons
+      const platforms = Array.from(new Set(f.results.map(r => r.platformKey)));
+      const filterWrap = document.getElementById("platformFilterWrap");
+      
+      let pFilterHtml = `<button class="btn ${st.channel === 'all' ? 'active' : ''}" onclick="setChannel('all')">全部渠道 (${f.results.length})</button>`;
+      platforms.forEach(p => {
+        const count = f.results.filter(r => r.platformKey === p).length;
+        pFilterHtml += `<button class="btn ${st.channel === p ? 'active' : ''}" onclick="setChannel('${p}')">${PLATC[p] || p} (${count})</button>`;
+      });
+      filterWrap.innerHTML = pFilterHtml;
+
+      let list = f.results;
+      if (st.channel !== "all") {
+        list = list.filter(r => r.platformKey === st.channel);
+      }
+
+      // Sort
+      const sortBy = document.getElementById("sort").value;
+      if (sortBy === "score") {
+        list.sort((a, b) => (b.overall || 0) - (a.overall || 0));
+      } else if (sortBy === "date") {
+        list.sort((a, b) => (b.date || "").localeCompare(a.date || ""));
+      } else if (sortBy === "platform") {
+        list.sort((a, b) => (a.platformKey || "").localeCompare(b.platformKey || ""));
+      }
+
+      if (list.length === 0) {
+        grid.innerHTML = `<div style="grid-column:1/-1;text-align:center;color:#999;padding:40px 0;">无筛选结果</div>`;
+        return;
+      }
+
+      grid.innerHTML = list.map((it, i) => {
+        const idx = f.results.indexOf(it);
+        const isDiscard = isItemDiscarded(it);
+        const overallStr = it.overall !== null && it.overall !== undefined ? it.overall.toFixed(1) : '—';
+        const discardOverlay = (isDiscard && !it.anomaly) ? `
+          <div class="discard-overlay">
+            <div class="discard-badge">已过滤</div>
+            <div class="discard-reason">${esc(it.reason || "时效性或综合质量均分未达标")}</div>
+          </div>
+        ` : '';
+
+        const thumbs = it.images && it.images.length > 0 ? `
+          <div class="thumbs">
+            ${it.images.map(img => `<img src="${esc(img)}" referrerpolicy="no-referrer" onerror="this.src='${NOIMG}'">`).join('')}
+          </div>
+        ` : '';
+
+        return `
+          <div class="result ${isDiscard ? 'discard' : ''}" data-idx="${idx}">
+            ${discardOverlay}
+            ${thumbs}
+            <div class="body">
+              <div class="meta">
+                <span class="platform p-${it.platformKey}">${esc(it.platform)}</span>
+                <span>${esc(it.date)}</span>
+              </div>
+              <h2 title="${esc(it.title)}">${esc(it.title)}</h2>
+              <div class="excerpt">${esc(it.text)}</div>
+              
+              <div class="tags">
+                ${(it.tools || []).map(t => `<span class="tag">${esc(t)}</span>`).join('')}
+              </div>
+
+              <div class="scorebar">
+                <div class="overall">
+                  <span class="decision ${isDiscard ? 'discard' : ''}">${isDiscard ? '已过滤' : '上报'}</span>
+                  <span class="score" style="color: ${it.anomaly ? 'var(--rose)' : '#2563eb'}">${overallStr}</span>
+                </div>
+                <div class="group-snapshot">
+                  ${groupSnapshot(it)}
+                </div>
+                <div class="actions">
+                  <a href="${esc(it.url)}" target="_blank" onclick="event.stopPropagation()">🌐 源链接</a>
+                  <button onclick="event.stopPropagation(); showDetail(${idx})">🔍 查看详情</button>
+                </div>
+              </div>
+            </div>
+          </div>
+        `;
+      }).join('');
+    }
+
+    function setChannel(ch) {
+      st.channel = ch;
+      renderGrid();
+    }
+
+    // Modal dialogue script
+    function esc(s) {
+      return (s === undefined || s === null ? "" : String(s)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
+    }
+
+    const PLATC = { xhs: "小红书", gzh: "公众号", zhihu: "知乎", x: "X", bili: "B站", douyin: "抖音", sph: "视频号", youtube: "YouTube", github: "GitHub", toutiao: "头条", weibo: "微博" };
+    const NOIMG = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='400'%3E%3Crect width='600' height='400' fill='%23eee7dc'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%236f6961' font-size='28'%3ENo image%3C/text%3E%3C/svg%3E";
+
+    const scoreGroupsNew = [
+      { id: "relevance", title: "相关性", short: "相关", keys: ["relevance_production", "relevance_query"] },
+      { id: "fixed", title: "固定维度", short: "固定", keys: ["recency", "popularity", "feedback"] },
+      { id: "usecase", title: "用例维度", short: "用例", keys: ["realism", "expressiveness"] },
+      { id: "dynamic", title: "动态维度", short: "动态", keys: [] }
+    ];
+
+    function makeModalRow(label, scoreKey, it) {
+      const rawV = it.scores[scoreKey];
+      const v = (rawV !== undefined && rawV !== null) ? parseFloat(rawV) : NaN;
+      const hasScore = !isNaN(v);
+      const valStr = hasScore ? (Number.isInteger(v) ? v : v.toFixed(1)) : '-';
+      const barV = hasScore ? v : 0;
+      const reason = it.score_reasons ? it.score_reasons[scoreKey] : '';
+      const infoIcon = reason ? `<span class="info-icon" onclick="pinScoreReason(this, '${esc(label)}', '${esc(scoreKey)}')" title="评判理由: ${esc(reason)}" style="margin-left: 5px; cursor: pointer; color: var(--muted); opacity: 0.7;">ⓘ</span>` : '';
+      return `
+        <div class="sc-row ${!hasScore ? 'missing' : ''}">
+          <span class="label">${esc(label)}</span>
+          <div class="bar-wrap">
+            <div class="bar">
+              <div class="bar-fill" style="--v: ${barV}"></div>
+            </div>
+            <span class="value">${valStr}</span>
+            ${infoIcon}
+          </div>
+        </div>
+      `;
+    }
+
+    function pinScoreReason(el, label, key) {
+      alert(`${label} 判定理由:\n\n${el.title.replace("评判理由: ", "")}`);
+    }
+
+    function groupAverage(it, g) {
+      if (!it.scores) return null;
+      let keys = g.keys;
+      if (g.id === "dynamic") {
+        keys = [];
+        if (it.knowledge_type && (it.knowledge_type.includes("procedure") || it.knowledge_type.includes("工序"))) {
+          keys.push("procedure_completeness", "procedure_input", "procedure_implementation", "procedure_output", "procedure_generality");
+        }
+        if (it.knowledge_type && (it.knowledge_type.includes("step") || it.knowledge_type.includes("能力") || it.knowledge_type.includes("步骤"))) {
+          keys.push("step_input", "step_implementation", "step_output", "step_generality");
+        }
+        if (it.knowledge_type && (it.knowledge_type.includes("tool") || it.knowledge_type.includes("工具"))) {
+          keys.push("tool_boundary", "tool_comparison", "tool_specificity", "tool_example", "tool_limits");
+        }
+      }
+      const vs = keys.map(k => parseFloat(it.scores[k])).filter(v => !isNaN(v));
+      return vs.length ? vs.reduce((a, b) => a + b, 0) / vs.length : null;
+    }
+
+    function getQualityAverage(it) {
+      if (!it.scores) return null;
+      const keys = ["recency", "popularity", "feedback", "realism", "expressiveness"];
+      if (it.knowledge_type && (it.knowledge_type.includes("procedure") || it.knowledge_type.includes("工序"))) {
+        keys.push("procedure_completeness", "procedure_input", "procedure_implementation", "procedure_output", "procedure_generality");
+      }
+      if (it.knowledge_type && (it.knowledge_type.includes("step") || it.knowledge_type.includes("能力") || it.knowledge_type.includes("步骤"))) {
+        keys.push("step_input", "step_implementation", "step_output", "step_generality");
+      }
+      if (it.knowledge_type && (it.knowledge_type.includes("tool") || it.knowledge_type.includes("工具"))) {
+        keys.push("tool_boundary", "tool_comparison", "tool_specificity", "tool_example", "tool_limits");
+      }
+      const vs = keys.map(k => parseFloat(it.scores[k])).filter(v => !isNaN(v));
+      return vs.length ? vs.reduce((a, b) => a + b, 0) / vs.length : null;
+    }
+
+    function fmt(v) {
+      return v === null ? "N/A" : v.toFixed(1);
+    }
+
+    function groupSnapshot(it) {
+      const relAvg = groupAverage(it, scoreGroupsNew[0]);
+      const qualAvg = getQualityAverage(it);
+      return `
+        <div class="group-pill"><span>相关度</span><strong>${fmt(relAvg)}</strong></div>
+        <div class="group-pill"><span>制作质量</span><strong>${fmt(qualAvg)}</strong></div>
+      `;
+    }
+
+    function renderNewScores(it) {
+      const relAvg = groupAverage(it, scoreGroupsNew[0]);
+      const relAvgStr = relAvg !== null ? relAvg.toFixed(1) : 'N/A';
+      
+      let relevanceHtml = `
+        <div class="sc-card">
+          <div class="sc-card-head">
+            <div class="title"><span class="badge">01</span>相关性</div>
+            <div class="avg-score">均分 <strong>${relAvgStr}</strong><span style="font-size:12px;color:#9ca3af;">/10</span></div>
+          </div>
+          <div class="sc-card-body">
+            ${makeModalRow("和内容制作知识相关", "relevance_production", it)}
+            ${makeModalRow("和 query 相关", "relevance_query", it)}
+          </div>
+        </div>
+      `;
+
+      const qualAvg = getQualityAverage(it);
+      const qualAvgStr = qualAvg !== null ? qualAvg.toFixed(1) : 'N/A';
+
+      let qualityHtml = `
+        <div class="sc-card">
+          <div class="sc-card-head">
+            <div class="title"><span class="badge">02</span>质量</div>
+            <div class="avg-score">均分 <strong>${qualAvgStr}</strong><span style="font-size:12px;color:#9ca3af;">/10</span></div>
+          </div>
+          <div class="sc-card-body">
+            <div class="sc-sub-header">固定维度</div>
+            ${makeModalRow("时效性", "recency", it)}
+            ${makeModalRow("热度性", "popularity", it)}
+            ${makeModalRow("评论反馈", "feedback", it)}
+            
+            <div class="sc-sub-header">用例</div>
+            ${makeModalRow("真实感 (非AI)", "realism", it)}
+            ${makeModalRow("表现力", "expressiveness", it)}
+      `;
+
+      let dynamicHtml = '';
+      if (it.knowledge_type && (it.knowledge_type.includes("procedure") || it.knowledge_type.includes("工序"))) {
+        dynamicHtml += `
+          <div class="sc-sub-header">工序</div>
+          ${makeModalRow("流程完整性", "procedure_completeness", it)}
+          ${makeModalRow("输入完整性", "procedure_input", it)}
+          ${makeModalRow("实现完整性", "procedure_implementation", it)}
+          ${makeModalRow("输出完整性", "procedure_output", it)}
+          ${makeModalRow("泛化性", "procedure_generality", it)}
+        `;
+      }
+      if (it.knowledge_type && (it.knowledge_type.includes("step") || it.knowledge_type.includes("能力") || it.knowledge_type.includes("步骤"))) {
+        dynamicHtml += `
+          <div class="sc-sub-header">能力</div>
+          ${makeModalRow("输入完整性", "step_input", it)}
+          ${makeModalRow("实现完整性", "step_implementation", it)}
+          ${makeModalRow("输出完整性", "step_output", it)}
+          ${makeModalRow("泛化性", "step_generality", it)}
+        `;
+      }
+      if (it.knowledge_type && (it.knowledge_type.includes("tool") || it.knowledge_type.includes("工具"))) {
+        dynamicHtml += `
+          <div class="sc-sub-header">工具</div>
+          ${makeModalRow("能力边界覆盖", "tool_boundary", it)}
+          ${makeModalRow("有效比较", "tool_comparison", it)}
+          ${makeModalRow("参数/接口具体性", "tool_specificity", it)}
+          ${makeModalRow("实操示例", "tool_example", it)}
+          ${makeModalRow("版本&限制", "tool_limits", it)}
+        `;
+      }
+
+      qualityHtml += dynamicHtml + `
+          </div>
+        </div>
+      `;
+
+      return relevanceHtml + qualityHtml;
+    }
+
+    let detailDialogIndex = -1;
+    function showDetail(idx) {
+      detailDialogIndex = idx;
+      const f = curForm();
+      const it = f.results[idx];
+      
+      const isDiscard = isItemDiscarded(it);
+      const overallStr = it.overall !== null && it.overall !== undefined ? it.overall.toFixed(1) : '—';
+      
+      document.getElementById("modalMeta").innerHTML = `
+        <span class="platform p-${it.platformKey}">${esc(it.platform)}</span>
+        <span>发布日期: ${esc(it.date)}</span>
+        <span style="margin-left:auto; font-family: monospace;">CaseID: ${esc(it.case_id)}</span>
+      `;
+      document.getElementById("modalTitle").textContent = it.title;
+      document.getElementById("modalReason").textContent = it.reason || "时效与品质良好";
+      document.getElementById("modalText").textContent = it.text;
+      
+      document.getElementById("modalOverallScoreVal").textContent = overallStr;
+      document.getElementById("modalOverallScoreVal").style.color = it.anomaly ? "var(--rose)" : "#2563eb";
+      
+      document.getElementById("modalScores").innerHTML = renderNewScores(it);
+      
+      const tags = (it.tools || []).map(t => `<span class="tag">${esc(t)}</span>`).join("");
+      const foundBy = (it.found_by || []).map(q => `<span class="tag" style="background:#e0f2fe; color:#0369a1;">${esc(q)}</span>`).join("");
+      document.getElementById("modalTags").innerHTML = tags + foundBy;
+      
+      const imgDiv = document.getElementById("modalImages");
+      imgDiv.innerHTML = "";
+      if (it.images && it.images.length > 0) {
+        it.images.forEach(img => {
+          imgDiv.innerHTML += `<img src="${esc(img)}" referrerpolicy="no-referrer" onclick="window.open(this.src)" style="cursor:zoom-in;">`;
+        });
+      } else {
+        imgDiv.innerHTML = `<div style="grid-column:1/-1; color:#999; font-size:13px;">无图片</div>`;
+      }
+
+      const tabs = document.getElementById("modalTabs");
+      tabs.style.display = "flex";
+      
+      switchModalTab("detail");
+      
+      const dialog = document.getElementById("detailDialog");
+      dialog.classList.remove("fullscreen");
+      document.getElementById("toggleFullscreenBtn").textContent = "📺 全屏";
+      dialog.showModal();
+    }
+
+    function switchModalTab(tab) {
+      const dBtn = document.getElementById("tabDetailBtn");
+      const pBtn = document.getElementById("tabProcedureBtn");
+      const dContent = document.getElementById("modalContentDetail");
+      const pContent = document.getElementById("modalContentProcedure");
+
+      if (tab === "detail") {
+        dBtn.classList.add("active");
+        pBtn.classList.remove("active");
+        dContent.style.display = "grid";
+        pContent.style.display = "none";
+      } else {
+        pBtn.classList.add("active");
+        dBtn.classList.remove("active");
+        dContent.style.display = "none";
+        pContent.style.display = "flex";
+
+        switchProcSubTab('agent');
+      }
+    }
+
+    // 工序子 tab:'agent'(Agent 工序,run_cyber 校验版)/ 'model'(大模型工序,单次直出)
+    let procVariant = 'agent';
+    function switchProcSubTab(variant) {
+      procVariant = variant;
+      document.getElementById('subTabAgent').classList.toggle('active', variant === 'agent');
+      document.getElementById('subTabModel').classList.toggle('active', variant === 'model');
+      loadProcedureState();
+    }
+
+    function toggleModalFullscreen() {
+      const dialog = document.getElementById("detailDialog");
+      const btn = document.getElementById("toggleFullscreenBtn");
+      if (dialog.classList.contains("fullscreen")) {
+        dialog.classList.remove("fullscreen");
+        btn.textContent = "📺 全屏";
+      } else {
+        dialog.classList.add("fullscreen");
+        btn.textContent = "📺 退出全屏";
+      }
+    }
+
+    // Procedure workflow extraction & terminal logger
+    function loadProcedureState() {
+      if (procPollInterval) clearInterval(procPollInterval);
+      
+      const f = curForm();
+      const it = f.results[detailDialogIndex];
+      const q = DATA.queries[st.qi].key;
+      const form = "A";
+      const caseId = it.case_id;
+
+      const setupPanel = document.getElementById("procSetupPanel");
+      const consolePanel = document.getElementById("procConsolePanel");
+      const iframe = document.getElementById("procedureIframe");
+      const statusText = document.getElementById("procStatusText");
+      const actionBtns = document.getElementById("procActionBtns");
+
+      setupPanel.style.display = "none";
+      consolePanel.style.display = "none";
+      iframe.style.display = "none";
+      actionBtns.innerHTML = "";
+      statusText.textContent = "正在检测工序状态...";
+
+      const vlabel = procVariant === 'model' ? '大模型工序' : 'Agent 工序';
+      fetch(`/api/procedure_status?q=${encodeURIComponent(q)}&form=${form}&case_id=${encodeURIComponent(caseId)}&variant=${procVariant}`)
+        .then(r => r.json())
+        .then(d => {
+          if (d.status === "success") {
+            statusText.textContent = `${vlabel}: 已提取`;
+            iframe.src = "/" + d.procedure_html;
+            iframe.style.display = "block";
+
+            actionBtns.innerHTML = `
+              <select id="procVersionSelect" onchange="onProcVersionChange()" title="历史版本" style="padding:5px 8px; font-size:12px; max-width:220px;"></select>
+              <button class="btn" onclick="showProcSetupPanel()">♻️ 重新生成</button>
+              <button class="btn" onclick="openProcLog('${esc(q)}', '${form}', '${esc(caseId)}', '${procVariant}')">📋 提取日志</button>
+            `;
+            loadProcVersions(q, form, caseId, procVariant);
+          } else if (d.status === "running") {
+            statusText.textContent = `${vlabel}: 正在提取中...`;
+            consolePanel.style.display = "flex";
+            pollProcLog(q, form, caseId, procVariant);
+          } else if (d.status === "failed") {
+            statusText.textContent = `${vlabel}: 提取失败`;
+            consolePanel.style.display = "flex";
+            document.getElementById("procConsoleOutput").textContent = d.error || "提取进程异常退出。";
+            actionBtns.innerHTML = `
+              <button class="btn" onclick="showProcSetupPanel()">♻️ 重试提取</button>
+              <button class="btn" onclick="openProcLog('${esc(q)}', '${form}', '${esc(caseId)}', '${procVariant}')">📋 提取日志</button>
+            `;
+          } else {
+            // not_started
+            statusText.textContent = `${vlabel}: 未提取`;
+            showProcSetupPanel();
+          }
+        });
+    }
+
+    // 版本下拉:列出该帖该变体的所有版本,切换即加载对应版本的 html
+    function loadProcVersions(q, form, caseId, variant) {
+      fetch(`/api/procedure_versions?q=${encodeURIComponent(q)}&form=${form}&case_id=${encodeURIComponent(caseId)}&variant=${variant}`)
+        .then(r => r.json())
+        .then(d => {
+          const sel = document.getElementById("procVersionSelect");
+          if (!sel) return;
+          const vers = d.versions || [];
+          if (!vers.length) { sel.style.display = "none"; return; }   // 真没版本才隐藏
+          sel.style.display = "";                                     // 有版本就显示(哪怕只有 1 个)
+          sel.innerHTML = vers.map(v =>
+            `<option value="${esc(v.version)}">${esc(v.version)}${v.is_latest ? " (最新)" : ""}${v.procedure_count != null ? " · " + v.procedure_count + "工序" : ""}</option>`
+          ).join("");
+          sel.value = d.latest || (vers[0] && vers[0].version) || "";
+        })
+        .catch(() => {});
+    }
+
+    function onProcVersionChange() {
+      const sel = document.getElementById("procVersionSelect");
+      if (!sel) return;
+      const v = sel.value;
+      const f = curForm();
+      const it = f.results[detailDialogIndex];
+      const q = DATA.queries[st.qi].key;
+      const caseId = it.case_id;
+      const iframe = document.getElementById("procedureIframe");
+      fetch(`/api/procedure_status?q=${encodeURIComponent(q)}&form=A&case_id=${encodeURIComponent(caseId)}&variant=${procVariant}&version=${encodeURIComponent(v)}`)
+        .then(r => r.json())
+        .then(d => {
+          if (d.status === "success" && d.procedure_html) {
+            iframe.src = "/" + d.procedure_html;
+            document.getElementById("procStatusText").textContent =
+              `${procVariant === 'model' ? '大模型工序' : 'Agent 工序'}: ${v}`;
+          } else {
+            alert("该版本无法加载: " + (d.error || "页面文件不存在"));
+          }
+        });
+    }
+
+    function showProcSetupPanel() {
+      document.getElementById("procSetupPanel").style.display = "flex";
+      document.getElementById("procConsolePanel").style.display = "none";
+      document.getElementById("procedureIframe").style.display = "none";
+
+      const isModel = procVariant === 'model';
+      // 引擎下拉只 Agent 工序用;模型下拉两者都用
+      document.getElementById("procEngineWrap").style.display = isModel ? "none" : "block";
+      document.getElementById("startProcBtn").style.display = isModel ? "none" : "inline-block";
+      document.getElementById("startModelBtn").style.display = isModel ? "inline-block" : "none";
+      document.getElementById("procSetupHint").textContent = isModel
+        ? "大模型工序:单次大模型直出 workflow.json(不走 agent / validate 循环)。选模型后点「🤖 模型提取」。"
+        : "Agent 工序:run_cyber 多轮 + validate 校验修错。选引擎和模型后点「开始提取工序」。";
+
+      const engine = isModel ? "cyber_runner" : document.getElementById("procEngineSelect").value;
+      populateModels(engine);
+      if (isModel) document.getElementById("procModelSelect").value = "anthropic/claude-sonnet-4-6";  // 大模型工序默认 claude
+    }
+
+    const MODELS_BY_ENGINE = {
+      cyber_runner: [
+        "google/gemini-3.1-flash-lite",
+        "google/gemini-3.5-flash",
+        "anthropic/claude-sonnet-4-6",
+        "anthropic/claude-3.5-haiku",
+        "anthropic/claude-3.5-sonnet",
+        "qwen/qwen-2.5-72b-instruct"
+      ],
+      claude_sdk: [
+        "claude-3-5-sonnet-20241022",
+        "claude-3-5-haiku-20241022"
+      ]
+    };
+
+    function populateModels(engine) {
+      const select = document.getElementById("procModelSelect");
+      const models = MODELS_BY_ENGINE[engine] || [];
+      select.innerHTML = models.map(m => `<option value="${esc(m)}">${esc(m)}</option>`).join("");
+    }
+
+    function onProcEngineChange() {
+      const engine = document.getElementById("procEngineSelect").value;
+      populateModels(engine);
+    }
+
+    function startProcedureExtraction() {
+      const f = curForm();
+      const it = f.results[detailDialogIndex];
+      const q = DATA.queries[st.qi].key;
+      const form = "A";
+      const caseId = it.case_id;
+
+      const engine = document.getElementById("procEngineSelect").value;
+      const model = document.getElementById("procModelSelect").value;
+
+      procVariant = 'agent';
+      document.getElementById("procSetupPanel").style.display = "none";
+      document.getElementById("procConsolePanel").style.display = "flex";
+      document.getElementById("procStatusText").textContent = "Agent 工序: 启动提取任务...";
+
+      fetch("/api/generate_procedure", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ q, form, case_id: caseId, engine, model })
+      })
+      .then(r => r.json())
+      .then(d => {
+        if (d.status === "started") {
+          pollProcLog(q, form, caseId, 'agent');
+        } else {
+          alert("提取任务启动失败: " + d.error);
+          showProcSetupPanel();
+        }
+      })
+      .catch(err => {
+        alert("网络请求出错: " + err);
+        showProcSetupPanel();
+      });
+    }
+
+    // 模型提取:单次大模型直出 workflow.json(不走 agent/validate 循环),用上方下拉选的模型
+    function startModelExtraction() {
+      const f = curForm();
+      const it = f.results[detailDialogIndex];
+      const q = DATA.queries[st.qi].key;
+      const form = "A";
+      const caseId = it.case_id;
+      const model = document.getElementById("procModelSelect").value;
+
+      procVariant = 'model';
+      document.getElementById("procSetupPanel").style.display = "none";
+      document.getElementById("procConsolePanel").style.display = "flex";
+      document.getElementById("procStatusText").textContent = "大模型工序: 启动模型提取...";
+
+      fetch("/api/extract_procedure_model", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ q, form, case_id: caseId, model })
+      })
+      .then(r => r.json())
+      .then(d => {
+        if (d.status === "started") {
+          pollProcLog(q, form, caseId, 'model');
+        } else {
+          alert("模型提取启动失败: " + d.error);
+          showProcSetupPanel();
+        }
+      })
+      .catch(err => {
+        alert("网络请求出错: " + err);
+        showProcSetupPanel();
+      });
+    }
+
+    function pollProcLog(q, form, caseId, variant) {
+      variant = variant || procVariant || 'agent';
+      const vlabel = variant === 'model' ? '大模型工序' : 'Agent 工序';
+      if (procPollInterval) clearInterval(procPollInterval);
+
+      const consoleOutput = document.getElementById("procConsoleOutput");
+      const statusText = document.getElementById("procStatusText");
+      const consoleStatus = document.getElementById("procConsoleStatus");
+
+      consoleStatus.textContent = "streaming";
+      consoleStatus.style.color = "#00ff00";
+
+      const poll = () => {
+        fetch(`/api/procedure_status?q=${encodeURIComponent(q)}&form=${form}&case_id=${encodeURIComponent(caseId)}&variant=${variant}`)
+          .then(r => r.json())
+          .then(d => {
+            if (d.status === "success") {
+              clearInterval(procPollInterval);
+              procPollInterval = null;
+              loadProcedureState();
+            } else if (d.status === "failed") {
+              clearInterval(procPollInterval);
+              procPollInterval = null;
+              statusText.textContent = `${vlabel}: 提取失败`;
+              consoleOutput.textContent += `\n❌ 进程异常退出: ${d.error || "未知原因"}`;
+              consoleStatus.textContent = "failed";
+              consoleStatus.style.color = "var(--rose)";
+
+              document.getElementById("procActionBtns").innerHTML = `
+                <button class="btn" onclick="showProcSetupPanel()">♻️ 重试提取</button>
+                <button class="btn" onclick="openProcLog('${esc(q)}', '${form}', '${esc(caseId)}', '${variant}')">📋 提取日志</button>
+              `;
+            }
+          });
+
+        fetch(`/api/procedure_log?q=${encodeURIComponent(q)}&form=${form}&case_id=${encodeURIComponent(caseId)}&variant=${variant}`)
+          .then(r => r.json())
+          .then(d => {
+            if (d.log) {
+              consoleOutput.textContent = d.log;
+              consoleOutput.scrollTop = consoleOutput.scrollHeight;
+            }
+          });
+      };
+
+      poll();
+      procPollInterval = setInterval(poll, 1500);
+    }
+
+    function openProcLog(q, form, caseId, variant) {
+      variant = variant || procVariant || 'agent';
+      const win = window.open("", "_blank");
+      win.document.write("<h3>加载日志中...</h3>");
+      fetch(`/api/procedure_log?q=${encodeURIComponent(q)}&form=${form}&case_id=${encodeURIComponent(caseId)}&variant=${variant}`)
+        .then(r => r.json())
+        .then(d => {
+          win.document.body.innerHTML = "";
+          const pre = win.document.createElement("pre");
+          pre.style.whiteSpace = "pre-wrap";
+          pre.style.fontFamily = "monospace";
+          pre.textContent = d.log || "无日志输出";
+          win.document.body.appendChild(pre);
+        })
+        .catch(err => {
+          win.document.body.innerHTML = "<h3>日志加载出错: " + err + "</h3>";
+        });
+    }
+
+    // Spec prompt editor script
+    const ALLOWED_SPEC_FILES = [
+      "README.md",
+      "tools.md",
+      "extraction/phase1-skeleton.md",
+      "extraction/phase2-normalize.md",
+      "extraction/phase3-finalize.md",
+      "taxonomy/type_suggestions.md"
+    ];
+
+    function openSpecEditor() {
+      const select = document.getElementById("specFileSelect");
+      select.innerHTML = ALLOWED_SPEC_FILES.map(f => `<option value="${esc(f)}">${esc(f)}</option>`).join("");
+      
+      document.getElementById("specLoadStatus").textContent = "";
+      document.getElementById("specSaveStatus").textContent = "";
+      document.getElementById("specContentTextarea").value = "";
+      
+      const dialog = document.getElementById("specEditorDialog");
+      dialog.showModal();
+      loadSpecFileContent();
+    }
+
+    function loadSpecFileContent() {
+      const file = document.getElementById("specFileSelect").value;
+      const status = document.getElementById("specLoadStatus");
+      const textarea = document.getElementById("specContentTextarea");
+      
+      status.textContent = "⏳ 正在读取...";
+      status.style.color = "var(--amber)";
+      textarea.disabled = true;
+      
+      fetch(`/api/spec_content?file=${encodeURIComponent(file)}`)
+        .then(r => r.json().then(d => ({ ok: r.ok, d })))
+        .then(({ ok, d }) => {
+          textarea.disabled = false;
+          if (ok) {
+            textarea.value = d.content || "";
+            status.textContent = "✓ 读取成功";
+            status.style.color = "var(--mint)";
+          } else {
+            status.textContent = "❌ 读取失败: " + (d.error || "未知错误");
+            status.style.color = "var(--rose)";
+          }
+        })
+        .catch(err => {
+          textarea.disabled = false;
+          status.textContent = "❌ 读取失败: " + err;
+          status.style.color = "var(--rose)";
+        });
+    }
+
+    function saveSpecFileContent() {
+      const file = document.getElementById("specFileSelect").value;
+      const content = document.getElementById("specContentTextarea").value;
+      const status = document.getElementById("specSaveStatus");
+      
+      status.textContent = "⏳ 正在保存到磁盘...";
+      status.style.color = "var(--amber)";
+      
+      fetch("/api/save_spec", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ file, content })
+      })
+      .then(r => r.json().then(d => ({ ok: r.ok, d })))
+      .then(({ ok, d }) => {
+        if (ok) {
+          status.textContent = "✅ 保存成功!新的 Prompt 规则已在本地生效。";
+          status.style.color = "var(--mint)";
+          setTimeout(() => {
+            if (status.textContent.includes("保存成功")) {
+              status.textContent = "";
+            }
+          }, 4000);
+        } else {
+          status.textContent = "❌ 保存失败: " + (d.error || "未知错误");
+          status.style.color = "var(--rose)";
+        }
+      })
+      .catch(err => {
+        status.textContent = "❌ 网络错误: " + err;
+        status.style.color = "var(--rose)";
+      });
+    }
+
+    // Re-eval current query result cases
+    function reevalCurrentQuery() {
+      if (st.qi === -1 || !DATA.queries[st.qi]) return;
+      const q = DATA.queries[st.qi].key;
+      const btn = document.getElementById("reevalBtn");
+      
+      btn.disabled = true;
+      btn.textContent = `♻️ 重评中 ${q}...`;
+
+      fetch("/api/reeval", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ q })
+      })
+      .then(r => r.json())
+      .then(d => {
+        if (d.status === "started") {
+          startReevalPolling(q);
+        } else {
+          alert("重评任务启动失败: " + d.error);
+          btn.disabled = false;
+          btn.textContent = "♻️ 重新评估当前结果";
+        }
+      })
+      .catch(err => {
+        alert("请求出错: " + err);
+        btn.disabled = false;
+        btn.textContent = "♻️ 重新评估当前结果";
+      });
+    }
+
+    function startReevalPolling(q) {
+      if (reevalPollIntervals[q]) return;
+      const btn = document.getElementById("reevalBtn");
+      
+      const poll = () => {
+        fetch(`/api/reeval_status?q=${encodeURIComponent(q)}`)
+          .then(r => r.json())
+          .then(d => {
+            const isCurrent = DATA.queries[st.qi] && DATA.queries[st.qi].key === q;
+            if (d.status === "success") {
+              clearInterval(reevalPollIntervals[q]);
+              delete reevalPollIntervals[q];
+              if (isCurrent) {
+                btn.disabled = false;
+                btn.textContent = '♻️ 重新评估当前结果';
+              }
+              loadData(true);
+              alert(`Query "${q}" 重新评估完成!已自动更新本页评分展示。`);
+            } else if (d.status === "failed") {
+              clearInterval(reevalPollIntervals[q]);
+              delete reevalPollIntervals[q];
+              if (isCurrent) {
+                btn.disabled = false;
+                btn.textContent = '♻️ 重新评估当前结果';
+              }
+              alert(`Query "${q}" 重新评估失败: ${d.error}`);
+            } else if (d.status === "running") {
+              if (isCurrent) {
+                btn.disabled = true;
+                btn.textContent = `♻️ 重评中 ${q}...`;
+              }
+            }
+          })
+          .catch(err => console.error("Poll error:", err));
+      };
+      
+      poll();
+      reevalPollIntervals[q] = setInterval(poll, 3000);
+    }
+
+    let batchProcPollInterval = null;
+
+    function batchExtractProcedures() {
+      if (st.qi === -1 || !DATA.queries[st.qi]) return;
+      const q = DATA.queries[st.qi].key;
+      const form = ['A', 'B', 'C'][st.fi];
+      
+      const concurrencyInput = document.getElementById("batchConcurrency");
+      const concurrency = concurrencyInput ? parseInt(concurrencyInput.value) : 4;
+      const model = "google/gemini-3.1-flash-lite"; 
+      
+      const btn = document.getElementById("batchProcBtn");
+      btn.disabled = true;
+      btn.textContent = "⚡ 提交任务...";
+      
+      const execConsoleCard = document.getElementById("execConsoleCard");
+      if (execConsoleCard) {
+        execConsoleCard.style.display = "flex";
+      }
+      const consoleTitle = document.getElementById("consoleTitle");
+      if (consoleTitle) consoleTitle.textContent = `🚀 批量工序提取控制台 - ${q}`;
+      const consoleStatus = document.getElementById("consoleStatus");
+      if (consoleStatus) {
+        consoleStatus.textContent = "running";
+        consoleStatus.style.color = "var(--mint)";
+      }
+      const consoleOutput = document.getElementById("consoleOutput");
+      if (consoleOutput) consoleOutput.textContent = `[info] 正在为 Query: "${q}" (Form ${form}) 提交批量工序提取任务...\n`;
+
+      fetch("/api/batch_generate_procedure", {
+        method: "POST",
+        headers: { "Content-Type": "application/json" },
+        body: JSON.stringify({ q, form, concurrency, model })
+      })
+      .then(r => r.json().then(d => ({ ok: r.ok, d })))
+      .then(({ ok, d }) => {
+        if (!ok) {
+          btn.disabled = false;
+          btn.textContent = "⚡ 一键提取工序";
+          if (consoleStatus) {
+            consoleStatus.textContent = "failed";
+            consoleStatus.style.color = "var(--rose)";
+          }
+          if (consoleOutput) consoleOutput.textContent += `[error] 提交失败: ${d.error || "未知错误"}\n`;
+          alert("提交批量提取任务失败: " + (d.error || "未知错误"));
+          return;
+        }
+        
+        if (consoleOutput) consoleOutput.textContent += `[info] 任务启动成功,后台 PID: ${d.pid || "N/A"}\n[info] 正在获取日志...\n`;
+        startBatchProcPolling(q);
+      })
+      .catch(err => {
+        btn.disabled = false;
+        btn.textContent = "⚡ 一键提取工序";
+        if (consoleStatus) {
+          consoleStatus.textContent = "failed";
+          consoleStatus.style.color = "var(--rose)";
+        }
+        if (consoleOutput) consoleOutput.textContent += `[error] 网络错误: ${err}\n`;
+        alert("网络错误: " + err);
+      });
+    }
+
+    function startBatchProcPolling(q) {
+      if (batchProcPollInterval) {
+        clearInterval(batchProcPollInterval);
+      }
+      
+      const btn = document.getElementById("batchProcBtn");
+      const consoleStatus = document.getElementById("consoleStatus");
+      const consoleOutput = document.getElementById("consoleOutput");
+      
+      const poll = () => {
+        fetch(`/api/batch_generate_status?q=${encodeURIComponent(q)}`)
+          .then(r => r.json())
+          .then(d => {
+            const isCurrent = DATA.queries[st.qi] && DATA.queries[st.qi].key === q;
+            
+            if (d.status === "success") {
+              clearInterval(batchProcPollInterval);
+              batchProcPollInterval = null;
+              if (isCurrent) {
+                btn.disabled = false;
+                btn.textContent = "⚡ 一键提取工序";
+                if (consoleStatus) {
+                  consoleStatus.textContent = "success";
+                  consoleStatus.style.color = "var(--mint)";
+                }
+              }
+              fetch(`/api/batch_generate_log?q=${encodeURIComponent(q)}`)
+                .then(r => r.json())
+                .then(ld => {
+                  if (isCurrent && ld.log && consoleOutput) {
+                    consoleOutput.textContent = ld.log + "\n🎉 批量工序提取已全部成功完成,已自动生成并编译 workflow json 和 HTML 文件!\n";
+                    consoleOutput.scrollTop = consoleOutput.scrollHeight;
+                  }
+                });
+              loadData(true);
+            } else if (d.status === "failed") {
+              clearInterval(batchProcPollInterval);
+              batchProcPollInterval = null;
+              if (isCurrent) {
+                btn.disabled = false;
+                btn.textContent = "⚡ 一键提取工序";
+                if (consoleStatus) {
+                  consoleStatus.textContent = "failed";
+                  consoleStatus.style.color = "var(--rose)";
+                }
+              }
+              fetch(`/api/batch_generate_log?q=${encodeURIComponent(q)}`)
+                .then(r => r.json())
+                .then(ld => {
+                  if (isCurrent && ld.log && consoleOutput) {
+                    consoleOutput.textContent = ld.log + `\n❌ 任务执行失败: ${d.error || "未知原因"}\n`;
+                    consoleOutput.scrollTop = consoleOutput.scrollHeight;
+                  }
+                });
+            } else if (d.status === "running") {
+              if (isCurrent) {
+                btn.disabled = true;
+                btn.textContent = "⚡ 批量提取中...";
+                if (consoleStatus) {
+                  consoleStatus.textContent = "running";
+                  consoleStatus.style.color = "var(--mint)";
+                }
+              }
+              fetch(`/api/batch_generate_log?q=${encodeURIComponent(q)}`)
+                .then(r => r.json())
+                .then(ld => {
+                  if (isCurrent && ld.log && consoleOutput) {
+                    consoleOutput.textContent = ld.log;
+                    consoleOutput.scrollTop = consoleOutput.scrollHeight;
+                  }
+                });
+            }
+          })
+          .catch(err => console.error("Batch poll error:", err));
+      };
+      
+      poll();
+      batchProcPollInterval = setInterval(poll, 2000);
+    }
+
+    function loadData(forceReload) {
+      document.getElementById("lede").textContent = "正在加载数据...";
+      fetch("/api/data")
+        .then(r => r.json())
+        .then(d => {
+          DATA = d;
+          document.getElementById("lede").textContent = `runs_new/ 下共找到 ${d.queries.length} 个检索到的 query。`;
+          
+          updateThresholdLimits();
+          
+          if (DATA.queries.length > 0) {
+            if (st.qi === -1 || st.qi >= DATA.queries.length) {
+              st.qi = 0;
+            }
+            st.fi = 0;
+            document.getElementById("resultsArea").style.display = "block";
+          } else {
+            st.qi = -1;
+            document.getElementById("resultsArea").style.display = "none";
+          }
+          
+          renderSidebar();
+          renderGrid();
+          renderHead();
+          
+          if (d.active_reevals) {
+            Object.keys(d.active_reevals).forEach(q => {
+              if (d.active_reevals[q] === "running") {
+                startReevalPolling(q);
+              }
+            });
+          }
+          if (d.active_batch_tasks) {
+            Object.keys(d.active_batch_tasks).forEach(q => {
+              if (d.active_batch_tasks[q] === "running") {
+                startBatchProcPolling(q);
+              }
+            });
+          }
+        })
+        .catch(err => {
+          document.getElementById("lede").textContent = "读取数据失败:" + err;
+        });
+    }
+
+    // App Initialization
+    (function init() {
+      // Build query builder dimension groups
+      const root = document.getElementById('dimensions');
+      DIMS.forEach(dim => {
+        const grp = document.createElement('div');
+        grp.className = 'dim-group';
+        grp.dataset.id = dim.id;
+        root.appendChild(grp);
+        renderDim(dim.id);
+      });
+      updateQueryPreview();
+
+      // Load scanned queries list
+      loadData(false);
+    })();
+  </script>
+</body>
+
+</html>

+ 4 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/.gitignore

@@ -0,0 +1,4 @@
+__pycache__/
+*.pyc
+.ocr_cache/
+_archive/

+ 341 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/plan_tool.py

@@ -0,0 +1,341 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""plan_tool.py — procedure-dsl 的「计划」内置工具 (技能本地, 仅 Cyber/run_cyber 引擎)。
+
+为什么是工具而不是"写 understanding.md":
+  弱模型读了"先想清楚工序"的 prompt 也照样跳过、直接堆骨架。把这一步做成**工具**,
+  LLM 必须**调用一次**把【工序分解 + 每工序步骤逐条展开 + 每工序覆盖原文哪些章节】
+  作为结构化参数交上来 —— 工具当场校验完整性 (混合门禁), 通过就**自动据计划生成
+  workflow.json 骨架**, 结果回灌进对话锚定后续填充。于是:
+    · understanding 重新独立成一步 (但由工具承载, 不靠自觉)
+    · 工序由计划显式决定 (章节认领是声明式, 不再靠词汇模糊匹配)
+    · workflow.json 结构严格按计划生成 (工序数/步骤数/顺序锁定, LLM 只填值)
+
+设计边界 (遵守"runner 零业务知识"): 本模块是**技能本地**, 不进 agent/tools/builtin/,
+run_cyber 仅 `import plan_tool` 触发 @tool 注册 + 调 set_plan_context 注入原文/路径。
+Claude SDK 路 (run_procedure_dsl) 没有 repo 工具系统, 那条路 understanding 仍走 prompt。
+"""
+# ⚠ 不能用 `from __future__ import annotations`: 它把类型注解变成字符串, 而框架
+#   SchemaGenerator 靠运行时 get_origin() 内省真实类型 — 拿字符串会把 procedures 这种
+#   List[Dict] 退化成 "string", LLM 就不知道该传数组了。
+import json
+import re
+from pathlib import Path
+from typing import Any, Dict, List, Optional
+
+from agent.tools import tool, ToolResult, ToolContext
+
+
+# ===========================================================================
+# 运行时上下文 (run_cyber.main() 在跑 runner 前注入; 工具闭包读它, 避免让 LLM 传路径)
+# ===========================================================================
+
+_PLAN_CTX: Dict[str, Any] = {}
+
+
+def set_plan_context(*, body_text: str = "", out_dir: Optional[Path] = None,
+                     case_id: Any = None, source: Optional[dict] = None,
+                     ocr: str = "", spec_name: str = "spec") -> None:
+    """run_cyber 在执行前调用, 把原文正文 / 配图 OCR / 输出目录 / source 元信息交给工具。"""
+    _PLAN_CTX.clear()
+    _PLAN_CTX.update({
+        "body_text": body_text or "",
+        "ocr": ocr or "",
+        "out_dir": Path(out_dir) if out_dir else None,
+        "case_id": case_id,
+        "source": source or {},
+        "spec_name": spec_name or "spec",
+    })
+
+
+# ===========================================================================
+# 原文章节解析 (与 lint-case.py 同口径: 行首 0N| 标号, 排除 "图 0N|" 配图说明)
+# ===========================================================================
+
+# 与 lint-case.py 同口径: 行首两位标号 NN| (01..99), 行首要求天然排除 "图 0N|" 配图说明
+_SEC_RE = re.compile(r'(?m)^\s*(\d{2})\s*[||]')
+
+
+def _source_sections(body: str) -> List[tuple]:
+    """返回 [(章节号, 标题)],如 [('01','从一个案例开始'), ('02','结构化 Prompt 框架'), ...]。"""
+    marks = [(m.start(), m.group(1)) for m in _SEC_RE.finditer(body or "")]
+    out: List[tuple] = []
+    for i, (pos, num) in enumerate(marks):
+        end = marks[i + 1][0] if i + 1 < len(marks) else len(body)
+        seg = body[pos:end]
+        after = re.split(r'[||]', seg, 1)
+        tail = after[-1] if len(after) > 1 else seg
+        title = ""
+        for ln in tail.splitlines():
+            ln = ln.strip()
+            if ln:
+                title = ln[:24]
+                break
+        out.append((num, title))
+    return out
+
+
+def _norm_sec(s: Any) -> str:
+    """把 '1' / '01' / '第1章' 之类归一成两位章节号 '01'。无数字返回原串。"""
+    m = re.search(r'\d+', str(s))
+    return f"0{int(m.group())}"[-2:] if m and int(m.group()) < 10 else (m.group() if m else str(s).strip())
+
+
+# ===========================================================================
+# 入参容错 (弱模型常把 list 传成 JSON 字符串 / 包一层 {"procedures": [...]})
+# ===========================================================================
+
+def _coerce_procedures(procedures: Any) -> List[dict]:
+    if isinstance(procedures, str):
+        try:
+            procedures = json.loads(procedures)
+        except Exception:
+            return []
+    if isinstance(procedures, dict):
+        procedures = procedures.get("procedures", procedures.get("list", []))
+    return procedures if isinstance(procedures, list) else []
+
+
+# ===========================================================================
+# 据计划生成 workflow.json 骨架
+# ===========================================================================
+
+def _io_labels(st: dict, key: str) -> List[str]:
+    """取步骤的 input/output 标签, 字符串或数组都收 (生成步典型是 [提示词, 参考图] 两个输入)。"""
+    v = st.get(key)
+    if v is None:
+        v = st.get(key + "s")
+    if isinstance(v, str):
+        v = [v]
+    if not isinstance(v, list):
+        return []
+    return [str(x).strip()[:40] for x in v if str(x).strip()]
+
+
+def _build_skeleton(summary: str, procedures: List[dict]) -> dict:
+    src = _PLAN_CTX.get("source") or {}
+    skeleton: Dict[str, Any] = {
+        "source": {
+            "platform": src.get("platform", ""),
+            "author": src.get("author", ""),
+            "date": src.get("date", ""),
+            "url": src.get("url", ""),
+            "title": src.get("title", ""),
+            "excerpt": src.get("excerpt", "") or (summary or "")[:120],
+        },
+        "procedures": [],
+    }
+    for pi, proc in enumerate(procedures, 1):
+        pid = f"p{pi}"
+        steps_out: List[dict] = []
+        for si, st in enumerate(proc.get("steps") or [], 1):
+            if not isinstance(st, dict):
+                continue
+            sid = f"s{si}"
+            ins = _io_labels(st, "input")
+            outs = _io_labels(st, "output")
+            tool = (st.get("tool") or "").strip()
+            loop = (st.get("loop") or "").strip()[:40]
+            if loop:
+                # 循环步 → block 父 + nested 子 (README「有循环/并行怎么切」的标准形)。
+                # block: 输入=被遍历的集合, 输出=结果列表; 子步带真实工具和逐项 IO。
+                steps_out.append({
+                    "id": sid, "kind": "block", "via": "-", "directive": "",
+                    "inputs": [{"type": loop, "value": "", "anchor": ""}],
+                    "outputs": [{"id": f"{sid}o1",
+                                 "type": (outs[0] + "列表")[:40] if outs else "结果列表",
+                                 "value": "", "anchor": ""}],
+                })
+                steps_out.append({
+                    "id": f"{sid}.1", "kind": "nested", "group": sid, "via": tool,
+                    "directive": "",
+                    "inputs": [{"type": t, "value": "", "anchor": ""} for t in ins],
+                    "outputs": [{"id": f"{sid}.1o{oi}", "type": t, "value": "", "anchor": ""}
+                                for oi, t in enumerate(outs, 1)],
+                })
+                continue
+            steps_out.append({
+                "id": sid,
+                "kind": "step",
+                "via": tool,
+                "directive": "",   # 待 LLM 用 wf-patch 填真实 prompt
+                "inputs": [{"type": t, "value": "", "anchor": ""} for t in ins],
+                "outputs": [{"id": f"{sid}o{oi}", "type": t, "value": "", "anchor": ""}
+                            for oi, t in enumerate(outs, 1)],
+            })
+        skeleton["procedures"].append({
+            "id": pid,
+            "name": (proc.get("name") or "").strip(),
+            "purpose": (proc.get("final_product") or proc.get("purpose") or "").strip(),
+            "category": (proc.get("category") or "").strip(),
+            "platform": src.get("platform", ""),
+            "author": src.get("author", ""),
+            "declarations": {"inputs": [], "resources": [], "returns": {}},
+            "steps": steps_out,
+        })
+    return skeleton
+
+
+# ===========================================================================
+# 工具本体
+# ===========================================================================
+
+_PLAN_DESC = (
+    "【第一步必做】提交你对这篇教程的工序计划 (understanding)。读完原文+配图后, "
+    "把它拆成若干工序、每个工序的步骤逐条展开、并声明每个工序覆盖原文哪些 0N 章节。"
+    "工具会校验完整性 (有章节没被任何工序认领 → 报错, 修改计划后**重新调用**; 工序只有单步 → 警告), "
+    "通过后**自动据此生成 workflow.json 骨架** (工序划分/步骤序列锁定), 你之后在骨架上填 "
+    "value/directive/anchor, 不再增删工序或步骤。\n"
+    "procedures 每项形如:\n"
+    '  {"name":"工序名", "category":"产物创造|资产建设|自动化|分析|学习", '
+    '"final_product":"终态产物", "source_sections":["01","03"], '
+    '"steps":[{"tool":"工具名/human", "input":["提示词","参考图"], '
+    '"does":"这步做什么的一句话自由描述", "output":"场景图"}, ...]}\n'
+    "要点: source_sections 必填 (原文每个 0N 章节都要被某个工序认领, 别漏整段); "
+    "steps 逐步展开别压成单步; input/output 写**短标签**(字符串或数组——生成步通常要 [提示词, 参考图] "
+    "两个输入, 都列上, 它们会变成步骤输入/输出的 type); "
+    '对一批数据逐个重复的步骤加 "loop":"被遍历数据的短标签(如 分镜脚本)", 骨架会自动展开成循环块+子步; '
+    "does 只是计划期的自由描述, **不是** workflow 的 taxonomy 动作词 (那留到 Phase 2 查 action.json 归类)。"
+)
+
+
+@tool(description=_PLAN_DESC, hidden_params=["context"], groups=["core"])
+async def plan_procedures(
+    summary: str,
+    procedures: List[Dict[str, Any]],
+    context: Optional[ToolContext] = None,
+) -> ToolResult:
+    """提交工序计划 → 校验 → 自动生成 workflow.json 骨架。
+
+    Args:
+        summary: 2-4 句说清这篇在教什么、分几大板块。
+        procedures: 工序列表 (结构见工具描述)。
+    """
+    procs = _coerce_procedures(procedures)
+    if not procs:
+        return ToolResult(
+            title="计划为空",
+            output="procedures 解析为空。请传一个工序数组, 每项含 name/category/"
+                   "final_product/source_sections/steps (steps 逐步展开)。",
+            error="empty plan",
+        )
+
+    body = _PLAN_CTX.get("body_text", "")
+    secs = _source_sections(body)
+    present = {num for num, _ in secs}
+    sec_title = dict(secs)
+
+    # ---- 收集声明 + 基础校验 ----
+    claimed: set = set()
+    warnings: List[str] = []
+    io_missing: List[str] = []   # 缺 input/output 标签是硬门禁: 骨架会带空 IO 出生, 下游全瞎
+    for pi, proc in enumerate(procs, 1):
+        if not isinstance(proc, dict):
+            warnings.append(f"procedures[{pi-1}] 不是对象, 已跳过")
+            continue
+        name = (proc.get("name") or "").strip() or f"(工序{pi})"
+        steps = proc.get("steps") or []
+        for s in (proc.get("source_sections") or []):
+            claimed.add(_norm_sec(s))
+        if not steps:
+            warnings.append(f"工序『{name}』没有 steps — 至少要有步骤序列")
+        elif len(steps) == 1:
+            warnings.append(f"工序『{name}』只有 1 个步骤 — 确认它真的无法再展开? (多数工序是多步)")
+        for sj, st in enumerate(steps, 1):
+            if not isinstance(st, dict):
+                continue
+            miss = [k for k in ("tool", "does") if not str(st.get(k) or "").strip()]
+            if miss:
+                warnings.append(f"工序『{name}』step{sj} 缺 {'/'.join(miss)} (四要素: 工具 tool·输入 input·动作 does·输出 output)")
+            io_miss = [k for k in ("input", "output") if not _io_labels(st, k)]
+            if io_miss:
+                io_missing.append(f"工序『{name}』step{sj} 缺 {'/'.join(io_miss)}")
+
+    # ---- 硬门禁: 每步必有 input + output 标签 (步骤=对输入操作产生新产物, 缺标签=骨架洞) ----
+    if io_missing:
+        lines = "\n".join(f"  · {m}" for m in io_missing)
+        return ToolResult(
+            title=f"{len(io_missing)} 个步骤缺 input/output 标签",
+            output=(
+                f"以下步骤缺输入或输出的短标签, 骨架会带着空 IO 生成, 后续校验/渲染全过不去:\n{lines}\n\n"
+                f"每步都要写 input(用到什么数据)和 output(产出什么) 的短标签 (字符串或数组)。"
+                f"原文没明写的, 按工艺推断该有什么(如生图步 input 必有 提示词)。"
+                f"补全后**重新调用 plan_procedures**。"
+            ),
+            error=f"steps missing input/output: {len(io_missing)}",
+        )
+
+    # ---- 硬门禁: 章节覆盖 (只在原文确有 0N 分章时启用) ----
+    if present:
+        unclaimed = sorted(present - claimed)
+        if unclaimed:
+            lines = "\n".join(f"  · 章节 {n} 『{sec_title.get(n,'')}』" for n in unclaimed)
+            return ToolResult(
+                title=f"计划漏了 {len(unclaimed)} 个章节",
+                output=(
+                    f"原文有 {len(present)} 个章节, 你的计划只认领了 {sorted(claimed) or '无'}。"
+                    f"下面这些章节**没有任何工序认领**, 极可能被整段漏抽:\n{lines}\n\n"
+                    f"请逐个判断: 它是一条独立工序 (有自己的做法/产物), 还是某工序的若干步骤? "
+                    f"想清楚后**重新调用 plan_procedures**, 让每个工序的 source_sections 把这些章节都覆盖上。"
+                    f"(无独立做法、纯展示的章节可以并进相邻工序的 steps, 但要在某工序的 source_sections 里出现。)"
+                ),
+                error=f"unclaimed sections: {','.join(unclaimed)}",
+            )
+        bogus = sorted(claimed - present - {""})
+        if bogus:
+            warnings.append(f"source_sections 里 {bogus} 在原文里找不到对应 0N 章节 (写错章节号?)")
+
+    # ---- 通过: 生成骨架 + 落盘 ----
+    skeleton = _build_skeleton(summary, procs)
+    out_dir: Optional[Path] = _PLAN_CTX.get("out_dir")
+    nproc = len(skeleton["procedures"])
+    nstep = sum(len(p["steps"]) for p in skeleton["procedures"])
+
+    written = []
+    if out_dir:
+        scratch = out_dir / "_scratch"
+        scratch.mkdir(parents=True, exist_ok=True)
+        wf_path = out_dir / "workflow.json"
+        wf_path.write_text(json.dumps(skeleton, ensure_ascii=False, indent=2), encoding="utf-8")
+        written.append(wf_path.as_posix())
+        # 计划原文留档 (供审计 workflow 是否仍按计划; 也方便你回看)
+        plan_path = scratch / "understanding.json"
+        plan_path.write_text(json.dumps(
+            {"summary": summary, "procedures": procs}, ensure_ascii=False, indent=2), encoding="utf-8")
+        written.append(plan_path.as_posix())
+
+    # ---- 回灌进对话: 计划摘要 + 骨架结构 + 指针 (规则细节在 README, 这里不复述) ----
+    spec_name = _PLAN_CTX.get("spec_name", "spec")
+    recap = [f"✅ 计划已通过校验, 已据此生成 workflow.json 骨架: {nproc} 工序 / {nstep} 步。"]
+    if present:
+        recap.append(f"章节覆盖: 原文 {sorted(present)} 全部被认领 ✓")
+    else:
+        recap.append("ℹ 原文未检测到 `NN|` 分章标号, 章节覆盖门禁未启用 — 自行核对没有整段漏抽。")
+    recap.append("")
+    for p in skeleton["procedures"]:
+        recap.append(f"【{p['id']}】{p['name']} ({p['category']}) — {len(p['steps'])} 步")
+        for st in p["steps"]:
+            ins = "+".join(io["type"] for io in st["inputs"]) or "—"
+            outs = "+".join(io["type"] for io in st["outputs"]) or "—"
+            tag = f" [{st['kind']}]" if st.get("kind") != "step" else ""
+            recap.append(f"    {st['id']}{tag} via={st['via'] or '—'}: [{ins}] → [{outs}]")
+    if warnings:
+        recap.append("")
+        recap.append("⚠ 警告 (不阻塞, 但请核对):")
+        for w in warnings:
+            recap.append(f"  - {w}")
+    recap.append("")
+    recap.append(
+        "锁定范围 = 工序划分与步骤序列; **在已有步骤里补输入/输出是允许且常见的**"
+        "(如生成步补第二个输入, wf-patch 路径不存在默认 upsert)。"
+        f"接下来按 {spec_name}/README.md「第二阶段 · 2.0 填内容」执行: "
+        "wf-patch 填 value(@quote)/anchor → verify-io.py 校验通过 → 进 2.1 归类。"
+        "若工序/步骤划分本身不对, 修改计划后重新调用 plan_procedures (整体重生成)。"
+    )
+    return ToolResult(
+        title=f"计划通过: {nproc} 工序 / {nstep} 步",
+        output="\n".join(recap),
+        metadata={"procedures": nproc, "steps": nstep,
+                  "sections_present": sorted(present), "written": written,
+                  "warnings": len(warnings)},
+    )

+ 231 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/SKILL.md

@@ -0,0 +1,231 @@
+# 工序提取 SKILL · procedure
+
+> 读一篇 AI 创作教程/案例,把它背后的"做法"还原成工序表,**直接写出 `workflow.json`**。
+
+**输入**:`input/case-{N}.json`(正文 + 配图;配图 OCR 文本若已存在于 `outputs/case-{N}/_scratch/ocr.txt` 一并读)。
+**输出**:`outputs/case-{N}/workflow.json`。
+
+## 流程
+
+1. **通读原文**,想清楚:有几个工序、每工序几步、每步「工具 · 输入 · 动作 · 输出」。
+2. **一次性 Write 完整的 `workflow.json`**(所有字段一趟填全,结构见下)。
+3. **校验**:
+
+   ```bash
+   python procedure/tools/validate.py --workflow outputs/case-{N}/workflow.json \
+       --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt
+   ```
+
+4. 报 ✗ 就修,重跑直到 0 错误;⚠ 警告逐条核对,确认无误可保留。零星错误直接 Edit `workflow.json`;**同类错误一大批**(整批 anchor / 整批 effect/action)用 `procedure/tools/wf-patch.py` 批量修(见「批量修错」节)。
+
+---
+
+## workflow.json 结构
+
+```json
+{
+  "source": {
+    "platform": "", "author": "", "date": "", "url": null,
+    "title": "", "excerpt": "1-2 句概括这篇教程的流水线"
+  },
+  "procedures": [
+    {
+      "id": "p1",
+      "name": "工序名称",
+      "purpose": "一句话说明该工序在做什么",
+      "category": "产物创造|资产建设|自动化|分析|学习",
+      "platform": "",
+      "author": "",
+      "declarations": {
+        "inputs": [{ "type": "参考图", "name": "产品图", "desc": "用户提供" }],
+        "resources": [],
+        "returns": { "type": "成品图" }
+      },
+      "type_registry": {
+        "主角图": { "extends": "参考图", "desc": "本案例的女主肖像" }
+      },
+      "steps": [
+        {
+          "id": "s1",
+          "kind": "step",
+          "via": "human",
+          "effect": "预处理",
+          "action": "生成/元素生成",
+          "substance": "人物、产品",
+          "form": null,
+          "directive": "",
+          "intent": "{via:human} {act:元素生成} {out-type:提示词}",
+          "inputs": [
+            { "type": "描述", "value": "原文逐字内容", "anchor": "← 工序输入" }
+          ],
+          "outputs": [
+            { "id": "s1o1", "type": "提示词", "value": "整段逐字提示词", "anchor": "→ s2" }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+### 字段规范
+
+| 字段 | 规范 |
+| --- | --- |
+| step `id` | `s1`、`s2`;控制块子步用点号 `s5.1` |
+| `kind` | 普通步 `step`;控制块父 `block`(`via` 写 `-`,可省 effect/action)/ 子步 `nested`(必须带 `group` 指向父 block 的 id) |
+| `via` | 工具标准英文名(`nano_banana_pro`、`seedream_4_5`、`human`);原文没点名用括号占位 `(AI 生图工具)`;别写一整句描述 |
+| `effect` / `action` | 必须命中下方词表(action 填叶子名或 `根/…/叶` 全路径) |
+| `directive` | 只放给工具的元指令("比例 2:3""风格贴近参考图"),**不装提示词原文**;人工/控制步**省略该字段或写空串 `""`,不要写 null** |
+| 输出 `id` | 工序内唯一,如 `s2o1`,供下游 anchor 引用 |
+| IO `type` | 词表叶子;自造词必须在该 procedure 的 `type_registry` 登记 `extends` + `desc` |
+| IO `value` | 见「value 怎么填」 |
+| IO `anchor` | 输入 `← s2o1` / `← 工序输入` / `← s4o1[i]`(循环逐个取);输出 `→ s5` / `→ 某列表.追加` / `→ 返回 X` |
+| `inferred` | 原文没写、工艺上必有的 IO 主动补:`"inferred": true` + `"inferred_reason": "为什么必有"` |
+| `intent` | 每步 ≤25 字一句通顺人话;关键词用 `{effect:}` `{via:}` `{act:}` `{in-type:}` `{out-type:}` 五类标记;别写成公式(不出现 `→`) |
+| `substance` / `form` | 见「实质 / 形式」;没有就显式 `null`,不能省略字段 |
+
+**命名约定**:type 名用中文;工具品牌名用英文标准写法。
+
+---
+
+## 提取判断
+
+### 有几个工序
+
+判断单位是"一条完整的 输入→最终产物 链",不是原文段落。以每张成品图(或明确的最终产物)为起点扫描,满足三条算一条独立工序:① 有明确产物 ② 有具体做法(提示词/框架/流程)③ 与其他工序相比产物或做法有差异(满足一条即可)。
+
+**章节认领**:原文按 `01 | 02 | 03` 分章时,逐章确认每章都落进了某个工序/步骤——**没有独立成品图的方法论章节本身就是一条工序,不能漏**。
+
+### 什么算一个步骤
+
+**步骤 = 对已有数据执行某个操作,产生一份之前不存在的新产物。** 判断口诀:把这步去掉、把它的内容挪进下一步的 inputs——什么都没丢,它就不是步骤,是输入。
+
+❌ 不是步骤:引入外部资源(写进使用它的步骤 inputs 或 `declarations.inputs`);原文直接给出的提示词(同上,不拆 `via=human` 预处理步);提示词多层展开(那是「写提示词」一步的输出 value 内容);纯展示/预览。
+✅ 是步骤:AI 工具生成图/视频、human 写提示词(原文在**教**怎么写才算)、后期工具调色排版。
+
+### 循环 / 并行
+
+展开成控制块 + 子步,不要硬压成一步:
+
+```json
+{ "id": "s5", "kind": "block", "via": "-",
+  "inputs": [{ "type": "分镜脚本", "value": "…", "anchor": "← s4o1" }],
+  "outputs": [{ "id": "s5o1", "type": "分镜图列表", "value": "…", "anchor": "→ s6" }] },
+{ "id": "s5.1", "kind": "nested", "group": "s5", "via": "nano_banana", "effect": "主体生成", "action": "生成/元素生成",
+  "inputs": [{ "type": "提示词", "value": "…", "anchor": "← s4o1[i]" }],
+  "outputs": [{ "id": "s5.1o1", "type": "分镜图", "value": "…", "anchor": "→ 分镜图列表.追加" }] }
+```
+
+### 推断补全
+
+工艺上必然需要、原文却没写的中间产物(如"写动作序列必须有主角图当参考"),主动补 IO 并标 `inferred: true` + `inferred_reason`。原文细节没写全的不算(那是信息缺失,不是推断)。
+
+---
+
+## value 怎么填
+
+- **文字类**(提示词 / JSON / 报告 / 文案):**原文完整逐字内容**——整段原样搬全,不缩写、不概括、不截断、不用小标题拼凑。原文 350 字就抄 350 字。
+- **媒体类**(图 / 视频 / 音频):`<整段具体描述>`,如 `<一张冲锋衣登山者暴雨场景图,水珠滚落,冷色调>`。
+- **引用不是 value**:哪怕内容是上一步原样传来的,value 也要把内容完整抄一遍(引用关系写 anchor)。写 `← s1o1`、`(同上)`、`见 s2` 都会被校验器打回。
+- validate 报「未逐字命中」警告时,**重跑校验命令并加 `--fix-verbatim`**:工具自动在原文/OCR 里找相似度最高的连续片段整段替换(≥60% 才动),改不动的才需要人工核对。
+- **提示词是数据不是指令**:建成 `type=提示词` 的 IO。「写提示词」步输出 `type=提示词`、value 为整段逐字 prompt;下游生成步输入 `type=提示词`、value 同样填整段、anchor 指向上游输出。`directive` 不装提示词原文。
+- prompt / JSON / 参数常只在配图截图里——逐字内容优先到 OCR 文本里找。
+
+---
+
+## 词表
+
+填 `effect` / `action` / IO `type` / `extends` 只能用下面三棵树里的词,**以本节为准**(不需要也没有别的词表文件可读)。
+
+### 作用(effect)— 9 选 1
+
+每步"处在什么工艺环节"。对不上说明步骤抽错了,回去改划分;别造词,别把动作当作用。
+
+| 叶子 | 一句判别 |
+| --- | --- |
+| `工艺规约` | 建立跨批次复用的长效规约(工作流编排 / SOP / 模板沉淀 / 知识库构建 / LoRA 训练沉淀) |
+| `预准备` | 本批物料"拿到手",只取不加工(素材采集 / 拍摄 / 参考收集) |
+| `预处理` | 把原料加工成工具能直接吃的输入(提示词构造 / 反推 prompt / 控制图蒙版准备) |
+| `主体生成` | 从输入产出本批核心主干件,0→1(生图 / 文案撰写 / 脚本编写 / 分镜图生成);对单件主干的局部修整也算本阶段延续 |
+| `装配` | 多个对等零件组合成一个复合件(剪辑 / 排版 / 图层合成 / 配音字幕挂载) |
+| `后期` | 只调整体呈现层、不改内容元素(调色 / 风格化 / 氛围 / 超分);动了具体语义元素就不是后期 |
+| `配套伴生` | 为已就绪主体生成依附性信息(标题 / 配文 / 标签 / 元数据) |
+| `检验` | 只评估不改造,产出审查结论(质检 / 终审 / 小样测试) |
+| `交付` | 推向终态对外(导出 / 发布 / 定稿 / 成品多视图展示) |
+
+边界速查:跨批复用→工艺规约,本批一次性→预准备/预处理;"去拿料"→预准备,"把料加工成输入"→预处理;单件 0→1→主体生成,多件→一件→装配;改呈现层→后期,改内容元素→主体生成延续。
+
+### 动作(action)
+
+填叶子名或全路径(如 `解构` 或 `提取/化学提取/解构`)。
+
+```
+获取                提取                生成                修改                存储
+  搜索: 检索 下载     物理提取: 裁切        元素生成            增: 添加 叠加        暂存: 缓存
+  查询: 调取           抠取 抽帧          关系生成:           删: 抹除 剪除        沉淀: 入库
+  录入: 上传 拍摄    化学提取: 识别          数组生成          变: 重述 风格化      归档: 存档
+    录音 键入          反推 解构            结构生成            转换 替换
+  引用: 选取                                                  调整 增强
+```
+
+⚠ **反推 vs 解构**:从文字/教程里提炼框架、要点(信息显式可见)→ `解构`;从图片推回 prompt 或隐含结构(信息不可直接看到)→ `反推`。"梳理教程结构""提取风格要素"几乎都是 `解构`。
+
+### 类型(type)
+
+候选词直接命中叶子就用;没命中挑最近叶子挂靠,在该 procedure 的 `type_registry` 登记 `{"extends": "叶子", "desc": "说明"}`。不允许自造词不登记。
+
+```
+程序控制类型                 内容类型
+  指令: 提示词 负向提示词 描述    素材
+  参数: 生成参数 规格参数          化学变化: 参考图 参考视频 参考音频 对标内容 分镜图
+    模型权重                            转场 蒙版 控制图 运动轨迹 滤镜 构图布局
+  评估: 评分 评语                 物理变化: 截图 视频片段 转场片段 关键帧 音效 特效
+  流程: 工作流 批处理            半成品
+数据复用类型                     序列: 大纲 脚本 分镜脚本 剪辑脚本 配音文案
+  原子: 数字人 版式               原子: 底图 样图 分镜视频
+  序列: 模板                      组合: 图层组合 拼图
+知识类型                       准成品: 歌词 配音 BGM 字幕 标题 正文
+  知识库                       成品: 成品图 视频成品 合成图
+```
+
+### 实质 / 形式(substance / form)— 自由提炼,无词表
+
+只描述最终产物**画面内容的视觉维度**,与步骤处理什么数据类型无关。
+
+- **substance**(画面里有什么):视觉内容主体,如 `美女`、`产品`。❌ 不填 `风格`(那是 form)、不填 `提示词/描述/框架`(数据类型)。即使这步产出文字,也填它面向的画面主体。
+- **form**(画面长什么样):视觉风格调性,如 `超现实主义`、`古风`。❌ 不填 `JSON/表格`(技术格式)。方法不限风格 → `null`。
+
+先判断作者意图:**通用方法文**(有"换个题材也能套"类泛化表述)→ substance 填方法的作用对象大类(`人物`、`产品`、`实拍图`);**具体案例文** → 填案例实际视觉主体与具体风格。判断不清偏具体案例。没有特别涉及就 `null`,多值用顿号并列。
+
+---
+
+## 批量修错(可选工具 wf-patch)
+
+validate 报出**一批同类错误**时,逐处 Edit 太碎,用 wf-patch 批量改(写入即校验,词表与 validate 同源;值非法整批拒绝并在报错末尾给出合法值清单,照清单改了重跑):
+
+```bash
+# 单条 / 多条 --set(path=value;值含空格用双引号包整个参数)
+python procedure/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json \
+    --set "p1.s2.effect=主体生成" \
+    --set "p1.s2.action=生成/元素生成" \
+    --set "p1.s1.inputs[0].anchor=← s0o1" \
+    --set "p1.s1.form=__null__"
+
+# 几十处一次过:写一份 patch 清单, --prune 让成功项自动删除、失败项留在文件里带 _error 原因
+python procedure/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json \
+    --patch outputs/case-{N}/_scratch/fix.json --prune
+#   fix.json = [{"path": "p1.s1.inputs[0].anchor", "value": "← s0o1"}, ...]
+#   改完重跑同一文件直到清空为 []
+
+# 删字段(字段不存在则幂等跳过)
+python procedure/tools/wf-patch.py --workflow ... --unset "p1.declarations.inputs[0].inferred"
+```
+
+路径语法:`p1.s2.effect`(step 标量)、`p1.s1.inputs[0].anchor`(IO 字段)、`p1.type_registry.主角图.extends`、`source.url`;嵌套步 `p1.s5.1.outputs[0].type`。`__null__` 表示 JSON null(substance/form/url 可用)。
+
+---
+
+## 完成条件
+
+`validate.py` 0 错误,且自查:每个章节都被某工序认领、文字 value 都是原文逐字、每步 intent 是一句通顺人话。

+ 78 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/render.py

@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+"""procedure skill 渲染入口 — 零校验, 直接出 HTML.
+
+质量门禁全部在 validate.py; 本脚本只负责把 workflow.json 拼成 case_data 并渲染,
+数据再不完美也尽量出图 (复用 spec/tools 的 renderer.build_html + merge_raw_source,
+跳过 render-case.py 的 schema / 占位 / 结构三层门禁)。
+
+用法:
+    python procedure/tools/render.py --workflow outputs/case-N/workflow.json \
+        --source-input input/case-N.json --page-title "Case N · 主题" \
+        --case-id N --out outputs/case-N/case-N.html
+
+退出码: 0 成功 / 1 渲染异常 / 2 CLI、文件问题
+"""
+
+import argparse
+import importlib.util
+import json
+import sys
+from pathlib import Path
+
+if hasattr(sys.stdout, "reconfigure"):
+    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
+    sys.stderr.reconfigure(encoding="utf-8", errors="replace")
+
+SPEC_TOOLS = Path(__file__).resolve().parent.parent.parent / "spec" / "tools"
+
+
+def _load_module(name, path):
+    spec = importlib.util.spec_from_file_location(name, path)
+    mod = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(mod)
+    return mod
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    ap.add_argument("--workflow", type=Path, required=True)
+    ap.add_argument("--source-input", type=Path, dest="source_input",
+                    help="原帖 raw json — 正文/封面 merge 进 HTML 折叠原文区")
+    ap.add_argument("--page-title", default=None)
+    ap.add_argument("--case-id", default=None)
+    ap.add_argument("--out", type=Path, required=True)
+    args = ap.parse_args()
+
+    try:
+        case_data = json.loads(args.workflow.read_text(encoding="utf-8"))
+    except FileNotFoundError:
+        print(f"✗ 文件不存在: {args.workflow}")
+        return 2
+    except json.JSONDecodeError as e:
+        print(f"✗ JSON 解析失败: {e}")
+        return 2
+
+    title = (case_data.get("source") or {}).get("title") or args.workflow.stem
+    case_data.setdefault("page_title", args.page_title or title)
+    if args.case_id is not None:
+        case_data["case_id"] = args.case_id
+
+    try:
+        if args.source_input:
+            _load_module("_render_case_mod", SPEC_TOOLS / "render-case.py") \
+                .merge_raw_source(case_data, args.source_input)
+        html = _load_module("_renderer_mod", SPEC_TOOLS / "renderer.py").build_html(case_data)
+    except Exception as e:
+        print(f"✗ 渲染异常 ({type(e).__name__}: {e}) — workflow.json 可能有渲染器吃不下的字段值")
+        return 1
+
+    args.out.parent.mkdir(parents=True, exist_ok=True)
+    args.out.write_text(html, encoding="utf-8", newline="")
+    n_procs = len(case_data.get("procedures") or [])
+    n_steps = sum(len(p.get("steps") or []) for p in case_data.get("procedures") or [])
+    print(f"render: ✓ wrote {args.out} ({len(html):,} chars, {n_procs} procedures, {n_steps} steps)")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 393 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/validate.py

@@ -0,0 +1,393 @@
+#!/usr/bin/env python3
+"""procedure skill 唯一校验器.
+
+agent 直接 Write 出 workflow.json 后跑本脚本, 一次性报出全部问题:
+  ✗ 错误 (必须修, exit 1): 结构缺字段 / 词表不命中 / 数据流断链 / 编号重复 / value 是引用占位
+  ⚠ 警告 (建议核对, 不拦截): 类型不一致 / 生成步缺提示词输入 / value 未在原文逐字命中
+
+用法:
+    python procedure/tools/validate.py --workflow outputs/case-N/workflow.json \
+        [--source input/case-N.json] [--ocr outputs/case-N/_scratch/ocr.txt]
+
+退出码: 0 = 无错误 / 1 = 有错误 / 2 = CLI 或文件问题
+"""
+
+import argparse
+import json
+import re
+import sys
+from difflib import SequenceMatcher
+from pathlib import Path
+
+if hasattr(sys.stdout, "reconfigure"):
+    sys.stdout.reconfigure(encoding="utf-8")
+    sys.stderr.reconfigure(encoding="utf-8")
+
+# 词表常量与 wf-patch.py 同源 (同目录 vocab.py)
+sys.path.insert(0, str(Path(__file__).resolve().parent))
+from vocab import EFFECT_LEAVES, ACTION_LEAF2PATH, TYPE_LEAVES  # noqa: E402
+
+CATEGORIES = {"产物创造", "资产建设", "自动化", "分析", "学习"}
+KINDS = {"step", "block", "nested"}
+STEP_ID_RE = re.compile(r"^s\d+(\.\d+)*$")
+SOURCE_REQUIRED = ["platform", "author", "date", "title", "excerpt"]
+PROC_REQUIRED = ["id", "name", "purpose", "category", "declarations", "steps"]
+STEP_REQUIRED = ["id", "kind", "via", "inputs", "outputs", "intent"]
+IO_REQUIRED = ["type", "value", "anchor"]
+INTENT_TOKEN_KINDS = {"effect", "via", "act", "in-type", "out-type"}
+
+
+def norm_ws(s):
+    return re.sub(r"\s+", "", s or "")
+
+
+def _norm_map(raw):
+    """去空白的归一文本 + 每个归一字符在原文里的下标 (用于把命中片段映射回原文逐字)."""
+    chars, idx = [], []
+    for i, ch in enumerate(raw):
+        if not ch.isspace():
+            chars.append(ch)
+            idx.append(i)
+    return "".join(chars), idx
+
+
+def _best_span(nv, doc_norm, doc_idx, doc_raw):
+    """在一个文档里找与 nv 最相似的连续片段. 返回 (相似度, 原文逐字片段) 或 None."""
+    sm = SequenceMatcher(None, nv, doc_norm, autojunk=False)
+    m = sm.find_longest_match(0, len(nv), 0, len(doc_norm))
+    if m.size < min(15, max(8, len(nv) // 4)):     # 连最长公共串都很短 → 内容不在这个文档里
+        return None
+    # 以最长公共串为锚, 框出 nv 在文档里应当对应的窗口 (前后各留 1/5 余量)
+    slack = max(10, len(nv) // 5)
+    w_start = max(0, m.b - m.a - slack)
+    w_end = min(len(doc_norm), m.b + (len(nv) - m.a) + slack)
+    sm2 = SequenceMatcher(None, nv, doc_norm[w_start:w_end], autojunk=False)
+    blocks = [b for b in sm2.get_matching_blocks() if b.size > 0]
+    if not blocks:
+        return None
+    t_start = w_start + blocks[0].b                 # 收紧到首尾命中块之间
+    t_end = w_start + blocks[-1].b + blocks[-1].size
+    ratio = SequenceMatcher(None, nv, doc_norm[t_start:t_end], autojunk=False).ratio()
+    return ratio, doc_raw[doc_idx[t_start]: doc_idx[t_end - 1] + 1]
+
+
+def fix_verbatim(wf, docs):
+    """把未逐字命中的文本 value 替换成原文里最相似的连续片段 (相似度够高才动).
+
+    docs = [(norm, idx_map, raw), ...] — 原文各字段 + OCR 各算一个文档, 片段不跨文档拼接.
+    返回 (fixed, skipped): fixed=[(path, ratio, 旧字数, 新字数)], skipped=[(path, 最高相似度)].
+    """
+    fixed, skipped = [], []
+    for proc in wf.get("procedures") or []:
+        pid = proc.get("id") or "p?"
+        for s in proc.get("steps") or []:
+            if not isinstance(s, dict):
+                continue
+            for arr in ("inputs", "outputs"):
+                for i, io in enumerate(s.get(arr) or []):
+                    if not isinstance(io, dict):
+                        continue
+                    v = io.get("value")
+                    if not isinstance(v, str) or v.lstrip().startswith("<"):
+                        continue
+                    nv = norm_ws(v)
+                    if len(nv) < 40 or any(nv in d[0] for d in docs):
+                        continue                    # 短文本 / 已逐字命中
+                    best = None
+                    for dn, di, dr in docs:
+                        r = _best_span(nv, dn, di, dr)
+                        if r and (best is None or r[0] > best[0]):
+                            best = r
+                    path = f"{pid}.{s.get('id', 's?')}.{arr}[{i}]"
+                    new_n = norm_ws(best[1]) if best else ""
+                    if best and best[0] >= 0.60 and 0.4 * len(nv) <= len(new_n) <= 2.5 * len(nv):
+                        io["value"] = best[1]
+                        fixed.append((path, best[0], len(nv), len(new_n)))
+                    else:
+                        skipped.append((path, best[0] if best else 0.0))
+    return fixed, skipped
+
+
+def collect_strings(obj, out):
+    if isinstance(obj, str):
+        out.append(obj)
+    elif isinstance(obj, list):
+        for x in obj:
+            collect_strings(x, out)
+    elif isinstance(obj, dict):
+        for x in obj.values():
+            collect_strings(x, out)
+
+
+class Report:
+    def __init__(self):
+        self.errors = []
+        self.warns = []
+
+    def err(self, path, msg):
+        self.errors.append((path, msg))
+
+    def warn(self, path, msg):
+        self.warns.append((path, msg))
+
+
+def check_io(rep, io, path, is_output, proc_output_ids):
+    if not isinstance(io, dict):
+        rep.err(path, "IO 项必须是对象")
+        return
+    for k in IO_REQUIRED:
+        if k not in io:
+            rep.err(path, f"缺字段 {k}")
+    if is_output and not io.get("id"):
+        rep.err(path, "输出缺 id (如 s2o1)")
+
+    value = io.get("value", "")
+    if isinstance(value, str):
+        if not value.strip():
+            rep.err(path, "value 为空 — 文字填原文逐字内容, 媒体填 <整段描述>")
+        elif re.match(r"^\s*(←|\(同|(同|见\s*s\d)", value):
+            rep.err(path, f"value 是引用占位 ({value[:20]!r}) — 引用写 anchor, value 抄真实内容")
+
+    anchor = io.get("anchor")
+    if isinstance(anchor, str) and anchor.strip():
+        a = anchor.strip()
+        if is_output:
+            if not a.startswith("→"):
+                rep.err(path, f"输出 anchor 应以 → 开头, 现为 {a!r}")
+        else:
+            if not a.startswith("←"):
+                rep.err(path, f"输入 anchor 应以 ← 开头, 现为 {a!r}")
+            else:
+                ref = a.lstrip("←").strip()
+                ref_id = re.sub(r"\[[^\]]*\]$", "", ref).strip()
+                if re.match(r"^s\d", ref_id) and ref_id not in proc_output_ids:
+                    rep.err(path, f"anchor 引用了不存在的输出编号 {ref_id!r}")
+
+    if io.get("inferred") is True and not io.get("inferred_reason"):
+        rep.err(path, "inferred=true 必须带 inferred_reason")
+
+
+def check_intent(rep, intent, path):
+    if not isinstance(intent, str) or not intent.strip():
+        rep.err(path, "缺 intent")
+        return
+    if "→" in intent:
+        rep.err(path, "intent 写成了公式 (含 →) — 要一句通顺人话")
+    for kind in re.findall(r"\{([^:{}]+):", intent):
+        if kind not in INTENT_TOKEN_KINDS:
+            rep.err(path, f"intent 标记类别 {{{kind}:}} 非法 — 只能用 {sorted(INTENT_TOKEN_KINDS)}")
+    plain = re.sub(r"\{[^:{}]+:([^{}]*)\}", r"\1", intent)
+    if len(plain) > 40:
+        rep.warn(path, f"intent 偏长 ({len(plain)} 字, 建议 ≤25)")
+
+
+def validate(wf, vocab, source_text):
+    rep = Report()
+
+    src = wf.get("source")
+    if not isinstance(src, dict):
+        rep.err("source", "缺 source 块")
+    else:
+        for k in SOURCE_REQUIRED:
+            if not src.get(k):
+                rep.err("source", f"缺字段 {k}")
+
+    procs = wf.get("procedures")
+    if not isinstance(procs, list) or not procs:
+        rep.err("procedures", "procedures 必须是非空数组")
+        return rep
+
+    for proc in procs:
+        pid = proc.get("id") or "p?"
+        for k in PROC_REQUIRED:
+            if k not in proc:
+                rep.err(pid, f"缺字段 {k}")
+        if proc.get("category") and proc["category"] not in CATEGORIES:
+            rep.err(pid, f"category={proc['category']!r} 不合法 — 只能是 {sorted(CATEGORIES)}")
+
+        decl = proc.get("declarations")
+        if isinstance(decl, dict):
+            for k in ("inputs", "resources", "returns"):
+                if k not in decl:
+                    rep.err(f"{pid}.declarations", f"缺字段 {k}")
+        # type_registry: 每条要 extends 到标准类型叶子 + desc
+        registry = proc.get("type_registry") or {}
+        for tname, entry in registry.items():
+            tpath = f"{pid}.type_registry.{tname}"
+            if not isinstance(entry, dict) or not entry.get("extends"):
+                rep.err(tpath, "缺 extends")
+            elif entry["extends"] not in vocab["type_leaves"]:
+                rep.err(tpath, f"extends={entry['extends']!r} 不是 type 词表叶子")
+            if not isinstance(entry, dict) or not entry.get("desc"):
+                rep.err(tpath, "缺 desc")
+        known_types = vocab["type_leaves"] | set(registry)
+
+        steps = proc.get("steps") or []
+        block_ids = {s.get("id") for s in steps if isinstance(s, dict) and s.get("kind") == "block"}
+        output_ids = set()
+        out_type_by_id = {}
+        for s in steps:
+            if not isinstance(s, dict):
+                continue
+            for o in s.get("outputs") or []:
+                if isinstance(o, dict) and o.get("id"):
+                    spath = f"{pid}.{s.get('id', 's?')}"
+                    if o["id"] in output_ids:
+                        rep.err(spath, f"输出编号 {o['id']!r} 重复")
+                    output_ids.add(o["id"])
+                    out_type_by_id[o["id"]] = o.get("type")
+
+        for s in steps:
+            if not isinstance(s, dict):
+                rep.err(pid, "steps 含非对象项")
+                continue
+            sid = s.get("id") or "s?"
+            spath = f"{pid}.{sid}"
+            for k in STEP_REQUIRED:
+                if k not in s:
+                    rep.err(spath, f"缺字段 {k}")
+            if s.get("id") and not STEP_ID_RE.match(s["id"]):
+                rep.err(spath, f"step id {s['id']!r} 不合规 (s1 / s5.1)")
+            kind = s.get("kind")
+            if kind not in KINDS:
+                rep.err(spath, f"kind={kind!r} 不合法 — 只能是 {sorted(KINDS)}")
+            if kind == "nested":
+                if not s.get("group"):
+                    rep.err(spath, "nested 步缺 group")
+                elif s["group"] not in block_ids:
+                    rep.err(spath, f"group={s['group']!r} 不是已存在的 block id")
+
+            # render schema: directive 若存在必须是字符串 (人工/控制步没有 prompt 就省略字段或写空串)
+            if "directive" in s and not isinstance(s["directive"], str):
+                rep.err(spath, f"directive={s['directive']!r} 必须是字符串 — 没有就删掉该字段, 不要写 null")
+            if kind in ("step", "nested"):
+                # render 硬门禁对齐: via 非空、inputs/outputs 非空数组 (缺 IO 按工艺推断补, 标 inferred)
+                if not str(s.get("via") or "").strip():
+                    rep.err(spath, "via 为空 — 步骤要写用的工具 (human / 工具名 / 占位 (AI 生图工具))")
+                for arr, label in (("inputs", "输入"), ("outputs", "输出")):
+                    if not s.get(arr):
+                        rep.err(spath, f"{arr} 为空数组 — 步骤必有{label}; 原文没明写就按工艺推断补, "
+                                       f"标 inferred:true + inferred_reason, 不要为过校验而删 IO")
+                # effect / action 必须命中词表
+                eff = s.get("effect")
+                if not eff:
+                    rep.err(spath, "缺 effect")
+                elif eff not in vocab["effect_leaves"]:
+                    rep.err(spath, f"effect={eff!r} 不是合法叶子 — 9 选 1: {sorted(vocab['effect_leaves'])}")
+                act = s.get("action")
+                if not act:
+                    rep.err(spath, "缺 action")
+                elif act not in vocab["action_leaves"] and act not in vocab["action_paths"]:
+                    rep.err(spath, f"action={act!r} 不在动作词表 (叶子名或 根/…/叶 全路径)")
+                # substance / form 必须显式处理 (填值或 null)
+                for k in ("substance", "form"):
+                    if k not in s:
+                        rep.err(spath, f"缺 {k} (没有就显式设 null)")
+
+            check_intent(rep, s.get("intent"), spath)
+
+            for arr, is_out in (("inputs", False), ("outputs", True)):
+                for i, io in enumerate(s.get(arr) or []):
+                    iopath = f"{spath}.{arr}[{i}]"
+                    check_io(rep, io, iopath, is_out, output_ids)
+                    if not isinstance(io, dict):
+                        continue
+                    t = io.get("type")
+                    if t and t not in known_types:
+                        rep.err(iopath, f"type={t!r} 不在词表也没在 type_registry 挂靠")
+                    # 输入类型与来源输出类型一致性
+                    if not is_out and isinstance(io.get("anchor"), str):
+                        ref_id = re.sub(r"\[[^\]]*\]$", "", io["anchor"].lstrip("←").strip()).strip()
+                        src_t = out_type_by_id.get(ref_id)
+                        if src_t and t and src_t != t:
+                            rep.warn(iopath, f"输入 type={t!r} 与来源 {ref_id} 的 type={src_t!r} 不一致")
+
+            # 生成步建议有提示词输入 + directive
+            if kind in ("step", "nested") and isinstance(s.get("action"), str) and s["action"].split("/")[0] == "生成":
+                in_types = {io.get("type") for io in s.get("inputs") or [] if isinstance(io, dict)}
+                if not in_types & {"提示词", "负向提示词", "描述"}:
+                    rep.warn(spath, "生成步没有 提示词/描述 类输入 — 确认是否漏建")
+
+        # value 逐字核对 (有 --source 才跑)
+        if source_text:
+            for s in steps:
+                if not isinstance(s, dict):
+                    continue
+                for arr in ("inputs", "outputs"):
+                    for i, io in enumerate(s.get(arr) or []):
+                        if not isinstance(io, dict):
+                            continue
+                        v = io.get("value")
+                        if not isinstance(v, str) or v.lstrip().startswith("<"):
+                            continue  # 媒体类描述不要求逐字
+                        nv = norm_ws(v)
+                        if len(nv) >= 40 and nv not in source_text:
+                            rep.warn(f"{pid}.{s.get('id','s?')}.{arr}[{i}]",
+                                     f"value ({len(nv)} 字) 未在原文/OCR 逐字命中 — 确认没缩写/改写"
+                                     f" (可加 --fix-verbatim 自动替换为原文片段)")
+    return rep
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    ap.add_argument("--workflow", required=True)
+    ap.add_argument("--source", help="原文 case json — 给了才跑 value 逐字核对")
+    ap.add_argument("--ocr", help="配图 OCR 文本, 并入逐字核对语料")
+    ap.add_argument("--fix-verbatim", action="store_true",
+                    help="把未逐字命中的文本 value 自动替换为原文里最相似的连续片段 "
+                         "(相似度 ≥60%% 才动, 改不动的留警告; 需要 --source)")
+    args = ap.parse_args()
+
+    try:
+        wf = json.loads(Path(args.workflow).read_text(encoding="utf-8"))
+    except FileNotFoundError:
+        print(f"✗ 文件不存在: {args.workflow}")
+        return 2
+    except json.JSONDecodeError as e:
+        print(f"✗ JSON 解析失败: {e}")
+        return 1
+
+    vocab = {
+        "effect_leaves": EFFECT_LEAVES,
+        "action_leaves": set(ACTION_LEAF2PATH),
+        "action_paths": set(ACTION_LEAF2PATH.values()),
+        "type_leaves": TYPE_LEAVES,
+    }
+
+    source_text = ""
+    docs = []          # 逐字段文档 [(norm, idx_map, raw)], --fix-verbatim 用 (片段不跨字段拼)
+    if args.source:
+        chunks = []
+        collect_strings(json.loads(Path(args.source).read_text(encoding="utf-8")), chunks)
+        source_text = norm_ws("".join(chunks))
+        docs = [(*_norm_map(c), c) for c in chunks if len(norm_ws(c)) >= 40]
+    if args.ocr and Path(args.ocr).exists():
+        ocr_raw = Path(args.ocr).read_text(encoding="utf-8")
+        source_text += norm_ws(ocr_raw)
+        docs.append((*_norm_map(ocr_raw), ocr_raw))
+
+    if args.fix_verbatim:
+        if not docs:
+            print("✗ --fix-verbatim 需要 --source (原文语料)")
+            return 2
+        fixed, skipped = fix_verbatim(wf, docs)
+        if fixed:
+            Path(args.workflow).write_text(
+                json.dumps(wf, ensure_ascii=False, indent=2), encoding="utf-8")
+        for p, r, a, b in fixed:
+            print(f"  ✦ [{p}] value 已替换为原文逐字片段 (相似度 {r:.0%}, {a}→{b} 字)")
+        for p, r in skipped:
+            print(f"  ⚠ [{p}] 找不到足够相似的原文连续片段 (最高 {r:.0%}) — 可能是多段拼接/自创内容, 人工处理")
+
+    rep = validate(wf, vocab, source_text)
+
+    for path, msg in rep.errors:
+        print(f"  ✗ [{path}] {msg}")
+    for path, msg in rep.warns:
+        print(f"  ⚠ [{path}] {msg}")
+    print(f"[validate] {args.workflow}: {len(rep.errors)} 错误, {len(rep.warns)} 警告")
+    return 1 if rep.errors else 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 109 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/vocab.py

@@ -0,0 +1,109 @@
+"""procedure skill 词表常量 — validate.py / wf-patch.py 共用的单一来源.
+
+与 SKILL.md 内嵌的三棵词表树一一对应 (叶子名 → 根/…/叶 全路径); 改词表时两处同步改.
+本 skill 不再携带 taxonomy json — 人读 SKILL.md, 机器读这里.
+"""
+
+EFFECT_LEAF2PATH = {
+    '工艺规约': '制作/准备阶段/工艺规约',
+    '预准备': '制作/准备阶段/预准备',
+    '预处理': '制作/准备阶段/预处理',
+    '主体生成': '制作/加工阶段/主体生成',
+    '装配': '制作/加工阶段/装配',
+    '后期': '制作/收尾阶段/后期',
+    '配套伴生': '制作/收尾阶段/配套伴生',
+    '检验': '制作/收尾阶段/检验',
+    '交付': '制作/收尾阶段/交付',
+}
+
+ACTION_LEAF2PATH = {
+    '检索': '获取/搜索/检索',
+    '下载': '获取/搜索/下载',
+    '调取': '获取/查询/调取',
+    '上传': '获取/录入/上传',
+    '拍摄': '获取/录入/拍摄',
+    '录音': '获取/录入/录音',
+    '键入': '获取/录入/键入',
+    '选取': '获取/引用/选取',
+    '裁切': '提取/物理提取/裁切',
+    '抠取': '提取/物理提取/抠取',
+    '抽帧': '提取/物理提取/抽帧',
+    '识别': '提取/化学提取/识别',
+    '反推': '提取/化学提取/反推',
+    '解构': '提取/化学提取/解构',
+    '元素生成': '生成/元素生成',
+    '数组生成': '生成/关系生成/数组生成',
+    '结构生成': '生成/关系生成/结构生成',
+    '添加': '修改/增/添加',
+    '叠加': '修改/增/叠加',
+    '抹除': '修改/删/抹除',
+    '剪除': '修改/删/剪除',
+    '重述': '修改/变/重述',
+    '风格化': '修改/变/风格化',
+    '转换': '修改/变/转换',
+    '替换': '修改/变/替换',
+    '调整': '修改/变/调整',
+    '增强': '修改/变/增强',
+    '缓存': '存储/暂存/缓存',
+    '入库': '存储/沉淀/入库',
+    '存档': '存储/归档/存档',
+}
+
+TYPE_LEAF2PATH = {
+    '提示词': '程序控制类型/指令/提示词',
+    '负向提示词': '程序控制类型/指令/负向提示词',
+    '描述': '程序控制类型/指令/描述',
+    '生成参数': '程序控制类型/参数/生成参数',
+    '规格参数': '程序控制类型/参数/规格参数',
+    '模型权重': '程序控制类型/参数/模型权重',
+    '评分': '程序控制类型/评估/评分',
+    '评语': '程序控制类型/评估/评语',
+    '工作流': '程序控制类型/流程/工作流',
+    '批处理': '程序控制类型/流程/批处理',
+    '数字人': '数据复用类型/原子/数字人',
+    '版式': '数据复用类型/原子/版式',
+    '模板': '数据复用类型/序列/模板',
+    '参考图': '内容类型/素材/化学变化/参考图',
+    '参考视频': '内容类型/素材/化学变化/参考视频',
+    '参考音频': '内容类型/素材/化学变化/参考音频',
+    '对标内容': '内容类型/素材/化学变化/对标内容',
+    '分镜图': '内容类型/素材/化学变化/分镜图',
+    '转场': '内容类型/素材/化学变化/转场',
+    '蒙版': '内容类型/素材/化学变化/蒙版',
+    '控制图': '内容类型/素材/化学变化/控制图',
+    '运动轨迹': '内容类型/素材/化学变化/运动轨迹',
+    '滤镜': '内容类型/素材/化学变化/滤镜',
+    '构图布局': '内容类型/素材/化学变化/构图布局',
+    '截图': '内容类型/素材/物理变化/截图',
+    '视频片段': '内容类型/素材/物理变化/视频片段',
+    '转场片段': '内容类型/素材/物理变化/转场片段',
+    '关键帧': '内容类型/素材/物理变化/关键帧',
+    '音效': '内容类型/素材/物理变化/音效',
+    '特效': '内容类型/素材/物理变化/特效',
+    '大纲': '内容类型/半成品/序列/大纲',
+    '脚本': '内容类型/半成品/序列/脚本',
+    '分镜脚本': '内容类型/半成品/序列/分镜脚本',
+    '剪辑脚本': '内容类型/半成品/序列/剪辑脚本',
+    '配音文案': '内容类型/半成品/序列/配音文案',
+    '底图': '内容类型/半成品/原子/底图',
+    '样图': '内容类型/半成品/原子/样图',
+    '分镜视频': '内容类型/半成品/原子/分镜视频',
+    '图层组合': '内容类型/半成品/组合/图层组合',
+    '拼图': '内容类型/半成品/组合/拼图',
+    '歌词': '内容类型/准成品/歌词',
+    '配音': '内容类型/准成品/配音',
+    'BGM': '内容类型/准成品/BGM',
+    '字幕': '内容类型/准成品/字幕',
+    '标题': '内容类型/准成品/标题',
+    '正文': '内容类型/准成品/正文',
+    '成品图': '内容类型/成品/成品图',
+    '视频成品': '内容类型/成品/视频成品',
+    '合成图': '内容类型/成品/合成图',
+    '知识库': '知识类型/知识库',
+}
+
+ACTION_CONTROL = ['并行', '遍历', '分支', '请求', '等待']
+
+EFFECT_LEAVES = set(EFFECT_LEAF2PATH)
+ACTION_LEAVES = set(ACTION_LEAF2PATH)
+TYPE_LEAVES = set(TYPE_LEAF2PATH)

+ 957 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/procedure/tools/wf-patch.py

@@ -0,0 +1,957 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+wf-patch.py — workflow.json 的安全批量字段设置器 (procedure skill 版).
+
+procedure skill 的主路径是**直接 Write/Edit workflow.json**; 本工具是批量修错的快捷方式:
+  validate.py 报出几十条同类错误 (整批 anchor / 整批 effect/action) 时, 用 Edit
+  一处一处改太碎, 手写整段 JSON 又易踩转义坑. wf-patch 卡在中间:
+  **你只负责语义决策 (path=value), 工具负责安全落盘 + 合法性校验**.
+
+  - 安全 IO: 工具自己 json.load -> 改 -> json.dump(ensure_ascii=False), 你永远不手写 JSON.
+  - 写入即校验 (fail-fast): 每条赋值立刻对照词表 / type_registry / anchor 格式校验,
+    **任何一条非法 -> 报具体哪条错, 整批不写**. 词表与 validate.py 同源 (vocab.py).
+
+用法:
+    # 单条 / 多条 --set (path=value, 只在第一个 '=' 处切, value 可含 '=' 和空格)
+    python procedure/tools/wf-patch.py --workflow outputs/case-N/workflow.json \
+        --set 'p1.s1.inputs[0].anchor=← s0.主角图' \
+        --set 'p1.s2.effect=主体生成' \
+        --set 'p1.s2.action=生成/图像生成/文生图'
+
+    # 或一次性喂一份 patch 清单 (适合 1.3 加 anchor / 2A 填字段这种几十处批量)
+    python procedure/tools/wf-patch.py --workflow outputs/case-N/workflow.json --patch _scratch/anchors.json
+    # anchors.json = [{"path": "p1.s1.inputs[0].anchor", "value": "← s0.x"}, ...]
+
+    # 只校验不写
+    python procedure/tools/wf-patch.py --workflow ... --set '...' --dry-run
+
+    # 删字段 (取代手 Edit 删; 字段不存在则幂等跳过)
+    python procedure/tools/wf-patch.py --workflow ... --unset 'p1.declarations.inputs[0].inferred'
+
+    # 只校验不写
+    python procedure/tools/wf-patch.py --workflow ... --set '...' --dry-run
+
+路径语法 (proc/step 主用 id (p1/s1), 下标 procedures[N].steps[M] 也接受; inputs/outputs 用 [i]; 嵌套步 id 带点 s2.1 也支持):
+    p1.s2.effect                      step 标量字段 (effect/substance/form/via/action/directive/kind/intent/group)
+    p1.s1.inputs[0].anchor            IO 字段 (anchor/type/value/id)
+    p1.s2.focus                       step 的 focus 数组 (逗号分隔: focus=via,action,out-type-0)
+    p1.purpose                        procedure 头部字段 (name/purpose/category/platform/author)
+    p1.declarations.inputs[0].desc    declarations 内任意字段 (通用下钻)
+    source.url                        case-level 原帖信息 (platform/author/date/url/title/excerpt)
+    p1.type_registry.场景图.extends    注册 case-specific 类型 (会自动建 type_registry 段)
+
+value 特殊取值:
+    __null__   -> JSON null (用于 substance/form/url 可空)
+
+仍用 Write / Edit 的只剩 (尽量别碰生 JSON):
+    - workflow.json 骨架的首次创建 (Phase 1.2 从 template Write)
+    - instruction (列表套列表, 手动 Edit; 透传 directive 用 --resolve-passthrough)
+    改字段/删字段/改 source 现在都走本工具, 不要再 Read→Edit 改 workflow.json (会反复重读、烧 token).
+
+自动修引号 (load 时兜底):
+    workflow.json 由模型直 Write, 偶尔把中文引号写成未转义的 ASCII " → JSON 崩.
+    本工具 load 失败时会自动把这类误引号修成「」再 parse; 修成功则继续 patch, 并把
+    修复随本次写回落盘 (--dry-run 不写). 修不回才按 exit 2 报错. 不用再手写 _scratch 修复脚本.
+
+退出码:
+    0  全部校验通过并写入 (--dry-run 时为校验通过)
+    1  有校验失败 (整批未写) / 路径解析失败
+    2  CLI 参数错误 / 文件不存在 / JSON 损坏 (且自动修引号也救不回)
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import re
+import sys
+from pathlib import Path
+
+# 词表常量与 validate.py 同源 (同目录 vocab.py); 被当脚本跑时 sys.path[0] 即本目录.
+sys.path.insert(0, str(Path(__file__).resolve().parent))
+from vocab import (EFFECT_LEAF2PATH, ACTION_LEAF2PATH, TYPE_LEAF2PATH,  # noqa: E402
+                   ACTION_CONTROL, EFFECT_LEAVES, ACTION_LEAVES, TYPE_LEAVES)
+
+# Windows 控制台 UTF-8
+for _s in (sys.stdout, sys.stderr):
+    if hasattr(_s, 'reconfigure'):
+        try:
+            _s.reconfigure(encoding='utf-8', errors='replace')
+        except Exception:
+            pass
+
+KIND_VOCAB = {'step', 'block', 'nested'}
+
+# value/directive 里的「引用占位」文案 — 这些是 anchor 的活, value 应填数据本身.
+# 命中即视为「未真正回填」(--resolve-passthrough 会尝试填, lint 会报警).
+META_REF = re.compile(r'[((]?\s*同\s*s[\d]|见\s*s[\d]|←\s*s[\d]|同上')
+
+
+# ===========================================================================
+# 自动修引号: 模型直 Write workflow.json 时常把中文引号写成 ASCII " (未转义) → JSON 崩.
+# 仅在 json.loads 失败时兜底调用 (合法文件零开销). 判别: 串内一个 ASCII " 之后第一个
+# 非空白字符 ∈ {,:}]} 或 EOF → 真·字符串定界符 (保留); 否则是误写的内容引号 → 换直角
+# 引号「」(串内交替 开「/闭」). 逻辑独立内置于本文件 (不 import 任何外部模块);
+# scratch/repair_workflow_quotes.py 是同款独立实现, 二者无依赖关系. 改完必须能 parse 才用.
+# ===========================================================================
+
+_STRUCT_AFTER = set(',:}]')
+
+
+def repair_ascii_quotes(raw: str):
+    """→ (修后文本, 改动的内容引号数). 纯走字符, 不依赖能否 parse."""
+    out, i, n = [], 0, len(raw)
+    in_str = esc = False
+    open_q = True
+    changes = 0
+    while i < n:
+        c = raw[i]
+        if not in_str:
+            out.append(c)
+            if c == '"':
+                in_str, esc, open_q = True, False, True
+            i += 1
+            continue
+        if esc:
+            out.append(c); esc = False; i += 1; continue
+        if c == '\\':
+            out.append(c); esc = True; i += 1; continue
+        if c == '"':
+            j = i + 1
+            while j < n and raw[j] in ' \t\r\n':
+                j += 1
+            nxt = raw[j] if j < n else ''
+            if nxt == '' or nxt in _STRUCT_AFTER:
+                out.append(c); in_str = False          # 真·结束符
+            else:
+                out.append('「' if open_q else '」')     # 误写的内容引号
+                open_q = not open_q
+                changes += 1
+            i += 1
+            continue
+        out.append(c); i += 1
+    return ''.join(out), changes
+
+
+class PathError(Exception):
+    """路径无法解析到 workflow.json 里的目标位置."""
+
+
+# ===========================================================================
+# 词表 (vocab.py 常量; 变量名沿用旧 *_PATHS = {leaf: 全路径} 约定, 校验逻辑零改动)
+# ===========================================================================
+
+EFFECT_PATHS = EFFECT_LEAF2PATH
+ACTION_PATHS = ACTION_LEAF2PATH
+TYPE_PATHS = TYPE_LEAF2PATH
+
+def _closest(name: str, leaves) -> str:
+    """给个最接近的叶子名做提示 (子串/前缀朴素匹配, 仅供报错文案)."""
+    cands = [lf for lf in leaves if name and (name in lf or lf in name)]
+    return (' 最接近: ' + '/'.join(cands[:3])) if cands else ''
+
+
+def _leaf_menu(field: str) -> str:
+    """校验失败时把该词表的**完整合法叶子**摆出来, 让模型直接照抄、别瞎猜反复试。
+
+    三张词表都很小 (effect 9 / action 30 / type 50), 整列得起。比"去读文件"更直接:
+    模型不用多花一次 read_file, 报错里就有菜单。每个失败字段类型只在末尾打一次。
+    """
+    if field == 'effect':
+        return ('合法 effect 叶子 (照抄其一): ' + ' / '.join(sorted(EFFECT_LEAVES))
+                + '  [词表树见 procedure/SKILL.md]')
+    if field == 'action':
+        byb: dict = {}
+        for p in sorted(set(ACTION_PATHS.values())):
+            byb.setdefault(p.split('/')[0], []).append(p)
+        body = '; '.join(' | '.join(byb[b]) for b in sorted(byb))
+        return ('合法 action 叶路径 (照抄其一, 全集): ' + body
+                + '  [词表树见 procedure/SKILL.md]')
+    if field in ('type', 'extends'):
+        return ('合法 type 叶子 (extends 挂靠照抄其一): ' + ' / '.join(sorted(TYPE_LEAVES))
+                + '  [词表树见 procedure/SKILL.md]')
+    return ''
+
+
+# ===========================================================================
+# 字段校验 -> (ok, normalized_value, err_msg)
+# ===========================================================================
+
+def validate_field(field: str, value, proc: dict, pending_types: set[str] = None):
+    # null 哨兵 (substance/form/url 可空)
+    if value == '__null__':
+        if field in ('substance', 'form', 'url'):
+            return True, None, ''
+        return False, value, f'__null__ 只对 substance/form/url 有意义, {field} 不可为 null'
+
+    # focus 是数组: 逗号分隔 → list ('via,action,out-type-0'); 空串 → []
+    if field == 'focus':
+        items = [t.strip() for t in str(value).split(',') if t.strip()]
+        return True, items, ''
+
+    if field == 'effect':
+        if value in EFFECT_LEAVES:
+            return True, value, ''
+        # 给了全路径 -> 归一到叶名 (schema 存叶名)
+        for leaf, path in EFFECT_PATHS.items():
+            if value == path:
+                return True, leaf, ''
+        # 容错: 路径里有某段是合法叶名 → 取最末的那个
+        segs = [s.strip() for s in str(value).split('/') if s.strip()]
+        for seg in reversed(segs):
+            if seg in EFFECT_LEAVES:
+                return True, seg, ''
+        return False, value, f'effect={value!r} 不是 effect 词表叶子(存叶名).{_closest(segs[-1] if segs else str(value), EFFECT_LEAVES)}'
+
+    if field == 'action':
+        # action 存全路径; 给叶名自动展开, 给全叶路径原样接受
+        if value in ACTION_PATHS:                 # 是叶名
+            return True, ACTION_PATHS[value], ''
+        if value in ACTION_PATHS.values():        # 是合法叶路径
+            return True, value, ''
+        # 容错: 路径里有某段是合法叶名(多写了段 / 前缀错, 如 生成/元素生成/文生图)→ 取最末的合法叶, 纠正到其全路径
+        segs = [s.strip() for s in str(value).split('/') if s.strip()]
+        for seg in reversed(segs):
+            if seg in ACTION_PATHS:
+                return True, ACTION_PATHS[seg], ''
+        return False, value, (f'action={value!r} 不是合法动作叶子/叶路径 '
+                              f'(对到 action 词表的叶子, 如 元素生成、提取/化学提取/反推).{_closest(segs[-1] if segs else str(value), ACTION_LEAVES)}')
+
+    if field == 'type':
+        # type 是自由标签: Phase 1 随便起个描述性词即可, 不校验是否叶子/注册。
+        # 「对到 type.json 标准叶子 / 注册 type_registry 挂靠」是 Phase 2 归类的活;
+        # 最终是否合法由 lint-case (Check 1: 揪未注册的 case-specific type) + render schema 兜底。
+        if isinstance(value, str) and value.strip():
+            return True, value.strip(), ''
+        return False, value, 'type 不能为空'
+
+    if field == 'extends':                        # type_registry entry 的 extends 必须桥到 stdlib 叶子
+        if value in TYPE_LEAVES:
+            return True, value, ''
+        return False, value, f'type_registry extends={value!r} 必须是 type 词表叶子.{_closest(value, TYPE_LEAVES)}'
+
+    if field in ('substance', 'form'):
+        # 自由提炼的元素点 — 不查词表、不校验 (README「第二阶段 · 2.1 实质 / 形式」).
+        # 字符串原样存 (如 "人物、卧室场景"), 数组逐项 strip 后存. 旧的 taxonomy-lookup 校验已废弃.
+        if isinstance(value, str):
+            return True, value.strip(), ''
+        if isinstance(value, list):
+            return True, [str(p).strip() for p in value if str(p).strip()], ''
+        return False, value, f'{field} 必须是字符串或数组'
+
+    if field == 'anchor':
+        if re.match(r'^\s*(←|→)', str(value)):
+            return True, value, ''
+        return False, value, f'anchor={value!r} 须以 ← (输入引用) 或 → (输出去向) 开头'
+
+    if field == 'kind':
+        if value in KIND_VOCAB:
+            return True, value, ''
+        return False, value, f'kind={value!r} 不在 {sorted(KIND_VOCAB)}'
+
+    # 自由文本字段 (name/value/intent/via/purpose/category/platform/author/desc/group...)
+    return True, value, ''
+
+
+# ===========================================================================
+# 路径解析 -> (parent_container, key, proc, field_name)
+# ===========================================================================
+
+_SEG = re.compile(r'^([^\[]+)(?:\[(\d+)\])?$')
+
+
+def _split_seg(seg: str):
+    m = _SEG.match(seg)
+    if not m:
+        raise PathError(f'非法路径段 {seg!r}')
+    return m.group(1), (int(m.group(2)) if m.group(2) is not None else None)
+
+
+def _descend(container, segs, create=False):
+    """沿 segs 走进 container, 返回 (parent, last_key). create=True 时自动建中间节点.
+
+    segs 每段可带 [i] 下标. last_key 是 dict 键 (str) 或列表下标 (int);
+    设置即 parent[last_key]=value, 删除即 del parent[last_key].
+    用于 source.* / declarations.* 等通用路径 (proc/step 的 id 寻址不走这里).
+    """
+    cur = container
+    for i, seg in enumerate(segs):
+        name, idx = _split_seg(seg)
+        last = (i == len(segs) - 1)
+
+        if idx is None:
+            if last:
+                if not isinstance(cur, dict):
+                    raise PathError(f'{name!r} 的父级不是对象')
+                return cur, name
+            if not isinstance(cur, dict):
+                raise PathError(f'路径段 {name!r} 的父级不是对象')
+            if name not in cur:
+                if not create:
+                    raise PathError(f'路径段 {name!r} 不存在, 无法下钻')
+                cur[name] = {}
+            cur = cur[name]
+        else:
+            if not isinstance(cur, dict):
+                raise PathError(f'路径段 {name!r} 的父级不是对象')
+            if name not in cur:
+                if not create:
+                    raise PathError(f'路径段 {name!r} 不存在, 无法下钻')
+                cur[name] = []
+            lst = cur[name]
+            if not isinstance(lst, list):
+                raise PathError(f'{name} 不是列表')
+            if idx >= len(lst):
+                if not create:
+                    raise PathError(f'{name}[{idx}] 越界或非列表')
+                while idx >= len(lst):
+                    lst.append({})
+            if last:
+                return lst, idx
+            cur = lst[idx]
+    raise PathError('路径为空')
+
+
+# ── --create 自动建结构用的骨架 ─────────────────────────────────────────────
+_STEP_SCALARS = {'effect', 'substance', 'form', 'via', 'action', 'directive', 'kind', 'intent', 'group'}
+
+
+def _new_procedure(pid: str) -> dict:
+    return {
+        'id': pid, 'name': '', 'purpose': '', 'category': '', 'platform': '', 'author': '',
+        'declarations': {'inputs': [], 'resources': [], 'returns': {}},
+        'steps': [],
+    }
+
+
+def _new_step(sid: str) -> dict:
+    return {'id': sid, 'kind': 'step', 'via': '', 'inputs': [], 'outputs': []}
+
+
+def _new_io(is_output: bool, sid: str, idx: int) -> dict:
+    if is_output:
+        return {'id': f'{sid}o{idx + 1}', 'type': '', 'value': '', 'anchor': ''}
+    return {'type': '', 'value': '', 'anchor': ''}
+
+
+def _split_step_path(remainder: str):
+    """create 模式下 step 不存在、无法前缀匹配时, 从路径切出 (sid, fsegs).
+
+    规则: 出现 inputs[i]/outputs[i] 段 → 其前为 sid; 否则末段须是已知 step 标量字段, 其前为 sid.
+    sid 可含点 (嵌套步 s2.1)。切不出返回 (None, None) — 不创建, 避免误建。
+    """
+    segs = remainder.split('.')
+    for j, s in enumerate(segs):
+        nm, _ = _split_seg(s)
+        if nm in ('inputs', 'outputs'):
+            return ('.'.join(segs[:j]) or None), segs[j:]
+    if segs[-1] in _STEP_SCALARS:
+        return ('.'.join(segs[:-1]) or None), [segs[-1]]
+    return None, None
+
+
+def locate(data: dict, path: str, create: bool = False):
+    """把 path 解析到目标. 返回 (parent, key, proc, field_name).
+
+    设置即 parent[key] = value. proc 给校验提供 type_registry 上下文.
+    proc / step 主用 id 寻址 (p1/s1), 也接受下标 procedures[N]/steps[M]; inputs/outputs 用 [i] 下标.
+    step id 可能带点 (嵌套步 s2.1) — 用最长前缀匹配消歧 (s2.1 优先于 s2).
+    create=True (构建模式): 缺失的 procedure / step / IO 元素 / 中间结构自动创建, 新建打印到 stderr.
+    """
+    if '.' not in path:
+        raise PathError(f'路径太短 {path!r}, 至少 <proc>.<字段> 或 source.<字段>')
+
+    proc_id, remainder = path.split('.', 1)
+
+    # --- source.* 分支 (case-level 原帖信息, 无 proc 上下文) ---
+    if proc_id == 'source':
+        src = data.setdefault('source', {})
+        parent, key = _descend(src, remainder.split('.'), create=create)
+        return parent, key, None, (key if isinstance(key, str) else '')
+
+    procs = data.setdefault('procedures', [])
+    # 接受两种 proc 寻址: id (p1) 或下标别名 procedures[N] (映射到第 N 个工序; 弱模型爱用这种)
+    m_idx = re.match(r'^procedures\[(\d+)\]$', proc_id)
+    if m_idx:
+        idx = int(m_idx.group(1))
+        if idx < len(procs):
+            proc = procs[idx]
+        elif create:
+            proc = _new_procedure(f'p{idx + 1}')
+            procs.append(proc)
+            print(f'[wf-patch] + 新建 procedure p{idx + 1} (来自 procedures[{idx}])', file=sys.stderr)
+        else:
+            raise PathError(f'procedures[{idx}] 越界 (现有 {len(procs)} 个工序)')
+    else:
+        proc = next((p for p in procs if p.get('id') == proc_id), None)
+        if proc is None:
+            if not create:
+                ids = [p.get('id') for p in procs]
+                raise PathError(f'找不到 procedure id={proc_id!r} (现有: {ids})')
+            proc = _new_procedure(proc_id)
+            procs.append(proc)
+            print(f'[wf-patch] + 新建 procedure {proc_id}', file=sys.stderr)
+
+    # --- type_registry 分支 (允许自动建段/条目) ---
+    if remainder == 'type_registry' or remainder.startswith('type_registry.'):
+        parts = remainder.split('.')
+        if len(parts) == 3:
+            reg = proc.setdefault('type_registry', {})
+            entry = reg.setdefault(parts[1], {})
+            return entry, parts[2], proc, parts[2]
+        raise PathError('type_registry 路径形如 p1.type_registry.<类型名>.<extends|desc>')
+
+    # --- step 分支: 支持 id 寻址 (p1.s1.effect) 和下标寻址 (procedures[0].steps[0].effect) ---
+    matched, field_part = None, None
+    m_step = re.match(r'^steps\[(\d+)\]\.(.+)$', remainder)   # 下标寻址 steps[N].<字段>
+    if m_step:
+        sidx = int(m_step.group(1))
+        steps = proc.setdefault('steps', [])
+        if sidx < len(steps):
+            matched = steps[sidx]
+        elif create:
+            matched = _new_step(f's{sidx + 1}')
+            steps.append(matched)
+            print(f'[wf-patch] + 新建 step (procedures.steps[{sidx}] → id s{sidx + 1})', file=sys.stderr)
+        else:
+            raise PathError(f'steps[{sidx}] 越界 (该工序现有 {len(steps)} 步)')
+        field_part = m_step.group(2)
+    else:                                                     # id 寻址: 最长前缀匹配现有 step id
+        for s in (proc.get('steps') or []):
+            sid = s.get('id')
+            if not sid:
+                continue
+            if remainder == sid:
+                raise PathError(f'step 路径要带字段, 形如 {proc_id}.{sid}.effect')
+            if remainder.startswith(sid + '.') and (matched is None or len(sid) > len(matched['id'])):
+                matched = s
+        if matched is None and create:
+            sid_new, _ = _split_step_path(remainder)
+            if sid_new:
+                matched = _new_step(sid_new)
+                proc.setdefault('steps', []).append(matched)
+                print(f'[wf-patch] + 新建 step {proc_id}.{sid_new}', file=sys.stderr)
+        if matched is not None:
+            field_part = remainder[len(matched['id']) + 1:]   # 'sid.' 之后
+    if matched is not None:
+        sid = matched.get('id', '?')
+        fsegs = field_part.split('.')
+        name2, idx2 = _split_seg(fsegs[0])
+        if name2 in ('inputs', 'outputs'):
+            if idx2 is None:
+                raise PathError(f'{name2} 要带下标, 形如 {name2}[0]')
+            lst = matched.get(name2)
+            if not isinstance(lst, list):
+                if create:
+                    matched[name2] = lst = []
+                else:
+                    raise PathError(f'{proc_id}.{sid}.{name2}[{idx2}] 越界 (该 step 有 0 个 {name2})')
+            if idx2 >= len(lst):
+                if not create:
+                    raise PathError(f'{proc_id}.{sid}.{name2}[{idx2}] 越界 (该 step 有 {len(lst)} 个 {name2})')
+                while idx2 >= len(lst):
+                    lst.append(_new_io(name2 == 'outputs', sid, len(lst)))
+            if len(fsegs) != 2:
+                raise PathError(f'IO 路径形如 {proc_id}.{sid}.{name2}[{idx2}].anchor')
+            return lst[idx2], fsegs[1], proc, fsegs[1]
+        else:
+            if len(fsegs) != 1:
+                raise PathError(f'step 标量字段形如 {proc_id}.{sid}.{name2}')
+            return matched, name2, proc, name2
+
+    # --- proc 内其余路径: 头部字段 / declarations.* / return_row.* 等, 走通用下钻 ---
+    parent, key = _descend(proc, remainder.split('.'), create=create)
+    return parent, key, proc, (key if isinstance(key, str) else '')
+
+
+# ===========================================================================
+# 透传回填: anchor 为纯 ← sN.varname 的 IO, 从源 output 抄 value (逐字回填)
+# ===========================================================================
+
+def _is_fillable(value) -> bool:
+    """该 value 算「还没真正回填」吗 — 空 / 占位符 / 引用文案."""
+    if value in (None, '', '-'):
+        return True
+    return bool(META_REF.search(str(value)))
+
+
+def _passthrough_id(anchor):
+    """anchor 为 `← <output-id>` (可带 [i] 容器索引) → 返回 output id; 否则 None.
+
+    `← 工序输入` / `← s6 (链)` 等非纯 id 引用返回 None (无法确定唯一源 value).
+    """
+    m = re.match(r'^\s*←\s*([^\s\[((]+)', str(anchor or ''))
+    if not m:
+        return None
+    return m.group(1) or None
+
+
+def resolve_passthrough(data: dict):
+    """把 anchor 为纯透传 (← <output-id>)、value 仍空或占位的 input, 用源 output 的 value 逐字填上.
+
+    迭代到不动点 (处理链式透传). 返回 (filled_msgs, warn_msgs).
+    """
+    out_index = {}          # output id -> output item (读 value)
+    for p in data.get('procedures') or []:
+        for s in p.get('steps') or []:
+            for o in s.get('outputs') or []:
+                if isinstance(o, dict) and o.get('id'):
+                    out_index[o['id']] = o
+
+    def _src_value(rid):
+        src = out_index.get(rid)
+        if src is None or _is_fillable(src.get('value')):
+            return None
+        return src['value']
+
+    filled: list[str] = []
+    changed, rounds = True, 0
+    while changed and rounds < 20:
+        changed, rounds = False, rounds + 1
+        for p in data.get('procedures') or []:
+            for s in p.get('steps') or []:
+                for idx, io in enumerate(s.get('inputs') or []):
+                    if not isinstance(io, dict) or not _is_fillable(io.get('value')):
+                        continue
+                    rid = _passthrough_id(io.get('anchor'))
+                    val = _src_value(rid) if rid else None
+                    if val is None:
+                        continue
+                    io['value'] = val
+                    filled.append(
+                        f"{p.get('id')}.{s.get('id')}.inputs[{idx}].value "
+                        f"← 复制自 {rid} ({len(str(val))} 字)"
+                    )
+                    changed = True
+
+    # 仍填不动的透传 (源 id 找不到) → warn
+    warns: list[str] = []
+    for p in data.get('procedures') or []:
+        for s in p.get('steps') or []:
+            for idx, io in enumerate(s.get('inputs') or []):
+                if not isinstance(io, dict) or not _is_fillable(io.get('value')):
+                    continue
+                rid = _passthrough_id(io.get('anchor'))
+                if rid and out_index.get(rid) is None:
+                    warns.append(
+                        f"{p.get('id')}.{s.get('id')}.inputs[{idx}] anchor 指向 "
+                        f"{rid} 但找不到该 output id (检查 anchor / output id)"
+                    )
+    return filled, warns
+
+
+# ===========================================================================
+# 应用
+# ===========================================================================
+
+def load_patches(args) -> list[tuple[str, str]]:
+    """汇总 --set、--patch 与 --set-file 成 [(path, value), ...]."""
+    def _norm(v):
+        if isinstance(v, str):
+            # 将中文全角双角/单引号自动归一化为标准半角引号,更利于 AI 生图引擎和 Prompt 语法识别
+            v = v.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
+        return v
+
+    def _dq(x: str) -> str:
+        # 剥掉成对外层引号. cmd.exe 不剥单引号 → agent 写的 --set 'p.f=v' / p.f='v'
+        # 会把单引号原样传进来, 导致 path 变成 'p1 这种 (找不到 procedure). 这里兜底剥掉.
+        x = x.strip()
+        if len(x) >= 2 and x[0] == x[-1] and x[0] in ('"', "'"):
+            x = x[1:-1].strip()
+        return x
+
+    out: list[tuple[str, str]] = []
+    for s in args.set or []:
+        s = _dq(s)                           # 整体外层引号 (cmd 没剥的 'path=value')
+        if '=' not in s:
+            raise SystemExit(f'wf-patch: --set 缺 "=" : {s!r} (形如 path=value)')
+        path, value = s.split('=', 1)        # 只切第一个 '='
+        out.append((_dq(path), _norm(_dq(value))))
+
+    # 🟢 新增:从外部文件读取值注入
+    for sf in getattr(args, 'set_file', None) or []:
+        if '=' not in sf:
+            raise SystemExit(f'wf-patch: --set-file 缺 "=" : {sf!r} (形如 path=file_path)')
+        path, fpath_str = sf.split('=', 1)
+        fpath = Path(fpath_str.strip())
+        if not fpath.exists():
+            raise SystemExit(f'wf-patch: --set-file 指定的文件不存在: {fpath_str}')
+        try:
+            value = fpath.read_text(encoding='utf-8')
+        except Exception as e:
+            raise SystemExit(f'wf-patch: 无法读取 --set-file 指定的文件 {fpath_str}: {e}')
+        out.append((path.strip(), _norm(value)))
+
+    if args.patch:
+        if not args.patch.exists():
+            raise SystemExit(
+                f'wf-patch: --patch 文件不存在 {args.patch}\n'
+                f'  → --patch 的清单文件是**你要先写的输入**(扁平 `[{{"path":..,"value":..}}]` JSON)。\n'
+                f'    先 write_file 写出它, 再 `--patch` 跑它;\n'
+                f'    或字段不多时直接内联: `--set \'p1.s1.inputs[0].type=参考图\' --set ...`(不用文件)。')
+        try:
+            items = json.loads(args.patch.read_text(encoding='utf-8'))
+        except json.JSONDecodeError as e:
+            raise SystemExit(f'wf-patch: --patch 不是合法 JSON: {e}')
+        for it in items:
+            out.append((it['path'], _norm(it['value'])))
+    return out
+
+
+# ===========================================================================
+# @quote 标记回填: value/directive 写 `@quote|起锚|止锚` 或 `@quote|关键词`,
+# 由 --resolve-quotes 顺标记从原文/配图 OCR 匹配真实内容, 批量替换 (空白无关匹配)
+# ===========================================================================
+
+def _q_source_text(path: Path) -> str:
+    d = json.loads(path.read_text(encoding='utf-8'))
+    if not isinstance(d, dict):
+        return str(d)
+    return '\n'.join(str(d.get(k, '')) for k in ('title', 'body_text') if d.get(k))
+
+
+def _q_norm(text: str):
+    chars, idx = [], []
+    for i, ch in enumerate(text):
+        if ch.isspace():
+            continue
+        chars.append(ch)
+        idx.append(i)
+    return ''.join(chars), idx
+
+
+def _q_range_between(text: str, frm: str, to: str):
+    ns, idx = _q_norm(text)
+    nf, _ = _q_norm(frm)
+    nt, _ = _q_norm(to)
+    if not nf or not nt:
+        return None
+    p = ns.find(nf)
+    if p < 0:
+        return None
+    q = ns.find(nt, p + len(nf))
+    if q < 0:
+        return None
+    return text[idx[p]: idx[q + len(nt) - 1] + 1]
+
+
+def _q_braces(text: str, lo: int, hi: int):
+    depth, op, i = 0, None, lo
+    while i >= 0:
+        if text[i] == '}':
+            depth += 1
+        elif text[i] == '{':
+            if depth == 0:
+                op = i
+                break
+            depth -= 1
+        i -= 1
+    if op is None:
+        return None
+    depth, j = 0, op
+    while j < len(text):
+        if text[j] == '{':
+            depth += 1
+        elif text[j] == '}':
+            depth -= 1
+            if depth == 0:
+                return (op, j) if j >= hi else None
+        j += 1
+    return None
+
+
+def _q_query_block(text: str, query: str):
+    ns, idx = _q_norm(text)
+    nq, _ = _q_norm(query)
+    if not nq:
+        return None
+    p = ns.find(nq)
+    if p < 0:
+        return None
+    o_lo, o_hi = idx[p], idx[p + len(nq) - 1]
+    br = _q_braces(text, o_lo, o_hi)           # 命中落在 {...} 内 → 返回整块
+    if br:
+        return text[br[0]: br[1] + 1]
+    lo = text.rfind('\n', 0, o_lo) + 1          # 否则返回所在行/段
+    hi = text.find('\n', o_hi)
+    return text[lo: (hi if hi >= 0 else len(text))].strip()
+
+
+def resolve_quotes(data: dict, corpora: list):
+    """扫 value/directive 里的 `@quote|...` 标记, 顺标记从 corpora 匹配真实内容批量替换.
+
+    标记: `@quote|起锚|止锚` (范围, 推荐长段) 或 `@quote|关键词` (命中落 JSON 块返回整块, 否则所在行/段).
+    corpora: [(label, text), ...] 依次尝试 (原文优先, 再 OCR). 返回 (filled, warns).
+    """
+    filled, warns = [], []
+
+    def _resolve(v: str):
+        parts = v[len('@quote|'):].split('|')
+        for label, text in corpora:
+            r = _q_range_between(text, parts[0], parts[1]) if len(parts) >= 2 else _q_query_block(text, parts[0])
+            if r:
+                return r, label
+        return None, None
+
+    for p in data.get('procedures') or []:
+        pid = p.get('id')
+        for s in p.get('steps') or []:
+            sid = s.get('id')
+            d = s.get('directive')
+            if isinstance(d, str) and d.startswith('@quote|'):
+                r, label = _resolve(d)
+                if r:
+                    s['directive'] = r
+                    filled.append(f'{pid}.{sid}.directive ← [{label}] {len(r)} 字')
+                else:
+                    warns.append(f'{pid}.{sid}.directive: @quote 未匹配 {d[:40]!r}')
+            for kind in ('inputs', 'outputs'):
+                for k, item in enumerate(s.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    v = item.get('value')
+                    if isinstance(v, str) and v.startswith('@quote|'):
+                        r, label = _resolve(v)
+                        if r:
+                            item['value'] = r
+                            filled.append(f'{pid}.{sid}.{kind}[{k}].value ← [{label}] {len(r)} 字')
+                        else:
+                            warns.append(f'{pid}.{sid}.{kind}[{k}].value: @quote 未匹配 {v[:40]!r}')
+    return filled, warns
+
+
+def prune_patch_file(patch_path: Path, value_errors: list) -> int | None:
+    """把 --patch 文件裁成只剩**未成功 (value 校验失败)** 的条目, 成功的删掉。
+
+    成功项已落盘到 workflow.json, 留在 patch 里只会重复应用; 裁掉后 patch 文件就是
+    "剩余待修清单", 每条带 `_error` 失败原因 (再读时 path/value 之外的键被忽略, 无副作用)。
+    改完 value 重跑同一文件直到清空为 []。返回剩余条数; 文件读不动/不是数组返回 None。
+    """
+    try:
+        items = json.loads(patch_path.read_text(encoding='utf-8'))
+    except Exception:
+        return None
+    if not isinstance(items, list):
+        return None
+    err_by_path: dict = {}
+    for p, _field, msg in value_errors:
+        err_by_path.setdefault(p, msg)            # 同 path 多错只留第一条
+    remaining = []
+    for it in items:
+        if isinstance(it, dict) and it.get('path') in err_by_path:
+            it = {k: v for k, v in it.items() if k != '_error'}
+            it['_error'] = err_by_path[it['path']]
+            remaining.append(it)
+    patch_path.write_text(json.dumps(remaining, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
+    return len(remaining)
+
+
+def main() -> None:
+    ap = argparse.ArgumentParser(
+        prog='wf-patch.py',
+        description='workflow.json 安全批量字段设置器 (写入即校验, 任何一条非法整批不写)',
+    )
+    ap.add_argument('--workflow', type=Path, required=True, help='目标 workflow.json')
+    ap.add_argument('--set', action='append', metavar='PATH=VALUE',
+                    help='单条赋值, 可重复. 只在第一个 = 处切; value 可含 = 和空格 (记得整体加引号)')
+    ap.add_argument('--patch', type=Path, default=None,
+                    help='批量赋值清单 .json: [{"path":..,"value":..}, ...]')
+    ap.add_argument('--set-file', action='append', metavar='PATH=FILE_PATH', default=None,
+                    help='从外部文件读取内容注入指定字段. e.g. p1.s1.outputs[0].value=_scratch/prompt.txt')
+    ap.add_argument('--unset', action='append', metavar='PATH', default=None,
+                    help='删字段, 可重复. e.g. p1.declarations.inputs[0].inferred (字段不存在则跳过). 取代手 Edit 删字段')
+    ap.add_argument('--resolve-passthrough', action='store_true',
+                    help='把 anchor 为纯透传 (← sN.varname)、value 仍空/占位的 IO, 顺 anchor 从源 output 逐字抄 value. 可单独跑, 也可跟在 --set/--patch 后 (先赋值再解析). 迭代处理链式透传')
+    ap.add_argument('--dry-run', action='store_true', help='只校验/预演, 不写')
+    ap.add_argument('--create', action='store_true',
+                    help='(已默认开启, 保留兼容) 缺失的 procedure / step / IO 元素自动创建、文件不存在从空建')
+    ap.add_argument('--no-create', action='store_true',
+                    help='关闭自动建: 路径不存在就报错 (严格防 typo; 仅在「纯填充已存在结构、想抓打错的路径」时用)')
+    ap.add_argument('--resolve-quotes', action='store_true',
+                    help='把 value/directive 里的 @quote|起锚|止锚 (或 @quote|关键词) 标记, 顺标记从 --source 原文 / --ocr 配图文本匹配真实内容批量替换. 跟 anchor patch 一起跑')
+    ap.add_argument('--source', type=Path, default=None, help='--resolve-quotes 的原文 case json (匹配语料)')
+    ap.add_argument('--ocr', type=Path, default=None, help='--resolve-quotes 的配图 OCR 文本文件 (第二语料)')
+    ap.add_argument('--prune', action='store_true',
+                    help='跟 --patch 配合: 应用后把 patch 文件裁成只剩**未成功**的条目(成功的已落盘→删掉, '
+                         '失败的标 _error 原因保留)。patch 文件即变"剩余待修清单", 改完重跑同一文件直到清空。')
+    args = ap.parse_args()
+    # 默认 upsert (缺路径自动建); 弱模型增量 patch 总需要它, gated 反而一直撞「越界/不存在」死循环。
+    # --no-create 才关闭 (回到严格寻址、防 typo)。--create 保留为 no-op 兼容旧命令/文档。
+    args.create = not args.no_create
+
+    wf = args.workflow
+    repaired = 0
+    if args.create and not wf.exists():
+        data = {}
+        print(f'[wf-patch] + 新建 workflow 文件 {wf.name} (从空开始构建)', file=sys.stderr)
+    elif not wf.exists():
+        print(f'wf-patch: 文件不存在 {wf} (默认会从空新建; 你传了 --no-create 才不建)', file=sys.stderr)
+        sys.exit(2)
+    else:
+        raw = wf.read_text(encoding='utf-8')
+        try:
+            data = json.loads(raw)
+        except json.JSONDecodeError as e:
+            # 兜底: 试着把误写成 ASCII 的中文引号修成「」再 parse (模型直 Write 常见崩因)
+            fixed, repaired = repair_ascii_quotes(raw)
+            try:
+                data = json.loads(fixed)
+            except json.JSONDecodeError:
+                print(f'wf-patch: {wf} 不是合法 JSON, 无法处理: {e}\n'
+                      f'  → 去 workflow.json 第 {e.lineno} 行附近修语法 '
+                      f'(最常见: 数组 ] 或 对象 }} 结束后、下一个 "key" 前缺逗号), 修好再重跑。'
+                      f'别盲目重试本命令 (JSON 没修, 每次都同样报错)。', file=sys.stderr)
+                sys.exit(2)
+            print(f'[wf-patch] ⚠️ 原文件 JSON 非法 ({e.msg} @ line {e.lineno}); 已自动把 '
+                  f'{repaired} 处误写的 ASCII 引号修成「」→ 解析成功, 修复将随本次写回落盘',
+                  file=sys.stderr)
+
+    patches = load_patches(args)
+    unsets = args.unset or []
+    if not patches and not unsets and not args.resolve_passthrough and not args.resolve_quotes:
+        if args.patch:   # --patch 给了但解析为空 [] (多半是 --prune 收敛后): 算完成, 不是误用
+            print(f'wf-patch: {args.patch.name} 为空 [], 没有待应用项 (patch 已全部完成)。')
+            sys.exit(0)
+        print('wf-patch: 没有 --set / --patch / --unset / --resolve-passthrough / --resolve-quotes, 啥也没干', file=sys.stderr)
+        sys.exit(2)
+
+    # 解析 + 校验; 任何一条失败 -> 整批不写
+    pending_types = set()
+    for path, _ in patches:
+        m = re.match(r'^p\d+\.type_registry\.([^.]+)\.(extends|desc)$', path)
+        if m:
+            pending_types.add(m.group(1))
+
+    plan = []          # set: (parent, key, normalized_value, path, display)
+    del_plan = []      # unset: (parent, key, path)
+    skipped = []       # unset 跳过 (字段本就不在)
+    # 错误分两类, 决定原子 vs 部分应用:
+    #   fatal  = 路径/结构错 (locate 失败: 路径对不上、缺 --create 等) → 整批不写, 保护结构
+    #   value  = 字段值校验失败 (effect/action/type 等值非法) → **跳过这条、其余照写** (部分应用),
+    #            末尾以 exit 1 提示回去补。这样一批里几个值错不再连累其余正确字段一起丢。
+    fatal_errors = []  # (path, msg)
+    value_errors = []  # (path, msg)
+    for path, value in patches:
+        try:
+            parent, key, proc, field = locate(data, path, create=args.create)
+        except PathError as e:
+            fatal_errors.append((path, str(e)))
+            continue
+        ok, norm, msg = validate_field(field, value, proc, pending_types)
+        if not ok:
+            value_errors.append((path, field, msg))
+            continue
+        plan.append((parent, key, norm, path, norm if norm is not None else 'null'))
+    for path in unsets:
+        try:
+            parent, key, _proc, _field = locate(data, path)
+        except PathError as e:
+            fatal_errors.append((path, str(e)))
+            continue
+        present = (isinstance(parent, dict) and key in parent) or \
+                  (isinstance(parent, list) and isinstance(key, int) and key < len(parent))
+        (del_plan if present else skipped).append((parent, key, path) if present else path)
+
+    if patches or unsets:
+        n_fail = len(fatal_errors) + len(value_errors)
+        print(f'[wf-patch] {wf.name} — set {len(plan)}/{len(patches)} 通过, '
+              f'unset {len(del_plan)} 删/{len(skipped)} 跳过, {n_fail} 失败')
+        for _p, _k, _n, path, disp in plan:
+            print(f'  ✓ set   {path} = {disp}')
+        for _p, _k, path in del_plan:
+            print(f'  ✓ unset {path}')
+        for path in skipped:
+            print(f'  · skip  {path} (字段本就不存在)')
+        for path, _field, msg in value_errors:
+            print(f'  ✗ {path}  — {msg}')
+        for path, msg in fatal_errors:
+            print(f'  ✗✗ {path}  — {msg}  [路径/结构错]')
+        # 结构错 = patch 清单跟文件对不上 → 整批不写 (原子, 别半建坏骨架)
+        if fatal_errors:
+            print(f'\n有 {len(fatal_errors)} 条路径/结构错误, 整批未写入 (先修: 路径写对 / 该建的加 --create).',
+                  file=sys.stderr)
+            sys.exit(1)
+        # 只有字段值非法 → 跳过这几条、其余照常写, 进度不丢; 末尾 exit 1 提示去补
+        if value_errors:
+            # 把出错字段类型的**完整合法清单**打出来 (每类一次), 模型直接照抄、别再瞎猜反复试
+            shown = []
+            for _p, f, _m in value_errors:
+                key = 'type' if f == 'extends' else f
+                if key in ('effect', 'action', 'type') and key not in shown:
+                    shown.append(key)
+            for key in shown:
+                print(f'  ↳ {_leaf_menu(key)}', file=sys.stderr)
+            print(f'\n{len(value_errors)} 处字段值非法**已跳过未写**, 其余 {len(plan)} 处照常应用; '
+                  f'照上面清单选合法叶子, 修正这几条后重跑补上 (进度不丢, 别整批重来).', file=sys.stderr)
+
+    # 应用到内存 data (set 先 unset 后; resolve 要看到这些改动). 是否持久化由 dry-run 决定.
+    for parent, key, norm, _, _ in plan:
+        parent[key] = norm
+    for parent, key, _path in sorted(del_plan, key=lambda d: -d[1] if isinstance(d[1], int) else 0):
+        if isinstance(parent, list):
+            parent.pop(key)
+        else:
+            del parent[key]
+
+    # 透传回填
+    filled, warns = [], []
+    if args.resolve_passthrough:
+        filled, warns = resolve_passthrough(data)
+        print(f'[resolve-passthrough] 回填 {len(filled)} 处透传 value, {len(warns)} 处填不动')
+        for m in filled:
+            print(f'  ✓ {m}')
+        for w in warns:
+            print(f'  ⚠ {w}')
+
+    # @quote 标记回填 (顺 @quote|起锚|止锚 从原文/OCR 匹配真实内容批量替换)
+    quoted, qwarns = [], []
+    if args.resolve_quotes:
+        corpora = []
+        if args.source and args.source.exists():
+            corpora.append(('原文', _q_source_text(args.source)))
+        if args.ocr and args.ocr.exists():
+            corpora.append(('配图OCR', args.ocr.read_text(encoding='utf-8')))
+        if not corpora:
+            print('wf-patch: --resolve-quotes 需要 --source (或 --ocr) 指向匹配语料', file=sys.stderr)
+        else:
+            quoted, qwarns = resolve_quotes(data, corpora)
+            print(f'[resolve-quotes] 回填 {len(quoted)} 处 @quote 标记, {len(qwarns)} 处未匹配')
+            for m in quoted:
+                print(f'  ✓ {m}')
+            for w in qwarns:
+                print(f'  ⚠ {w}')
+
+    # 有字段值非法被跳过 → 退出码 1 (告诉 agent 还有几条要补), 但有效改动已照常落盘
+    final_exit = 1 if value_errors else 0
+
+    # --prune: 把 --patch 文件裁成只剩未成功项 (成功的已落盘→删, 失败的标 _error 留待修)。
+    # dry-run 不动文件 (预演不该有副作用); fatal 早已 exit, 到这里只剩 value 错或全成功。
+    if args.prune and args.patch and not args.dry_run:
+        nrem = prune_patch_file(args.patch, value_errors)
+        if nrem is not None:
+            if nrem:
+                print(f'\n[prune] 已把 {args.patch.name} 裁为剩余 {nrem} 条未成功项 '
+                      f'(成功的已删, 每条带 _error 原因); 修正 value 后重跑同一文件即可。', file=sys.stderr)
+            else:
+                print(f'\n[prune] {args.patch.name} 全部成功, 已清空为 []。', file=sys.stderr)
+
+    n_changes = len(plan) + len(del_plan) + len(filled) + len(quoted)
+    if args.dry_run:
+        extra = f' (+ 自动修复 {repaired} 处引号, dry-run 同样不写)' if repaired else ''
+        print(f'\n--dry-run: 预演 {n_changes} 处改动{extra}, 未写入.')
+        sys.exit(final_exit)
+
+    # repaired>0 时即便无字段改动也要落盘 (否则修好的引号没存下来, 文件还是坏的)
+    if n_changes == 0 and not repaired:
+        print('\n没有改动 (透传 value 都已填好 / 无可赋值), 未写文件.')
+        sys.exit(final_exit)
+
+    # 落盘 (安全序列化, 你从不手写 JSON)
+    wf.write_text(json.dumps(data, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
+    tail = f' (含自动修复 {repaired} 处引号→「」)' if repaired else ''
+    print(f'\n已写入 {n_changes} 处到 {wf.name}{tail}.')
+    sys.exit(final_exit)
+
+
+if __name__ == '__main__':
+    main()

+ 1302 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/run_cyber.py

@@ -0,0 +1,1302 @@
+#!/usr/bin/env python3
+"""
+run_cyber.py — run_procedure_dsl.py 的 Cyber Agent 移植版 (POC)。
+
+与 run_procedure_dsl.py 的唯一区别是**执行引擎**:
+  - run_procedure_dsl.py: Claude Agent SDK (ClaudeSDKClient) → 走 ~/.claude OAuth Max,
+    只能跑 Anthropic 协议端点。
+  - run_cyber.py:         本仓库自研 AgentRunner (agent/core/runner.py) → 多 Provider。
+    本 POC 默认走 OpenRouter (create_openrouter_llm_call), 一个 provider 通打
+    GPT / Gemini / Qwen / DeepSeek / Claude 全家, 换模型只改 --model 字符串。
+
+复用 run_procedure_dsl.py 的:
+  - 起手 prompt 全文 (_build_initial_blocks 的 text 块) —— 三阶段指令一字不改。
+  - 图片抽取 (_images_from_source) + 客户端下载缓存 (_url_to_cached_path)。
+图片块从 Anthropic base64 格式转成 OpenRouter 要的 OpenAI `image_url` data-URL 格式。
+
+单 Agent 全程跑 (与 spec 对齐, 见 spec/tools.md §7): Phase 2 (归类标注) 由主 Agent
+自己一趟做完, 不再分发 phase-2a/2b 子 Agent。RunConfig.exclude_tools 关掉
+agent/evaluate 两个分发工具, 防弱模型自作主张去 delegate。
+
+完成度判据走 lint-case.py --json (字段级规则只活在 spec/tools 一处, runner 不复刻);
+退出码: 0=completed / 2=失败 / 3=status unknown (跑完但引擎没回终态, 批量统计时单算) / 130=中断。
+
+用法 (与 run_procedure_dsl.py 对齐):
+    python run_cyber.py input/case-2-raw.json --out-dir case-2-cyber
+    python run_cyber.py input/case-2-raw.json --out-dir case-2-cyber \
+        --model openai/gpt-4o
+    # 中断后续跑 (从 outputs/<out-dir>/.trace_id 读 trace 接着跑):
+    python run_cyber.py input/case-2-raw.json --out-dir case-2-cyber --resume
+    # 批量: source 是 batch_posts.json (results[] 每项含 post), out-dir 是父目录,
+    # 每个工序一个子目录 outputs/<out-dir>/<case_id>/ (已出 HTML 的自动跳过):
+    python run_cyber.py input/batch_posts.json --out-dir batch-0610 --batch --model flash
+    # procedure skill (强模型直写版, 读 procedure/SKILL.md): 一次 write_file 出完整
+    # workflow.json + procedure/tools/validate.py 单工具校验, 不渲染 HTML:
+    python run_cyber.py input/case-2-raw.json --out-dir case-2-proc \
+        --skill procedure --model anthropic/claude-sonnet-4.6
+
+⚠️ POC 已知缺口 (非 Claude 模型上需逐步调):
+  - 起手 prompt 与 spec/ 里写的是 Claude 工具名 (Read/Write/Bash)。Cyber 实际工具是
+    read_file/write_file/edit_file/bash_command。下方 _cyber_runtime_note 给了映射, 但
+    spec 文档内 `详见 Read(...)` 这类示例仍是 Claude 名 —— 弱模型可能被带偏, 需观察 trace。
+  - edit_file 在非 Claude 模型上的 exact-match 命中率不如 Claude, workflow.json 反复 Edit
+    可能卡壳。先拿单 case smoke test, 别直接上量。
+"""
+import argparse
+import asyncio
+import base64
+import httpx
+import importlib.util
+import json
+import logging
+import os
+import subprocess
+import sys
+import time
+from datetime import datetime
+from pathlib import Path
+from typing import Any, Dict, List
+
+# run_cyber.py → procedure-dsl/
+DSL_ROOT = Path(__file__).resolve().parent
+
+
+def _find_repo_root(start: Path) -> Path:
+    """向上找含 pyproject.toml 的目录 (cyber-agent 仓库根), 用于 sys.path 兜底。"""
+    for p in [start, *start.parents]:
+        if (p / "pyproject.toml").exists():
+            return p
+    return start
+
+
+REPO_ROOT = _find_repo_root(DSL_ROOT)
+for _p in (str(REPO_ROOT), str(DSL_ROOT)):
+    if _p not in sys.path:
+        sys.path.insert(0, _p)
+
+# 技能本地「计划」内置工具 (plan_procedures): import 即把它注册进全局工具表 (groups=["core"]),
+# 主 Agent 因 tool_groups 含 core 而能看到它。Phase 1 第一步让 LLM 调用它做 understanding +
+# 自动生成 workflow.json 骨架。run_cyber 仅做注册 + 注入原文上下文, 业务逻辑全在 plan_tool.py。
+import plan_tool  # noqa: E402  (必须在 sys.path 设好之后)
+
+
+# 三阶段规格已全部并入 spec/README.md; 监听有没有 read_file README 判断「做了活却没读规则」
+_PHASE_FILES = {"README": "readme"}
+
+
+def _phase_read_gaps(out_dir: Path, read_phase: set) -> List[str]:
+    """检查 agent 有没有「做了某阶段的活却没读规则」(弱模型惯犯, 导致格式/规则全靠瞎猜)。
+
+    三阶段规则已合并进 spec/README.md, 所以只需确认 README 读过没。
+    判「做了某阶段」: Phase 1 = 建了 steps; Phase 2 = 填了 effect/action/intent; Phase 3 = 出了 HTML。
+    """
+    gaps: List[str] = []
+    if "readme" in read_phase:          # README 读过 = 三阶段规则都看过, 无 gap
+        return gaps
+    wf = out_dir / "workflow.json"
+    if not wf.exists():
+        return gaps
+    try:
+        d = json.loads(wf.read_text(encoding="utf-8"))
+    except Exception:
+        return gaps
+    did_p1 = any(p.get("steps") for p in d.get("procedures", []))
+    did_p2 = any((s.get("effect") or s.get("action") or s.get("intent"))
+                 for p in d.get("procedures", []) for s in (p.get("steps") or []) if isinstance(s, dict))
+    did_p3 = bool(list(out_dir.glob("*.html")))
+    done = [name for name, flag in (("第一阶段·搭骨架", did_p1),
+                                    ("第二阶段·填值+归类", did_p2),
+                                    ("第三阶段·渲染", did_p3)) if flag]
+    if done:
+        gaps.append(
+            f"你已经动了 {'、'.join(done)} 却**没 read_file** spec/README.md —— 三阶段全部规则"
+            "(字段填法、@quote、IO 校验、intent 的 {in-type:}/{out-type:} 标记、收尾检查清单)都在这一个文件里, "
+            "先读对应章节(第一/二/三阶段)再对照检查并修正你的输出。")
+    return gaps
+
+
+def _completion_gaps(out_dir: Path, spec_name: str = "spec") -> List[str]:
+    """跑完后查 workflow 是否真做完了 (防弱模型吐空消息提前自停)。返回未完成项清单, 空=完成。
+
+    判据: ① workflow.json 存在; ② lint-case.py 的「归类完成度」检查通过 (effect/action/intent
+    —— 字段级规则只活在 lint-case.py 一处, 这里消费它的 --json 输出, 不复刻); ③ 出了 HTML。
+    """
+    wf = out_dir / "workflow.json"
+    if not wf.exists():
+        return ["workflow.json 还没建 (Phase 1 没做完)"]
+    gaps: List[str] = []
+    lint = DSL_ROOT / spec_name / "tools" / "lint-case.py"
+    try:
+        r = subprocess.run(
+            [sys.executable, str(lint), "--workflow", str(wf), "--json", "--no-record"],
+            capture_output=True, text=True, encoding="utf-8", errors="replace",
+            cwd=str(DSL_ROOT), timeout=120,
+            env={**os.environ, "PYTHONIOENCODING": "utf-8"})
+        if r.returncode != 0:
+            gaps.append(f"workflow.json 没过 lint 解析 ({(r.stderr or '').strip()[:120]}) — 修好再继续")
+        else:
+            gaps.extend(json.loads(r.stdout).get("checks", {}).get("classification_done", []))
+    except Exception as e:
+        gaps.append(f"完成度检查失败 ({type(e).__name__}: {e}) — 确认 workflow.json 是合法 JSON")
+    if not list(out_dir.glob("*.html")):
+        gaps.append("还没渲染出 HTML (Phase 3 没做: 跑 render-case.py)")
+    return gaps
+
+
+# ── procedure skill (--skill procedure): 直写 workflow.json + validate.py 单工具 ──
+# 监听文件是 procedure/SKILL.md (规则单文件); 完成判据是 validate.py 退出码 (不渲染 HTML)。
+_PROCEDURE_PHASE_FILES = {"SKILL": "readme"}
+
+
+def _phase_read_gaps_procedure(out_dir: Path, read_phase: set) -> List[str]:
+    """procedure 模式版「做了活却没读规则」: 动了 workflow.json 却没 read_file SKILL.md。"""
+    if "readme" in read_phase or not (out_dir / "workflow.json").exists():
+        return []
+    return ["你已经写了 workflow.json 却**没 read_file** procedure/SKILL.md —— 全部规则"
+            "(结构、字段规范、词表、value 逐字要求)都在这一个文件里, 先读它再对照修正你的输出。"]
+
+
+def _completion_gaps_procedure(out_dir: Path, source_for_agent: str, ocr_path: Path) -> List[str]:
+    """procedure 模式完成度: workflow.json 存在 + validate.py 0 错误。
+
+    错误清单直接消费 validate.py 的 stdout ✗ 行 (字段级规则只活在 validate.py 一处, 不复刻)。
+    """
+    wf = out_dir / "workflow.json"
+    if not wf.exists():
+        return ["workflow.json 还没建"]
+    cmd = [sys.executable, str(DSL_ROOT / "procedure" / "tools" / "validate.py"),
+           "--workflow", str(wf), "--source", source_for_agent]
+    if ocr_path.exists():
+        cmd += ["--ocr", str(ocr_path)]
+    try:
+        r = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8",
+                           errors="replace", cwd=str(DSL_ROOT), timeout=120,
+                           env={**os.environ, "PYTHONIOENCODING": "utf-8"})
+    except Exception as e:
+        return [f"validate 跑不起来 ({type(e).__name__}: {e}) — 确认 workflow.json 是合法 JSON"]
+    if r.returncode == 0:
+        return []
+    errs = [ln.strip() for ln in (r.stdout or "").splitlines() if ln.strip().startswith("✗")]
+    if not errs:
+        errs = [f"validate 退出码 {r.returncode}: {(r.stderr or r.stdout or '').strip()[:200]}"]
+    if len(errs) > 15:
+        errs = errs[:15] + [f"…(还有 {len(errs) - 15} 条, 修完上面的重跑 validate 看全量)"]
+    return errs
+
+
+def _finalize_procedure(out_dir: Path, source_for_agent: str, ocr_path: Path, case_id: str) -> None:
+    """procedure 模式收尾后处理 (agent 完成且 validate 全过后, runner 确定性执行):
+
+    ① validate --fix-verbatim: 把未逐字命中的 value 自动替换为原文最相似连续片段;
+    ② procedure/tools/render.py: 零校验渲染 HTML (质量门禁已由 validate 把过, 渲染只管出图;
+       也让 batch 的「已有 HTML 即跳过」恢复工作)。
+    渲染失败只警告不改退出码 (workflow.json 已完成, 可手动重渲)。
+    """
+    env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
+    wf = out_dir / "workflow.json"
+
+    fix_cmd = [sys.executable, str(DSL_ROOT / "procedure" / "tools" / "validate.py"),
+               "--workflow", str(wf), "--source", source_for_agent, "--fix-verbatim"]
+    if ocr_path.exists():
+        fix_cmd += ["--ocr", str(ocr_path)]
+    try:
+        r = subprocess.run(fix_cmd, capture_output=True, text=True, encoding="utf-8",
+                           errors="replace", cwd=str(DSL_ROOT), timeout=120, env=env)
+        fixes = [ln for ln in (r.stdout or "").splitlines()
+                 if ln.strip().startswith("✦") or "原文连续片段" in ln]
+        if fixes:
+            print("[finalize] 逐字回填:\n" + "\n".join(fixes), flush=True)
+    except Exception as e:
+        print(f"[finalize] ⚠ fix-verbatim 跳过 ({type(e).__name__}: {e})", flush=True)
+
+    title = f"Case {case_id}"
+    try:
+        t = (json.loads(wf.read_text(encoding="utf-8")).get("source") or {}).get("title") or ""
+        if t:
+            title = f"Case {case_id} · {t[:40]}"
+    except Exception:
+        pass
+    out_html = out_dir / f"case-{case_id}.html"
+    render_cmd = [sys.executable, str(DSL_ROOT / "procedure" / "tools" / "render.py"),
+                  "--workflow", str(wf), "--source-input", source_for_agent,
+                  "--page-title", title, "--case-id", str(case_id), "--out", str(out_html)]
+    try:
+        r = subprocess.run(render_cmd, capture_output=True, text=True, encoding="utf-8",
+                           errors="replace", cwd=str(DSL_ROOT), timeout=120, env=env)
+    except Exception as e:
+        print(f"[finalize] ⚠ 渲染失败 ({type(e).__name__}: {e}); 可手动重渲", flush=True)
+        return
+    if r.returncode == 0:
+        print(f"[finalize] ✓ HTML → {out_html}", flush=True)
+    else:
+        print(f"[finalize] ⚠ 渲染失败 (workflow 已完成, 可手动重渲): "
+              f"{(r.stdout or r.stderr or '').strip()[:400]}", flush=True)
+
+
+# 常用模型别名 → OpenRouter 全名 (--model / --phase1-model / --ocr-model 都认)。
+# 不在表里的值原样透传 (写全名、qwen 原生名都照旧)。
+_MODEL_ALIASES = {
+    "flash": "google/gemini-3.5-flash",
+    "flash-3.5": "google/gemini-3.5-flash",
+    "3.5-flash": "google/gemini-3.5-flash",
+    "gemini-3.5-flash": "google/gemini-3.5-flash",
+    "flash-lite": "google/gemini-3.1-flash-lite",
+    "gemini-3.1-flash-lite": "google/gemini-3.1-flash-lite",
+}
+
+
+def _resolve_model(name: str) -> str:
+    return _MODEL_ALIASES.get((name or "").strip().lower(), name)
+
+
+def _load_env() -> None:
+    """加载仓库根 .env 到环境变量。
+
+    各 provider 的 create_*_llm_call 直接 os.getenv 读 key / base_url
+    (OPEN_ROUTER_API_KEY / QWEN_API_KEY / QWEN_BASE_URL 等), 但本脚本绕过
+    agent.client (那里才 load_dotenv), 故在此显式加载, 否则 .env 里的配置读不到。
+    override=False: 已在 shell 里 export 的值优先, 不被 .env 覆盖。
+    """
+    try:
+        from dotenv import load_dotenv
+    except ImportError:
+        return
+    env_file = REPO_ROOT / ".env"
+    if env_file.exists():
+        load_dotenv(env_file, override=False)
+
+
+def _load_sibling_module(name: str, path: Path):
+    """按文件路径 import 同目录脚本 (run_procedure_dsl.py 不是包, 用 spec 加载)。"""
+    spec = importlib.util.spec_from_file_location(name, path)
+    mod = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(mod)
+    return mod
+
+
+# 复用 run_procedure_dsl.py 的纯函数 (它 main() 有 __main__ 守卫, import 无副作用)。
+_rpd = _load_sibling_module("run_procedure_dsl", DSL_ROOT / "run_procedure_dsl.py")
+_build_initial_blocks = _rpd._build_initial_blocks
+_images_from_source = _rpd._images_from_source
+_url_to_cached_path = _rpd._url_to_cached_path
+_derive_case_id = _rpd._derive_case_id
+_resolve_out_dir = _rpd._resolve_out_dir
+_MEDIA_TYPE = _rpd._MEDIA_TYPE
+
+
+# 极简引导: 只告诉主 Agent「你是 Cyber Agent + 工具名 + 去读 README 的运行时约定节」。
+# 其余所有运行时规则都在 spec/README.md (agent 本来就先读 README), 这里不复述。
+def _cyber_runtime_note(spec_name: str) -> str:
+    return f"""
+
+⚠️ 你的执行引擎是 **Cyber Agent**(不是 Claude Code):可用工具是 `read_file` / `write_file` / `edit_file` / `bash_command` / `glob_files` / `grep_content` / `read_images`(**不是** Read/Write/Edit/Bash/Glob/Grep)。
+**第一步就 read_file `{spec_name}/README.md`**(在你 cwd `procedure-dsl/` 下),然后**严格照它的「全程约定」节操作** —— 尤其『Cyber Agent 引擎专用』那部分(`bash_command` 是 cmd.exe、`goal` 用纯数字 focus、spec 相对链接补 `{spec_name}/` 前缀、read_file 会截断长文本)。「怎么建 workflow.json / 怎么用 @quote 填 value / patch 路径怎么写」全以 README 为准, 不要自行发挥。
+"""
+
+
+def _downscale_image(raw: bytes, max_dim: int, quality: int) -> tuple:
+    """把图片下采样 + 重压缩成 JPEG, 返回 (bytes, mime)。
+
+    为什么必须做: 实测 case 的 14 张原图 base64 合计 ~12MB, 直接发会把
+    OpenRouter→Claude 的上游流打断 (api_error: internal stream ended unexpectedly);
+    减到 ~3MB 内就稳。同时大幅省 input token (PNG 截图 base64 极占 token)。
+
+    策略: 最长边 > max_dim 才缩放 (保持比例); 一律转 JPEG (PNG 截图转 JPEG 体积降一个量级);
+    有透明通道的拍平到白底 (截图场景安全)。max_dim<=0 表示关闭, 原样返回。
+    PIL 不可用或处理失败 → 原样返回 (降级不阻塞)。
+    """
+    if max_dim <= 0:
+        return raw, "image/jpeg"
+    try:
+        import io
+        from PIL import Image
+        im = Image.open(io.BytesIO(raw))
+        if im.mode in ("RGBA", "LA", "P"):
+            bg = Image.new("RGB", im.size, (255, 255, 255))
+            im = im.convert("RGBA")
+            bg.paste(im, mask=im.split()[-1])
+            im = bg
+        else:
+            im = im.convert("RGB")
+        w, h = im.size
+        if max(w, h) > max_dim:
+            scale = max_dim / max(w, h)
+            im = im.resize((max(1, int(w * scale)), max(1, int(h * scale))), Image.LANCZOS)
+        out = io.BytesIO()
+        im.save(out, format="JPEG", quality=quality, optimize=True)
+        return out.getvalue(), "image/jpeg"
+    except Exception as e:
+        print(f"[image] downscale 失败, 用原图: {type(e).__name__}: {e}", flush=True)
+        return raw, "image/png"
+
+
+def _to_openai_content(text: str, images: List[str],
+                       max_dim: int = 1280, quality: int = 85) -> List[Dict[str, Any]]:
+    """把 (text, 图URL列表) 拼成 OpenAI 格式的 content blocks (OpenRouter / 各家通吃)。
+
+    - 文本块: {"type": "text", "text": ...}
+    - 图片块: {"type": "image_url", "image_url": {"url": "data:<mime>;base64,<...>"}}
+      URL 先经 run_procedure_dsl._url_to_cached_path 客户端下载缓存 (绕图床 robots.txt)。
+      每张图经 _downscale_image 下采样+转 JPEG (max_dim<=0 关闭), 防大 payload 打断上游流。
+    单张图失败不阻塞整批。
+    """
+    blocks: List[Dict[str, Any]] = [{"type": "text", "text": text}]
+    n_ok, n_fail = 0, 0
+    bytes_before, bytes_after = 0, 0
+    for ref in images:
+        try:
+            if ref.startswith(("http://", "https://")):
+                local = _url_to_cached_path(ref)
+            else:
+                local = Path(ref).expanduser().resolve()
+                if not local.exists():
+                    raise FileNotFoundError(ref)
+            raw = local.read_bytes()
+            small, mime = _downscale_image(raw, max_dim, quality)
+            bytes_before += len(raw)
+            bytes_after += len(small)
+            data = base64.standard_b64encode(small).decode()
+            blocks.append({
+                "type": "image_url",
+                "image_url": {"url": f"data:{mime};base64,{data}"},
+            })
+            n_ok += 1
+        except Exception as e:
+            n_fail += 1
+            print(f"[image] skip {ref[:80]}... ({type(e).__name__}: {e})", flush=True)
+    if n_ok and max_dim > 0:
+        print(f"[image] 下采样: {bytes_before//1024}KB → {bytes_after//1024}KB "
+              f"(max_dim={max_dim}, q={quality})", flush=True)
+    if images:
+        print(f"[image] {n_ok}/{len(images)} 成功 base64 化, {n_fail} 失败已跳过", flush=True)
+    return blocks
+
+
+# ──── 执行前预 OCR: 每张配图 → 文本 (供 quote-source --ocr 搜) ──────────────────
+# 截图教程的 prompt / JSON / 参数常只在图里, body_text 抽不到。执行前 OCR 成文本,
+# 让 LLM 也能从图片内容里 quote 出真实 value/directive。按图字节 hash 缓存, 不重复花钱。
+
+def _ocr_one(raw: bytes, model: str, api_key: str,
+             max_dim: int = 2000, quality: int = 90) -> str:
+    """单张图 → OCR 文本 (OpenRouter 视觉调用)。失败抛异常由上层兜。"""
+    small, mime = _downscale_image(raw, max_dim, quality)
+    data = base64.standard_b64encode(small).decode()
+    instr = ("请把这张图片里的所有文字逐字提取出来, 按从上到下、从左到右的阅读顺序输出。"
+             "只输出图中文字本身, 不要翻译、不要解释、不要添加任何说明。"
+             "图中若有代码/JSON/提示词, 请保留其原始换行与格式。若图中无文字, 输出空。")
+    payload = {
+        "model": model,
+        "messages": [{"role": "user", "content": [
+            {"type": "text", "text": instr},
+            {"type": "image_url", "image_url": {"url": f"data:{mime};base64,{data}"}},
+        ]}],
+    }
+    r = httpx.post("https://openrouter.ai/api/v1/chat/completions",
+                   headers={"Authorization": f"Bearer {api_key}"}, json=payload, timeout=120)
+    r.raise_for_status()
+    j = r.json()
+    return (j.get("choices") or [{}])[0].get("message", {}).get("content", "") or ""
+
+
+def _ocr_images(refs: List[str], model: str, api_key: str, cache_dir: Path) -> str:
+    """对每张图 OCR, 合并成带分段标记的文本。按图字节 hash 缓存, 单张失败跳过不阻塞。"""
+    import hashlib
+    cache_dir.mkdir(exist_ok=True)
+    out, n_ok = [], 0
+    for n, ref in enumerate(refs, 1):
+        try:
+            if ref.startswith(("http://", "https://")):
+                local = _url_to_cached_path(ref)
+            else:
+                local = Path(ref).expanduser().resolve()
+            raw = local.read_bytes()
+            h = hashlib.sha256(raw).hexdigest()[:24]
+            cf = cache_dir / f"{h}.txt"
+            if cf.exists():
+                txt, tag = cf.read_text(encoding="utf-8"), " (cache)"
+            else:
+                txt, tag = _ocr_one(raw, model, api_key), ""
+                cf.write_text(txt, encoding="utf-8")
+            out.append(f"\n===== [图 {n}] 来源: {ref[:90]} =====\n{txt.strip()}\n")
+            n_ok += 1
+            print(f"[ocr] 图 {n}/{len(refs)}: {len(txt.strip())} 字{tag}", flush=True)
+        except Exception as e:
+            print(f"[ocr] 图 {n}/{len(refs)} 失败跳过: {type(e).__name__}: {e}", flush=True)
+    print(f"[ocr] {n_ok}/{len(refs)} 张成功", flush=True)
+    return "".join(out)
+
+
+def _trace_append(trace_path: Path, chunk: str) -> None:
+    with trace_path.open("a", encoding="utf-8") as f:
+        f.write(chunk)
+
+
+def _content_to_text(content: Any) -> str:
+    """把 Message.content 归一成纯文本。
+
+    不同 provider 的 content 形态不一:
+      - str: 直接用 (OpenRouter / 多数情况)。
+      - list[block]: OpenAI/Qwen 多模态格式 [{"type":"text","text":...}, ...],
+        抽出各块的 text 字段拼起来。
+      - dict: 单个 block, 取其 text / content 字段, 取不到就 str() 兜底。
+    切片 (content[:2000]) 前必须先过这里, 否则对 dict/list 切片会抛 KeyError/TypeError。
+    """
+    if isinstance(content, str):
+        return content
+    if isinstance(content, list):
+        parts = []
+        for b in content:
+            if isinstance(b, str):
+                parts.append(b)
+            elif isinstance(b, dict):
+                parts.append(b.get("text") or b.get("content") or "")
+        return "".join(parts)
+    if isinstance(content, dict):
+        # Qwen/DeepSeek assistant: text 可能为空, 真正的话在 reasoning_content。
+        # tool 结果消息: 内容在 "result" 键 (之前漏读它, 导致 [tool result] 控制台全空白)。
+        # 都取不到就返回 "" (不要 str(content) 把整个 dict 当文本 dump 出来)。
+        return (content.get("text") or content.get("reasoning_content")
+                or content.get("result") or content.get("content") or "")
+    return str(content)
+
+
+def _build_fresh_prompt(args, *, source_for_agent: str, out_dir: Path, ocr_path: Path,
+                        images: List[str], workdir: Path, spec_name: str,
+                        body: str) -> str:
+    """拼 fresh run 的起手 prompt。
+
+    组成: 原脚本起手全文 (_build_initial_blocks 的 text 块) + Cyber 运行时注 + OCR 提示 +
+    完整正文内联 + 钉死路径的 plan/verify-io/lint 命令 + 模式附注 (--exp / --phase1-model)。
+    原则: **命令钉死精确路径** (弱模型用错文件名会让校验静默跳过), **规则细节不复述**
+    (canonical 在 spec/README.md, agent 起手就读它)。
+    """
+    anth_blocks = _build_initial_blocks(
+        source_for_agent, args.case_id, args.out_dir, images, workdir, spec_name)
+    text = anth_blocks[0]["text"] + _cyber_runtime_note(spec_name)
+
+    if ocr_path.exists():
+        text += (
+            f"\n\n## 🖼️ 配图已 OCR 成文本\n"
+            f"原文配图的文字已 OCR 提取到 `{ocr_path.as_posix()}`。"
+            f"填 value/directive 需要图里的文字时, 用 "
+            f"`python {spec_name}/tools/quote-source.py --source {source_for_agent} --query \"<短语>\" --ocr {ocr_path.as_posix()}` "
+            f"一并搜原文+图片 (quote-source 读全文件, 不受 read_file 截断影响; 别用 read_file 通读大 ocr.txt)。"
+        )
+    # 内联完整正文: read_file 会把 body_text 这种超长单行砍在 2000 字 (弱模型常不续 char_offset
+    # → 正文后半段静默丢失)。把完整 body_text 直接附进 prompt, agent 理解正文以这份为准。
+    if body:
+        text += (
+            f"\n\n## 📄 原文正文 (完整版, 已内联 — 别再 read_file 原文取正文)\n"
+            f"⚠️ read_file 读 `{source_for_agent}` 会把 body_text 这一长行砍在 2000 字 → 丢后半段。"
+            f"理解正文、提取 value/directive **以下面这份完整正文为准**; read_file 原文文件只为取 "
+            f"title/link/publish_timestamp 等短字段。\n\n```\n{body}\n```"
+        )
+
+    _lint_ocr = f" --ocr {ocr_path.as_posix()}" if ocr_path.exists() else ""
+    # 命令钉死精确路径; 怎么填/怎么修的规则看 README 对应节, 不在这复述。
+    text += (
+        f"\n\n## 🧭 第一步(必做): 调用 plan_procedures 工具做计划\n"
+        f"动手建 workflow.json 前**先调用一次 `plan_procedures`** 交工序计划 (结构见工具描述): "
+        f"工序拆分 + 每步「工具·输入·动作·输出」四要素 + 章节认领 (source_sections)。"
+        f"通过后骨架自动生成, 之后只用 wf-patch 在骨架上填值 (批量用 `--patch _scratch/xxx.json --prune`, "
+        f"剩余条目带 _error 原因, 改完重跑同一文件直到 `[]`), **不要 write_file 重写 workflow.json**。\n\n"
+        f"Phase 2.0 填完 value/directive/anchor 后**必须跑 IO 校验**(照抄), 通过才进 2.1 归类:\n"
+        f"```bash\npython {spec_name}/tools/verify-io.py --workflow {out_dir.as_posix()}/workflow.json "
+        f"--source {source_for_agent}{_lint_ocr}\n```\n\n"
+        f"Phase 3 lint(照抄, `--source` 必带, 否则章节覆盖/value 逐字两条强制静默跳过):\n"
+        f"```bash\npython {spec_name}/tools/lint-case.py --workflow {out_dir.as_posix()}/workflow.json "
+        f"--case-id {args.case_id} --source {source_for_agent}{_lint_ocr}\n```\n"
+        f"报「章节疑似漏抽」回 Phase 1 补工序; 报「value 疑似缩写」回 Phase 2.0 用 `@quote` 重填。"
+    )
+
+    if args.mode == "exp-direct":
+        text += _EXP_DIRECT_NOTE                  # 方案1: 不写 understanding, 直接 workflow.json
+    elif args.mode == "exp-understanding":
+        text += _EXP_UNDERSTANDING_ONLY_NOTE      # 方案2 第一步: 只产 understanding
+    elif args.mode == "exp-workflow":
+        text += _EXP_WORKFLOW_FROM_UNDERSTANDING_NOTE  # 方案2 第二步: 据 understanding 产 workflow
+    elif args.mode == "phase1":
+        text += _PHASE1_STOP_NOTE                 # 两段式 Pass 1: 做完整 Phase 1 即停
+    return text
+
+
+def _build_procedure_prompt(args, *, source_for_agent: str, out_dir: Path, ocr_path: Path,
+                            images: List[str], body: str) -> str:
+    """拼 --skill procedure 的 fresh 起手 prompt (强模型直写 workflow.json, 单校验工具)。
+
+    原则与 dsl 版一致: 命令钉死精确路径, 规则细节不复述 (canonical 在 procedure/SKILL.md)。
+    """
+    case_dir = out_dir.as_posix()
+    _ocr = f" --ocr {ocr_path.as_posix()}" if ocr_path.exists() else ""
+    text = (
+        f"请按 `procedure/` 目录里的 SKILL 处理这个 post: 提取工序, **直接写出完整的 workflow.json**。\n\n"
+        f"⚠️ 你的执行引擎是 **Cyber Agent**: 可用工具是 `read_file` / `write_file` / `edit_file` / "
+        f"`bash_command` / `glob_files` / `grep_content`(SKILL.md 里写的 Read/Write/Edit/Bash 对应它们)。"
+        f"`bash_command` 是 cmd.exe: 一条命令一次调用, 别用 `;` 串(要串用 `&&`)。"
+        f"cwd 是 `procedure-dsl/`。read_file 读长文件会截断, 续读用 char_offset。\n\n"
+        f"## 起手指令 (路径直接照搬, 不要改, 不要先探查)\n\n"
+        f"1. read_file `procedure/SKILL.md` — 全部规则(结构、字段规范、词表、value 逐字要求)都在"
+        f"这一个文件里, 读完不要重读, 也不要读 spec/ 下任何东西(那是另一套旧流程)。\n"
+        f"2. 通读下方内联正文 + 本消息所附的 {len(images)} 张配图, 想清楚工序划分"
+        f"(在文字回复里简述: 有几个独立工序、每工序的步骤序列), 然后**一次 write_file 写出完整的** "
+        f"`{case_dir}/workflow.json`(所有字段一趟填全)。\n"
+        f"3. 跑校验(照抄):\n"
+        f"```bash\npython procedure/tools/validate.py --workflow {case_dir}/workflow.json "
+        f"--source {source_for_agent}{_ocr}\n```\n"
+        f"4. 报 ✗ 的用 edit_file 直接修 workflow.json 对应字段, 重跑校验直到 **0 错误**; "
+        f"⚠ 警告逐条核对, 确认无误可保留。0 错误后一句话总结即停。\n\n"
+        f"## 输入\n\n"
+        f"- case 原文: `{source_for_agent}` (read_file 它只为取 title/link/publish_timestamp 等短字段; "
+        f"正文以下方内联版为准)\n"
+        f"- 配图: 本消息附了 {len(images)} 张图作多模态内容\n\n"
+        f"## 输出\n\n"
+        f"`{case_dir}/workflow.json` 是唯一产物(本 skill 不渲染 HTML, 不写 understanding.md)。"
+        f"过程草稿(若需要)放 `{case_dir}/_scratch/`。"
+    )
+    if ocr_path.exists():
+        text += (
+            f"\n\n## 🖼️ 配图已 OCR 成文本\n"
+            f"原文配图的文字已 OCR 提取到 `{ocr_path.as_posix()}`。prompt/JSON/参数常只在截图里——"
+            f"填 value 需要图里文字的逐字内容时, 从这个文件取(read_file 截断就用 char_offset 续读, "
+            f"或 bash_command 用 findstr 定位)。"
+        )
+    if body:
+        text += (
+            f"\n\n## 📄 原文正文 (完整版, 已内联 — 别再 read_file 原文取正文)\n"
+            f"⚠️ read_file 读 `{source_for_agent}` 会把 body_text 这一长行砍在 2000 字 → 丢后半段。"
+            f"理解正文、提取 value **以下面这份完整正文为准**。\n\n```\n{body}\n```"
+        )
+    return text
+
+
+# 两段式 (--phase1-model): Pass 1 只做 Phase 1, 然后换模型 resume 做 Phase 2+。
+_PHASE1_STOP_NOTE = """
+
+## ⏸️ 本段任务: 先完成 Phase 1, 然后**暂停等待下一步指示**
+
+这是一个**分阶段协作**的任务, 你负责的是**第一阶段**。本段请专注做完 Phase 1:
+  - Phase 1.1 心智模型 → 写 understanding.md
+  - Phase 1.2 workflow.json 骨架 (procedures/steps/IO 结构 + name/purpose/declarations)
+  - Phase 1.3 anchor 闭合 (IO 引用)
+
+完成 Phase 1.3 后, 请**暂停**: 用一句话报告产出, **本轮不再发任何工具调用**, 等待后续指示来推进 Phase 2/3。
+(注意: 这**不是禁止** Phase 2, 只是分工上**这一段先到 Phase 1 为止**; 后续会有新指示让你或另一协作者继续。)
+你的 Phase 1 产出质量直接决定后续阶段, 所以 understanding.md 和 workflow.json 骨架务必扎实、完整。
+"""
+
+
+# ── 实验模式 note (--exp) ──────────────────────────────────────────────────
+# 实验只比 Phase 1 骨架质量, 两方案都"产出 workflow.json 骨架+anchor 后停", 不跑 Phase 2/3。
+
+# 方案 1 (direct): 强模型不写 understanding.md, 边想边直接出 workflow.json。
+_EXP_DIRECT_NOTE = """
+
+## 🧪 实验模式 (direct): 不写 understanding.md, 直接产 workflow.json
+
+本次**跳过 Phase 1.1 的 understanding.md 文件** (spec 里提到的这一步本次作废, 不要 Write 它)。
+把"有几个独立工序、每个工序的步骤/IO/控制流"的分析**直接写在你的文字回复里**(简明扼要), 然后:
+- 直接 Write `workflow.json` 骨架 (Phase 1.2: procedures/steps/IO 结构 + name/purpose/declarations);
+- 用 wf-patch.py 加 anchor (Phase 1.3: IO 闭合)。
+完成 anchor 闭合后**立即停止**, 一句话总结即可, **不要进入 Phase 2** (不填 effect/action/type/substance/form, 不分发子 Agent)。
+"""
+
+# 方案 2 第一步 (split-A): 强模型只产 understanding.md, 不碰 workflow.json。精简读单。
+_EXP_UNDERSTANDING_ONLY_NOTE = """
+
+## 🧪 实验模式 (split · 第一步): 只产 understanding.md
+
+本次**只做 Phase 1.1**: 通读原文(含图)建立心智模型, 写进 understanding.md, 然后**立即停止**
+(**不要 Write workflow.json**, 不进 Phase 1.2+, **本轮不再发任何工具调用**)。
+
+### ⚡ 精简读单 (覆盖上面起手指令里的完整清单 — 以本节为准)
+本步**只读**这几样, 其余一律不读 (读了纯烧 context):
+  - `spec/README.md` (已在起手读过, 别重读 —— 三阶段规则 + 多工序判断标准 + DSL 概念全在这一个文件里)
+  - 原文 case json (body_text + 元数据) + 本消息所附的图
+**明确不要读** (本步用不上): `spec/tools.md` (脚本接口, 本步不调任何脚本)、`spec/format/` 下的 schema。
+
+### understanding.md 要写到"能让另一个模型照着填出 workflow.json"的程度
+- 有几个独立工序 (按 README『判断有几个工序』的标准), 每个: 工序名 + 终态产物 + 大致步骤数 + 工艺类型;
+- 每个工序的步骤序列, 每步的输入/输出 (是什么数据、从哪来、到哪去);
+- **控制流用大白话讲清** (哪步是循环/并行/分支、循环什么、并行几路) —— 不必纠结 block/nested 的 JSON 细节
+  (README『有循环/并行怎么切』有), 文字描述即可, 下游模型据此建 block/nested。
+后续由另一个模型读你的 understanding.md + JSON schema 生成 workflow.json。
+"""
+
+# 方案 2 第二步 (split-B): 全新一段、不给图, 弱模型只凭 understanding.md + schema 产 workflow.json。
+_EXP_WORKFLOW_FROM_UNDERSTANDING_NOTE = """
+
+## 🧪 实验模式 (split · 第二步): 据 understanding.md 产 workflow.json (本次不附原图)
+
+Phase 1.1 的心智模型已由**另一个(更强的)模型**写好 —— 就是上面"输出目录"里的 **understanding.md**。
+本次你的任务是 **Phase 1.2 + 1.3**, 且**只依据 understanding.md + schema**(本消息不附原图, 你看不到截图):
+  1. read_file 输出目录里的 `understanding.md`, 以及 spec 的 `format/case-data.schema.json`;
+  2. 按 understanding.md 的工序划分, Write `workflow.json` 骨架 (procedures/steps/IO 结构 + name/purpose/declarations);
+  3. 用 bash_command 跑 wf-patch.py 加 anchor (IO 闭合, 单条命令不要拼 `;`)。
+完成 anchor 后**立即停止**, **不要进入 Phase 2**, 也**不要重写 understanding.md**。
+"""
+
+
+async def run(args: argparse.Namespace) -> int:
+    from agent.core.runner import AgentRunner, RunConfig, KnowledgeConfig
+    from agent.trace import FileSystemTraceStore, Trace, Message
+    from agent.llm import create_openrouter_llm_call, create_qwen_llm_call
+
+    # provider 选择: 决定 llm_call 走哪家端点。
+    #   openrouter → OPEN_ROUTER_API_KEY, 一个 URL 通打各家 (model 形如 qwen/qwen-max)。
+    #   qwen       → QWEN_API_KEY + QWEN_BASE_URL (.env), 阿里 dashscope 原生
+    #                (model 形如 qwen-plus / qwen-max, 无 "qwen/" 前缀)。
+    if args.provider == "qwen":
+        make_llm_call = lambda: create_qwen_llm_call(model=args.model)
+    else:
+        make_llm_call = lambda: create_openrouter_llm_call(model=args.model)
+
+    workdir = DSL_ROOT
+    source_path = Path(args.source).expanduser().resolve()
+    if not source_path.exists():
+        print(f"❌ source not found: {source_path}", file=sys.stderr)
+        return 1
+
+    out_dir = _resolve_out_dir(args.out_dir, workdir)
+    out_dir.mkdir(parents=True, exist_ok=True)
+    (out_dir / "_scratch").mkdir(exist_ok=True)
+    trace_id_file = out_dir / ".trace_id"
+    trace_path = out_dir / "_trace_cyber.md"
+
+    # skill 目录; 不存在直接报错, 别让 agent 跑一半才发现。
+    #   --skill procedure → procedure/ (强模型直写版); 否则 spec/ (--spec-version 实验变体)。
+    if args.mode == "procedure":
+        spec_name = "procedure"
+    else:
+        spec_name = "spec" if not getattr(args, "spec_version", None) else f"spec-{args.spec_version}"
+    if not (DSL_ROOT / spec_name).is_dir():
+        print(f"❌ skill 目录不存在: {DSL_ROOT / spec_name}", file=sys.stderr)
+        return 1
+
+    # source 路径给 Agent (workdir 相对优先)。
+    try:
+        source_for_agent = source_path.relative_to(workdir).as_posix()
+    except ValueError:
+        source_for_agent = str(source_path)
+
+    # resume: 读已存 trace_id, 只发增量 "接着做" 消息。
+    resume_tid = None
+    if args.resume:
+        if not trace_id_file.exists():
+            print(f"❌ --resume 但无 {trace_id_file}; 先正常跑一次", file=sys.stderr)
+            return 1
+        resume_tid = trace_id_file.read_text(encoding="utf-8").strip() or None
+
+    images = _images_from_source(source_path) + (args.extra_image or [])
+
+    # 执行前预 OCR: 把每张配图的文字提取成文本, 落 _scratch/ocr.txt, 供 quote-source --ocr 搜。
+    # 只在 fresh run 做 (resume 时上次的 ocr.txt 还在); 按图字节 hash 缓存, 重跑不重复花钱。
+    ocr_path = out_dir / "_scratch" / "ocr.txt"
+    if not resume_tid and not getattr(args, "no_ocr", False) and images:
+        api_key = os.getenv("OPEN_ROUTER_API_KEY")
+        if not api_key:
+            print("[ocr] 跳过: 未设 OPEN_ROUTER_API_KEY", flush=True)
+        else:
+            print(f"[ocr] 对 {len(images)} 张配图预 OCR (model={args.ocr_model}) ...", flush=True)
+            ocr_text = _ocr_images(images, args.ocr_model, api_key, DSL_ROOT / ".ocr_cache")
+            if ocr_text.strip():
+                ocr_path.write_text(ocr_text, encoding="utf-8")
+                print(f"[ocr] -> {ocr_path} (共 {len(ocr_text)} 字)", flush=True)
+
+    if resume_tid and args.mode == "phase2-handoff":
+        # 两段式 Pass 2: Phase 1 已由另一模型做完, 从 Phase 2 开始。
+        # ⚠️ 必须强硬作废历史里 Pass1 的"只做 Phase1 就停"指令, 否则弱模型会跟着旧指令
+        #    重做 Phase1 再停 (实测 gemini-flash-lite 就这么干了)。
+        cd = out_dir.as_posix()
+        msgs = [{"role": "user", "content": (
+            f"【阶段交接 — 之前的指令已变更, 请严格按本条执行】\n\n"
+            f"Phase 1 (workflow.json 骨架 + anchor 闭合) **已经全部完成并落盘**, 是上一个模型做的。\n\n"
+            f"⚠️ 历史里那条『本次只做 Phase 1、做完即停、不要进 Phase 2』的指令**现已作废**。"
+            f"你现在的唯一任务是完成 **Phase 2 和 Phase 3**。\n\n"
+            f"❌ **绝对不要**重写 / 重新生成 workflow.json 的骨架 —— 它已经做好了, 重做即错误。\n"
+            f"✅ 现在立刻执行 (用 bash_command, 单条命令不要拼 `;`):\n"
+            f"  1. read_file `{cd}/workflow.json` 看当前骨架 (不要凭记忆, 也不要重写它)。\n"
+            f"  2. 读 {spec_name}/README.md 的『第二阶段』章节, 由你**自己一趟做完 Phase 2** "
+            f"(规则全以它为准)。**不要**切任务 / 分发子 Agent。\n"
+            f"  3. 用 wf-patch.py (bash_command, --set 或 `--patch _scratch/xxx.json --prune`) 回填 "
+            f"effect/action/type/substance/form/intent 到 workflow.json。\n"
+            f"  4. Phase 3: 跑 lint-case.py 校验, 再 render-case.py 出 HTML (.html 是唯一产物, .md 已取消)。"
+        )}]
+    elif resume_tid and args.mode == "procedure":
+        _ocr = f" --ocr {ocr_path.as_posix()}" if ocr_path.exists() else ""
+        msgs = [{"role": "user", "content": (
+            f"上次中断了, 接续做 case-{args.case_id} 的工序提取。\n"
+            f"先 read_file **当前磁盘版本**的 {out_dir.as_posix()}/workflow.json (不要凭记忆), 再跑\n"
+            f"`python procedure/tools/validate.py --workflow {out_dir.as_posix()}/workflow.json "
+            f"--source {source_for_agent}{_ocr}`\n"
+            f"看还差什么, 用 edit_file 修到 0 错误 (规则见 procedure/SKILL.md)。"
+        )}]
+    elif resume_tid:
+        msgs = [{"role": "user", "content": (
+            f"上次中断了, 接续做 case-{args.case_id} 的提取流程。\n"
+            f"先用 bash_command `ls` 看 {out_dir.as_posix()}/ 当前已落盘哪些产物, "
+            f"再 read_file **当前磁盘版本**的 workflow.json (计划留档在 _scratch/understanding.json) "
+            f"接着跑, 不要凭记忆。Phase 2 由你自己一趟做完 (wf-patch.py 落盘, 不分发子 Agent)。"
+        )}]
+    elif args.mode == "procedure":
+        # procedure skill: 不注册 plan 上下文 (没有 plan_procedures 这一步), 起手 prompt 自包含。
+        try:
+            _sd = json.loads(source_path.read_text(encoding="utf-8"))
+        except Exception:
+            _sd = None
+        _body = (_sd or {}).get("body_text") or "" if isinstance(_sd, dict) else ""
+        base_text = _build_procedure_prompt(
+            args, source_for_agent=source_for_agent, out_dir=out_dir, ocr_path=ocr_path,
+            images=images, body=_body)
+        msgs = [{"role": "user", "content": _to_openai_content(
+            base_text, images, max_dim=args.max_image_dim, quality=args.image_quality)}]
+    else:
+        # 原文 json: 正文给 prompt 内联 + 喂给 plan/IO 校验工具当上下文。
+        try:
+            _sd = json.loads(source_path.read_text(encoding="utf-8"))
+        except Exception:
+            _sd = None
+        _sd2 = _sd if isinstance(_sd, dict) else {}
+        _body = _sd2.get("body_text") or ""
+        plan_tool.set_plan_context(
+            body_text=_body,
+            ocr=ocr_path.read_text(encoding="utf-8") if ocr_path.exists() else "",
+            out_dir=out_dir,
+            case_id=args.case_id,
+            spec_name=spec_name,
+            source={
+                "platform": "",                                   # LLM/后续可补
+                "author": _sd2.get("channel_account_name", ""),
+                "url": _sd2.get("link", ""),
+                "title": _sd2.get("title", ""),
+                "date": str(_sd2.get("publish_timestamp", "") or ""),
+                "excerpt": _body[:120],
+            },
+        )
+        base_text = _build_fresh_prompt(
+            args, source_for_agent=source_for_agent, out_dir=out_dir, ocr_path=ocr_path,
+            images=images, workdir=workdir, spec_name=spec_name, body=_body)
+        # exp-workflow: 不给图, 纯凭 understanding.md + schema
+        imgs_for_prompt = [] if args.mode == "exp-workflow" else images
+        msgs = [{"role": "user", "content": _to_openai_content(
+            base_text, imgs_for_prompt, max_dim=args.max_image_dim, quality=args.image_quality)}]
+
+    cfg = RunConfig(
+        model=args.model,
+        temperature=0.3,
+        max_iterations=args.max_turns,
+        agent_type="main",
+        name=f"procedure-dsl case-{args.case_id} (cyber)",
+        tool_groups=["core", "system"],  # core=read/write/edit/glob/grep (agent 工具下面 exclude 掉);
+                                         # system=bash_command
+                                         # ⚠️ 没 system 组 → 主 Agent 无 bash, 跑不了 spec/tools/*.py
+                                         # (wf-patch / lint-case / render-case 全靠 bash)
+        parallel_tool_execution=True,   # 允许同轮并行工具调用 (如多个 read_file); 子 Agent 分发已废弃
+        context_injection_interval=0,   # 关掉周期性自动注入 get_current_context: procedure-dsl 单 Agent
+                                        # 不用 goal/协作者/IM, 那些注入只是给弱模型添乱 + 烧 token
+
+        enable_prompt_caching=False,    # 非 Claude 模型无效, 关掉省得干扰
+        # 关掉 goal 压缩: 它会在 goal 完成后把详细消息压成 [[SUMMARY]], 而弱模型 (如
+        # gemini-flash-lite) 一丢细节就倾向"推倒重做 Phase 1", 覆盖掉已完成的 Phase 2
+        # 归一化数据。单 case 运行上下文有限, 保留全量更安全。
+        goal_compression="none",
+        # 关掉知识沉淀: 否则任务结束会被自动注入"复盘→knowledge_save_pending"prompt
+        # (上次 Claude 在 seq6 被它带跑偏、qwen 浪费 turn51-52)。procedure-dsl 不需要它。
+        knowledge=KnowledgeConfig(
+            enable_extraction=False,            # 压缩时不反思
+            enable_completion_extraction=False, # 结束后不复盘 (核心: 去掉那段收尾 prompt)
+            enable_injection=False,             # focus goal 时不注入知识
+        ),
+        # 去知识沉淀 + 子 Agent 分发工具 (agent/evaluate): 单 Agent 全程;
+        # procedure 模式再去 plan_procedures (那是 dsl 三阶段的 Phase 1 工具, 此模式直写 workflow.json)
+        exclude_tools=["knowledge_save_pending", "agent", "evaluate"]
+                      + (["plan_procedures"] if args.mode == "procedure" else []),
+        trace_id=resume_tid,
+    )
+
+    print(f"[setup] engine     = Cyber AgentRunner")
+    print(f"[setup] skill      = {spec_name}/")
+    print(f"[setup] provider   = {args.provider}")
+    print(f"[setup] model      = {args.model}")
+    print(f"[setup] source     = {source_path}")
+    print(f"[setup] case_id    = {args.case_id}")
+    print(f"[setup] out_dir    = {out_dir}")
+    print(f"[setup] images     = {len(images)}")
+    print(f"[setup] max_iter   = {args.max_turns}")
+    print(f"[setup] resume     = {resume_tid[:8] + '...' if resume_tid else 'no'}")
+    print(flush=True)
+
+    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+    _trace_append(trace_path, f"\n\n---\n\n## ▶ {'Resume' if resume_tid else 'Fresh'} @ {now}\n"
+                              f"- model: `{args.model}` · case: `{args.case_id}` · images: `{len(images)}`\n")
+
+    # ⚠️ trace store 必须放**短路径**(仓库根 .trace), 不能放 out_dir/.trace。
+    # 原因 (Windows MAX_PATH=260): 子 Agent 的 trace_id 是 <父UUID>@delegate-<时间戳>-NNN,
+    # 消息文件名还把整个 id 重复一次。若 base 是深层的 outputs/<case>/.trace,
+    # 子 agent 消息文件路径会到 ~285 字符 > 260, 落盘报 [Errno 2] 子 Agent 直接失败。
+    # 放仓库根 .trace 后同样路径 ~204 < 260。各 case 的 trace 按 trace_id 区分, 不冲突。
+    trace_store_base = REPO_ROOT / ".trace"
+    runner = AgentRunner(
+        llm_call=make_llm_call(),
+        trace_store=FileSystemTraceStore(base_path=str(trace_store_base)),
+        debug=True,   # subagent.py 据此打印子 Agent (phase-2a/2b) 的实时执行过程,
+                      # 否则子 Agent 全程静默, 只有最后 delegate 汇总可见。
+    )
+
+    turn = 0
+    t0 = time.time()
+    status = "unknown"
+    # token / 成本累计 (主 trace; 子 Agent 的 token 在各自子 trace, 不计入此处)。
+    usage = {"in": 0, "out": 0, "cache_w": 0, "cache_r": 0, "cost": 0.0}
+
+    # 完成度兜底: 一轮跑完若 workflow 没填全/没出 HTML(弱模型常吐空消息提前自停),
+    # 带「还差哪些」的具体清单**续同一条 trace** 再跑, 直到完成或达上限。
+    # 实验/两段式 Pass1 (phase1 / exp-*) 是故意中途停的, 不兜底。
+    max_auto = (getattr(args, "max_auto_continue", 2)
+                if args.mode in ("full", "phase2-handoff", "procedure") else 0)
+    run_msgs = msgs
+    cur_trace = resume_tid
+    attempt = 0
+    read_phase: set = set()    # agent 读过哪些阶段规格文件 (监听 read_file 累计)
+    phase_files = _PROCEDURE_PHASE_FILES if args.mode == "procedure" else _PHASE_FILES
+    try:
+        while True:
+            async for item in runner.run(messages=run_msgs, config=cfg):
+                if isinstance(item, Trace):
+                    status = item.status
+                    if item.trace_id:
+                        cur_trace = item.trace_id
+                        trace_id_file.write_text(item.trace_id, encoding="utf-8")
+                    print(f"[trace] {item.trace_id} status={item.status}", flush=True)
+                elif isinstance(item, Message):
+                    role = getattr(item, "role", "?")
+                    raw_content = getattr(item, "content", "") or ""
+                    tool_calls = getattr(item, "tool_calls", None)
+                    # Qwen 原生: 整条消息塞在 content dict 里, tool_calls 也嵌在其中,
+                    # item.tool_calls 属性反而是空 —— 从 content 兜底捞出来。
+                    if not tool_calls and isinstance(raw_content, dict):
+                        tool_calls = raw_content.get("tool_calls")
+                    content = _content_to_text(raw_content)
+                    # 累计 token/成本 (token 字段挂在 assistant 消息上; tool 消息为 None → or 0)
+                    usage["in"]      += getattr(item, "prompt_tokens", 0) or 0
+                    usage["out"]     += getattr(item, "completion_tokens", 0) or 0
+                    usage["cache_w"] += getattr(item, "cache_creation_tokens", 0) or 0
+                    usage["cache_r"] += getattr(item, "cache_read_tokens", 0) or 0
+                    usage["cost"]    += getattr(item, "cost", 0.0) or 0.0
+                    if role == "assistant":
+                        turn += 1
+                        if content:
+                            print(f"\n[turn {turn} · text]\n{content}\n", flush=True)
+                            _trace_append(trace_path, f"\n### Turn {turn}\n> {content[:2000]}\n")
+                        for tc in (tool_calls or []):
+                            fn = (tc.get("function") or {}) if isinstance(tc, dict) else {}
+                            nm = fn.get("name", tc.get("name", "?") if isinstance(tc, dict) else "?")
+                            args_full = str(fn.get("arguments", ""))
+                            ar = args_full[:200]
+                            print(f"[turn {turn} · tool] {nm}({ar})", flush=True)
+                            _trace_append(trace_path, f"- `{nm}` — `{ar}`\n")
+                            # 监听阶段文件读取 (read_file 的 file_path 里命中阶段文件名)
+                            if nm == "read_file":
+                                for _key, _ph in phase_files.items():
+                                    if _key in args_full:
+                                        read_phase.add(_ph)
+                    elif role == "tool":
+                        preview = str(content)[:300]
+                        print(f"  ↳ [tool result] {preview}", flush=True)
+
+            # 一轮跑完 → 查完成度 (阶段文件没读的排最前: 先读规则再修输出)
+            if args.mode == "procedure":
+                gaps = (_phase_read_gaps_procedure(out_dir, read_phase)
+                        + _completion_gaps_procedure(out_dir, source_for_agent, ocr_path))
+            else:
+                gaps = _phase_read_gaps(out_dir, read_phase) + _completion_gaps(out_dir, spec_name)
+            if not gaps:
+                break
+            if attempt >= max_auto:
+                if max_auto > 0:
+                    print(f"\n⚠️ 达自动续跑上限({max_auto})仍未完成: {'; '.join(gaps)}", flush=True)
+                    _trace_append(trace_path, f"\n### ⚠ 达续跑上限仍未完成: {'; '.join(gaps)}\n")
+                break
+            attempt += 1
+            if args.mode == "procedure":
+                nudge = (
+                    "⚠️ 任务还没做完, 别停。validate 还在报错:\n"
+                    + "\n".join(f"  - {g}" for g in gaps)
+                    + "\n零星错误用 edit_file 修 workflow.json 对应字段; 同类错误一大批用 "
+                    "bash_command 跑 procedure/tools/wf-patch.py 批量修(--set 或 --patch 清单 --prune, "
+                    "用法见 SKILL.md「批量修错」节)。修完重跑上面那条 validate 命令, "
+                    "**0 错误才算完**。别重写整个文件。"
+                )
+            else:
+                nudge = (
+                    "⚠️ 任务还没做完, 别停。当前还差(**按顺序处理**):\n"
+                    + "\n".join(f"  - {g}" for g in gaps)
+                    + "\n**先 read_file 上面点名没读过的阶段规格文件**(里面写了格式/词表/检查规则), "
+                    "再据规则修后面的问题, **别重做已完成的部分**。提示: 缺 effect/action 用 "
+                    f"wf-patch.py --set 补(值必须命中 {spec_name}/taxonomy 词表; 写错时 wf-patch 整批拒绝并在"
+                    "报错末尾给出合法值清单, 照清单改了重跑); intent 写成带标记的句子(规则见 README「目的列」); "
+                    "没出 HTML 就跑 render-case.py。"
+                )
+            print(f"\n[auto-continue {attempt}/{max_auto}] 续跑补完: {'; '.join(gaps)}\n", flush=True)
+            _trace_append(trace_path, f"\n### ↻ auto-continue {attempt}: {'; '.join(gaps)}\n")
+            cfg.trace_id = cur_trace                       # 续同一条 trace (不重开)
+            run_msgs = [{"role": "user", "content": nudge}]
+
+        # procedure 模式收尾: validate 全过 → 自动逐字回填 + 渲染 HTML (runner 确定性后处理)
+        if args.mode == "procedure" and not gaps:
+            _finalize_procedure(out_dir, source_for_agent, ocr_path, args.case_id)
+            _trace_append(trace_path, "\n### ⚙ finalize: fix-verbatim + render HTML\n")
+    except KeyboardInterrupt:
+        print(f"\n⚠️ 中断. {out_dir}/ 产物已保留. 续跑: --resume", file=sys.stderr)
+        return 130
+    except Exception as e:
+        logging.exception("cyber run failed")
+        print(f"❌ {type(e).__name__}: {e}", file=sys.stderr)
+        return 1
+
+    elapsed = time.time() - t0
+    print(f"\n[done] status={status} turns={turn} wall={elapsed:.1f}s", flush=True)
+    print(f"[usage] tokens in={usage['in']:,} out={usage['out']:,} "
+          f"cache_w={usage['cache_w']:,} cache_r={usage['cache_r']:,} · cost=${usage['cost']:.4f} "
+          f"(model={args.model}; 不含子 Agent)", flush=True)
+    _trace_append(
+        trace_path,
+        f"\n### ◀ done · status={status} · turns={turn} · {elapsed:.1f}s\n"
+        f"- tokens: in={usage['in']:,} out={usage['out']:,} "
+        f"cache_w={usage['cache_w']:,} cache_r={usage['cache_r']:,} · cost=${usage['cost']:.4f}\n"
+    )
+    args._last_stats = dict(usage)   # 供 main() 两段式汇总
+    if status == "completed":
+        return 0
+    if status == "unknown":
+        # 跑完但引擎没回终态 (常见: 弱模型空消息自停)。产物可能仍完整, 单列退出码供批量统计区分。
+        print("⚠️ status=unknown (引擎未回报终态), 退出码 3; 产物可能完整, 建议核对 out_dir", file=sys.stderr)
+        return 3
+    return 2
+
+
+def _parse_args() -> argparse.Namespace:
+    p = argparse.ArgumentParser(
+        description="跑 procedure-dsl 提取流程 (Cyber AgentRunner + OpenRouter)",
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        epilog=__doc__,
+    )
+    p.add_argument("source", help="原始 post 文件 (input/case-N-raw.json)")
+    p.add_argument("--out-dir", required=True,
+                   help="输出目录名, 落在 outputs/ 下. case_id 自动从 basename 推。")
+    p.add_argument("--extra-image", action="append", default=[],
+                   help="额外配图 (本地路径 or URL), 可多次。")
+    p.add_argument("--provider", default="openrouter", choices=["openrouter", "qwen"],
+                   help="LLM 端点: openrouter (默认, OPEN_ROUTER_API_KEY, 一个 URL 通打各家) "
+                        "或 qwen (阿里 dashscope 原生, 读 .env 的 QWEN_API_KEY + QWEN_BASE_URL)。")
+    p.add_argument("--model", default="google/gemini-3.1-flash-lite",
+                   help="模型名 (默认 google/gemini-3.1-flash-lite, 与 UI/批量评估对齐)。"
+                        "provider=openrouter 时形如 openai/gpt-4o / qwen/qwen-max / "
+                        "anthropic/claude-sonnet-4.5; provider=qwen 时形如 qwen-plus / qwen-max (无前缀)。"
+                        "支持别名: flash / flash-3.5 → google/gemini-3.5-flash, "
+                        "flash-lite → google/gemini-3.1-flash-lite。")
+    p.add_argument("--phase1-model", default=None,
+                   help="启用两段式: Phase 1 (心智模型+骨架+anchor) 用这个模型跑完即停, "
+                        "Phase 2+ 换 --model resume 续跑。不传=全程单模型。"
+                        "例: --phase1-model anthropic/claude-sonnet-4.6 --model google/gemini-3.1-flash-lite")
+    p.add_argument("--phase1-provider", default=None, choices=["openrouter", "qwen"],
+                   help="Phase 1 段的 provider, 默认继承 --provider。")
+    p.add_argument("--exp", default=None, choices=["direct", "split"],
+                   help="Phase 1 实验模式 (产出 workflow.json 骨架后即停, 不跑 Phase 2/3):\n"
+                        "  direct = 强模型(--model)不写 understanding, 边想边直接出 workflow.json;\n"
+                        "  split  = 强模型(--phase1-model)只产 understanding → 弱模型(--model)据 understanding+schema 产 workflow.json。")
+    p.add_argument("--skill", default="dsl", choices=["dsl", "procedure"],
+                   help="dsl (默认) = spec/ 三阶段流程 (plan_procedures + wf-patch + lint + render); "
+                        "procedure = procedure/ 强模型直写版 (一次 write_file 出 workflow.json, "
+                        "validate.py 单工具校验, 不渲染 HTML)。")
+    p.add_argument("--spec-version", default=None, metavar="SUFFIX",
+                   help="用 spec-<SUFFIX>/ 目录而非默认 spec/ (实验变体, 不污染原 spec)。")
+    p.add_argument("--max-turns", type=int, default=300, help="最大迭代轮数 (default: 300)")
+    p.add_argument("--max-image-dim", type=int, default=1280,
+                   help="图片下采样最长边像素 (default: 1280, 0=关闭)。多张大图 base64 合计过大会"
+                        "打断 OpenRouter→Claude 上游流 (internal stream ended); 下采样+转JPEG 防此并省 token。")
+    p.add_argument("--image-quality", type=int, default=85,
+                   help="下采样后 JPEG 质量 (default: 85)。截图含文字, 别压太低伤可读性。")
+    p.add_argument("--resume", action="store_true",
+                   help="从 outputs/<out-dir>/.trace_id 读 trace 续跑 (batch 模式下按子目录逐 case 判断)")
+    p.add_argument("--batch", action="store_true",
+                   help="批量模式: source 是 batch_posts.json (results[] 每项含 post), "
+                        "out-dir 是父目录, 每个工序一个子目录 (已出 HTML 的自动跳过)")
+    p.add_argument("--batch-redo", action="store_true",
+                   help="batch 模式下重跑已有 HTML 的 case (默认跳过)")
+    p.add_argument("--batch-workers", type=int, default=1,
+                   help="batch 并行数 (默认 1=进程内串行, 控制台看实时 trace; >1 每 case 一个"
+                        "子进程, 输出落各自 _extract.log, 建议 2-4)")
+    p.add_argument("--no-ocr", action="store_true",
+                   help="跳过执行前的配图预 OCR (默认开启: 每张图 OCR 成文本落 _scratch/ocr.txt, 供 quote-source --ocr 搜)")
+    p.add_argument("--ocr-model", default="google/gemini-3.1-flash-lite",
+                   help="预 OCR 用的视觉模型 (default: google/gemini-3.1-flash-lite, 走 OpenRouter)")
+    p.add_argument("--max-auto-continue", type=int, default=2,
+                   help="完成度兜底: 跑完若 workflow 没填全/没出 HTML(弱模型常吐空消息自停), "
+                        "自动带'还差X'续跑的最大次数 (default: 2, 0=关闭)")
+    return p.parse_args()
+
+
+def _run_pass(args: argparse.Namespace, *, provider: str, model: str,
+              mode: str, resume: bool = False) -> tuple:
+    """跑一段: 设好 provider/model/mode/resume 后调 run()。返回 (退出码, usage 统计)。
+
+    mode ∈ {full, phase1, phase2-handoff, exp-direct, exp-understanding, exp-workflow}
+    (run() 内据此选起手附注、是否兜底续跑; 取代旧版 5 个 args 隐藏 flag)。
+    """
+    args.provider, args.model = provider, model
+    args.mode, args.resume = mode, resume
+    rc = asyncio.run(run(args))
+    return rc, dict(args._last_stats)
+
+
+def _banner(title: str) -> None:
+    print(f"\n{'='*64}\n  {title}\n{'='*64}", flush=True)
+
+
+def _run_batch(args: argparse.Namespace) -> int:
+    """批量模式: source 是 batch_posts.json, 逐条跑完整单 case 流程。
+
+    输入格式: {"results": [{"case_id", "platform", "source_url", "post": {...}}, ...]}
+    (也容忍顶层直接是 post 列表)。每条的 post 字段是单 case 输入的超集
+    (body_text/title/link/publish_timestamp/images), 落成 <子目录>/_source.json 后
+    走与单跑完全相同的流程 — 门禁/OCR/兜底续跑全部复用, 不另起一套。
+
+    目录: outputs/<out-dir>/<case_id>/ 一工序一子目录。
+    跳过: 子目录已有 *.html 视为做完, 跳过 (--batch-redo 强制重跑); 失败不中断后续 case。
+    --resume: 子目录有 .trace_id 的 case 续 trace 跑, 没有的正常 fresh。
+    并行: --batch-workers N (默认 1)。N=1 进程内串行 (控制台可看实时 trace);
+      N>1 每 case 一个**子进程** (plan_tool._PLAN_CTX 是模块级全局, 同进程并发会把
+      A case 的骨架写进 B case 的目录 — 进程边界是唯一安全的隔离), 各 case 输出落
+      <子目录>/_extract.log, 主进程只报进度。
+    退出码: 0=全部成功(含跳过/unknown) / 2=有失败 / 130=中断。
+    """
+    src = Path(args.source).expanduser().resolve()
+    data = json.loads(src.read_text(encoding="utf-8"))
+    items = data.get("results") if isinstance(data, dict) else data
+    if not isinstance(items, list) or not items:
+        print(f"❌ --batch: {src.name} 里没有 results[] 列表", file=sys.stderr)
+        return 2
+    batch_root = _resolve_out_dir(args.out_dir, DSL_ROOT)
+    batch_root.mkdir(parents=True, exist_ok=True)
+    workers = max(1, getattr(args, "batch_workers", 1))
+    print(f"[batch] {len(items)} 条 → {batch_root} (model={args.model}, workers={workers})", flush=True)
+
+    # ── 第一遍: 落盘 _source/_meta, 建工作清单 (跳过的直接进汇总) ──
+    want_resume = args.resume
+    summary: List[tuple] = []           # (case_id, 状态, cost)
+    work: List[tuple] = []              # (case_id, sub_dir, case_src, resume)
+    for n, item in enumerate(items, 1):
+        if not isinstance(item, dict):
+            continue
+        post = item.get("post") or item
+        cid = str(item.get("case_id") or post.get("channel_content_id") or f"case{n:03d}")
+        sub = batch_root / cid
+        if not args.batch_redo and list(sub.glob("*.html")):
+            print(f"[batch] {cid} 已有 HTML, 跳过", flush=True)
+            summary.append((cid, "skip", 0.0))
+            continue
+        if not (post.get("body_text") or "").strip():
+            print(f"[batch] {cid} post.body_text 为空, 跳过", flush=True)
+            summary.append((cid, "empty", 0.0))
+            continue
+        sub.mkdir(parents=True, exist_ok=True)
+        case_src = sub / "_source.json"
+        case_src.write_text(json.dumps(post, ensure_ascii=False, indent=2), encoding="utf-8")
+        (sub / "_meta.json").write_text(json.dumps({
+            "case_id": cid, "platform": item.get("platform", ""),
+            "source_url": item.get("source_url", post.get("link", "")),
+            "title": post.get("title", ""), "model": args.model,
+            "started_at": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
+        }, ensure_ascii=False, indent=2), encoding="utf-8")
+        work.append((cid, sub, case_src, want_resume and (sub / ".trace_id").exists()))
+
+    totals = {"in": 0, "out": 0, "cost": 0.0}
+    interrupted = False
+
+    if workers == 1:
+        # ── 串行: 进程内复用 run(), 控制台可看实时 trace ──
+        for n, (cid, sub, case_src, resume) in enumerate(work, 1):
+            args.source = str(case_src)
+            args.out_dir = str(sub)     # 绝对路径 → _resolve_out_dir 直通, 不再拼 outputs/
+            args.case_id = cid
+            args.resume = resume
+            args._last_stats = {}       # 防 run() 异常早退时把上一条 case 的统计错记到本条
+            _banner(f"[batch {n}/{len(work)}] {cid}")
+            try:
+                rc = asyncio.run(run(args))
+            except KeyboardInterrupt:
+                rc = 130
+            stats = dict(args._last_stats)
+            totals["in"] += stats.get("in", 0)
+            totals["out"] += stats.get("out", 0)
+            totals["cost"] += stats.get("cost", 0.0)
+            summary.append((cid, rc, stats.get("cost", 0.0)))
+            if rc == 130:
+                interrupted = True
+                print("\n⚠️ 批量中断; 已完成的 case 保留, 重跑同命令会跳过它们续做剩余。", file=sys.stderr)
+                break
+    elif work:
+        # ── 并行: 每 case 一个子进程, 输出落 <子目录>/_extract.log ──
+        from concurrent.futures import ThreadPoolExecutor, as_completed
+        live_procs: set = set()
+
+        def _one(cid: str, sub: Path, case_src: Path, resume: bool) -> tuple:
+            cmd = [sys.executable, "-u", str(DSL_ROOT / "run_cyber.py"), str(case_src),
+                   "--out-dir", str(sub), "--model", args.model, "--provider", args.provider,
+                   "--max-turns", str(args.max_turns),
+                   "--max-image-dim", str(args.max_image_dim),
+                   "--image-quality", str(args.image_quality),
+                   "--ocr-model", args.ocr_model,
+                   "--max-auto-continue", str(args.max_auto_continue)]
+            if getattr(args, "spec_version", None):
+                cmd += ["--spec-version", args.spec_version]
+            if getattr(args, "skill", "dsl") != "dsl":
+                cmd += ["--skill", args.skill]
+            if args.no_ocr:
+                cmd.append("--no-ocr")
+            if resume:
+                cmd.append("--resume")
+            log_path = sub / "_extract.log"
+            env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
+            with log_path.open("w", encoding="utf-8", buffering=1) as fh:
+                proc = subprocess.Popen(cmd, stdout=fh, stderr=subprocess.STDOUT,
+                                        cwd=str(DSL_ROOT), env=env)
+                live_procs.add(proc)
+                try:
+                    rc = proc.wait()
+                finally:
+                    live_procs.discard(proc)
+            # 子进程 cost 从其日志的 [usage] 行回收 (best-effort)
+            cost = tin = tout = 0
+            try:
+                import re as _re
+                tail = log_path.read_text(encoding="utf-8", errors="replace")[-4000:]
+                m = _re.findall(r"tokens in=([\d,]+) out=([\d,]+).*?cost=\$([0-9.]+)", tail)
+                if m:
+                    tin, tout, cost = (int(m[-1][0].replace(",", "")),
+                                       int(m[-1][1].replace(",", "")), float(m[-1][2]))
+            except Exception:
+                pass
+            return cid, rc, cost, tin, tout
+
+        print(f"[batch] 并行 {workers} 路, 各 case 实时日志: <子目录>/_extract.log", flush=True)
+        done_n = 0
+        try:
+            with ThreadPoolExecutor(max_workers=workers) as pool:
+                futs = {pool.submit(_one, *w): w[0] for w in work}
+                for fut in as_completed(futs):
+                    cid, rc, cost, tin, tout = fut.result()
+                    done_n += 1
+                    totals["in"] += tin
+                    totals["out"] += tout
+                    totals["cost"] += cost
+                    summary.append((cid, rc, cost))
+                    mark = "✅" if rc == 0 else ("⚠" if rc == 3 else "❌")
+                    print(f"[batch {done_n}/{len(work)}] {mark} {cid} rc={rc} ${cost:.4f}", flush=True)
+        except KeyboardInterrupt:
+            interrupted = True
+            print("\n⚠️ 批量中断, 终止运行中的子进程…", file=sys.stderr)
+            for p in list(live_procs):
+                try:
+                    p.terminate()
+                except Exception:
+                    pass
+
+    _banner(f"批量汇总 ({len(summary)}/{len(items)} 条)")
+    _MARK = {0: "✅", 3: "⚠ unknown", 130: "⏸ 中断", "skip": "↷ 跳过", "empty": "∅ 空正文"}
+    for cid, st, cost in summary:
+        print(f"  {_MARK.get(st, f'❌ rc={st}'):10} {cid}  ${cost:.4f}")
+    print(f"  tokens in={totals['in']:,} out={totals['out']:,} · 合计 ${totals['cost']:.4f}", flush=True)
+    if interrupted:
+        return 130
+    return 0 if all(st in (0, 3, "skip", "empty") for _, st, _ in summary) else 2
+
+
+def main() -> None:
+    for stream in (sys.stdout, sys.stderr):
+        if hasattr(stream, "reconfigure"):
+            stream.reconfigure(encoding="utf-8", errors="replace")
+    logging.basicConfig(level=logging.WARNING)
+    _load_env()   # 把 .env (OPEN_ROUTER_API_KEY / QWEN_API_KEY / QWEN_BASE_URL) 载入环境
+    args = _parse_args()
+    args.case_id = _derive_case_id(args.out_dir)
+    args.mode = "procedure" if args.skill == "procedure" else "full"
+    args._last_stats = {}
+    if args.skill == "procedure" and (args.exp or args.phase1_model or args.spec_version):
+        print("❌ --skill procedure 不与 --exp / --phase1-model / --spec-version 组合 "
+              "(单模型直写流程, 没有阶段拆分)。", file=sys.stderr)
+        sys.exit(2)
+    # 模型别名解析 (flash → google/gemini-3.5-flash 等; 非别名原样透传)
+    args.model = _resolve_model(args.model)
+    args.ocr_model = _resolve_model(args.ocr_model)
+    if args.phase1_model:
+        args.phase1_model = _resolve_model(args.phase1_model)
+
+    # ── 批量模式: 单模型全流程逐条跑 (不与 --exp / 两段式组合) ──
+    if args.batch:
+        if args.exp or args.phase1_model:
+            print("❌ --batch 暂不支持与 --exp / --phase1-model 组合 (单模型全流程逐条跑)。", file=sys.stderr)
+            sys.exit(2)
+        sys.exit(_run_batch(args))
+
+    def _g(d, k):
+        return d.get(k, 0) if d else 0
+
+    # ── 实验模式 (--exp): 只产 workflow.json 骨架, 不跑 Phase 2/3 ──
+    if args.exp == "direct":
+        # 方案1: 强模型(--model)不写 understanding, 边想边直接出 workflow.json。
+        _banner(f"[exp:direct] {args.provider}/{args.model} · 直接产 workflow.json")
+        rc, _ = _run_pass(args, provider=args.provider, model=args.model, mode="exp-direct")
+        sys.exit(rc)
+
+    if args.exp == "split":
+        # 方案2: 强模型(--phase1-model)只产 understanding → 弱模型(--model)据其产 workflow.json。
+        if not args.phase1_model:
+            print("❌ --exp split 需要 --phase1-model (强模型, 产 understanding)。", file=sys.stderr)
+            sys.exit(2)
+        main_provider, main_model = args.provider, args.model
+        p1_provider = args.phase1_provider or args.provider
+        p1_model = args.phase1_model
+        _banner(f"[exp:split] A · understanding · {p1_provider}/{p1_model}")
+        rcA, statsA = _run_pass(args, provider=p1_provider, model=p1_model, mode="exp-understanding")
+        if rcA not in (0, 3):
+            print(f"❌ split-A (understanding) 退出码={rcA}, 不继续。", file=sys.stderr)
+            sys.exit(rcA)
+        _banner(f"[exp:split] B · workflow.json · {main_provider}/{main_model}")
+        # B 是全新一段 (resume=False): 不继承强模型历史(含图), 只凭 understanding.md + schema
+        rcB, statsB = _run_pass(args, provider=main_provider, model=main_model, mode="exp-workflow")
+        _banner(f"[exp:split] 成本汇总 (case {args.case_id})")
+        print(f"  A understanding [{p1_model}]: in={_g(statsA,'in'):,} out={_g(statsA,'out'):,} · ${_g(statsA,'cost'):.4f}")
+        print(f"  B workflow.json [{main_model}]: in={_g(statsB,'in'):,} out={_g(statsB,'out'):,} · ${_g(statsB,'cost'):.4f}")
+        print(f"  合计: ${_g(statsA,'cost') + _g(statsB,'cost'):.4f}", flush=True)
+        sys.exit(rcB)
+
+    # 单模型: 直接跑 (mode 已在上面按 --skill 解析: full / procedure)。
+    if not args.phase1_model:
+        rc, _ = _run_pass(args, provider=args.provider, model=args.model, mode=args.mode)
+        sys.exit(rc)
+
+    # 两段式: Pass 1 (Phase 1, 模型A) → Pass 2 (Phase 2+, 模型B, resume 同一 trace)。
+    main_provider, main_model = args.provider, args.model
+    p1_provider = args.phase1_provider or args.provider
+    p1_model = args.phase1_model
+
+    _banner(f"Pass 1/2 · Phase 1 only · {p1_provider}/{p1_model}")
+    rc1, stats1 = _run_pass(args, provider=p1_provider, model=p1_model, mode="phase1")
+    if rc1 not in (0, 3):     # 3 = status unknown 但产物可能完整, 带着警告继续 Pass 2
+        print(f"❌ Pass 1 退出码={rc1}, 不继续 Phase 2。", file=sys.stderr)
+        sys.exit(rc1)
+
+    _banner(f"Pass 2/2 · Phase 2+ (resume) · {main_provider}/{main_model}")
+    rc2, stats2 = _run_pass(args, provider=main_provider, model=main_model,
+                            mode="phase2-handoff", resume=True)
+
+    _banner(f"两段式成本汇总 (case {args.case_id})")
+    print(f"  Pass1 [{p1_model}]: in={_g(stats1,'in'):,} out={_g(stats1,'out'):,} · ${_g(stats1,'cost'):.4f}")
+    print(f"  Pass2 [{main_model}]: in={_g(stats2,'in'):,} out={_g(stats2,'out'):,} · ${_g(stats2,'cost'):.4f}")
+    print(f"  合计: ${_g(stats1,'cost') + _g(stats2,'cost'):.4f} (不含子 Agent)", flush=True)
+    sys.exit(rc2)
+
+
+if __name__ == "__main__":
+    main()

+ 797 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/run_procedure_dsl.py

@@ -0,0 +1,797 @@
+#!/usr/bin/env python3
+"""
+run_procedure_dsl.py — 拿 procedure-dsl/spec.md 当指令本, 让 Claude Agent SDK
+(走 ~/.claude OAuth Max 订阅额度) 对单个 post 跑完三阶段提取, 落 case-N.{md,html}.
+
+设计:
+- 复用 Agent 仓 examples/process_pipeline/run_pipeline.py --use-claude-sdk 的 OAuth
+  思路: 子进程 env 把 ANTHROPIC_API_KEY / BASE_URL / AUTH_TOKEN 显式置空, 让
+  claude CLI 回落到 OAuth 凭证.
+- 与 agent/llm/claude_code_oauth.py 的 one-shot wrapper 不同: 那个 max_turns=1
+  + allowed_tools=[], 本脚本让 Agent 真正自主跑——开 Read/Write/Bash/Edit/Glob/Grep,
+  multi-turn, 自己读 spec.md / source / 调 bin/taxonomy-lookup.py / 写产物.
+- 单 post 输入, 多终端 = 多并行 (用户自己开).
+
+用法 (本脚本位于 procedure-dsl/, SDK cwd 默认设到 procedure-dsl/):
+    # source 是 input/case-N-raw.json, 脚本自动从 image_url_list 拉图作多模态.
+    # --out-dir 必填: 是 outputs/ 下的目录名, 产物全落这里; case_id 自动从它的 basename 推.
+    python run_procedure_dsl.py input/case-2-raw.json --out-dir case-2
+    python run_procedure_dsl.py input/case-2-raw.json --out-dir case-2 \\
+        --extra-image /path/to/local-ref.png --model claude-sonnet-4-6
+    # 跑实验版 spec-test/ 对比 (产物落 outputs/case-2_test/):
+    python run_procedure_dsl.py input/case-2-raw.json --out-dir case-2_test --version test
+    # 中断后恢复 (产物保留, agent 重读磁盘接着跑):
+    python run_procedure_dsl.py input/case-2-raw.json --out-dir case-2 --resume
+
+source 文件 schema (procedure-dsl/input/*.json 约定):
+    {
+      "title": str, "link": str, "body_text": str,
+      "image_url_list": [{"image_type": int, "image_url": str}, ...],
+      "publish_timestamp": ..., "channel_account_name": str,
+    }
+"""
+import argparse
+import asyncio
+import base64
+import json
+import logging
+import sys
+import time
+from datetime import datetime
+from pathlib import Path
+from typing import Any, Dict, List
+
+# run_procedure_dsl.py → procedure-dsl/
+DSL_ROOT = Path(__file__).resolve().parent
+
+
+def _derive_case_id(out_dir: str) -> str:
+    """从 --out-dir 自动派生 case_id (用于 prompt 文件名 + case_data.case_id + suggestions record).
+
+    规则: Path(out_dir).name 去掉 "case-" 前缀 (--out-dir 是 outputs/ 下的相对名).
+      --out-dir case-5             → "5"
+      --out-dir case-5-newflow     → "5-newflow"
+      --out-dir photo-album        → "photo-album"   (无 case- 前缀也行)
+      --out-dir case-11            → "11"
+
+    这样用户传 --out-dir 控制目录名, case_id 自动跟随 — 不再撞历史 case 目录.
+    """
+    name = Path(out_dir).name
+    if name.startswith("case-"):
+        name = name[5:]
+    return name or "?"
+
+
+def _resolve_out_dir(out_dir_arg: str, workdir: Path) -> Path:
+    """把 --out-dir 解析成实际工作目录. --out-dir 是 `outputs/` 下的相对名:
+
+      --out-dir newdir          → <workdir>/outputs/newdir
+      --out-dir case-5          → <workdir>/outputs/case-5
+      --out-dir outputs/newdir  → <workdir>/outputs/newdir   (容忍已带 outputs/ 前缀, 不重复嵌套)
+
+    传绝对路径则原样用 (escape hatch).
+    """
+    p = Path(out_dir_arg)
+    if p.is_absolute():
+        return p.resolve()
+    parts = p.parts
+    if parts and parts[0] == "outputs":          # 容忍历史习惯的 outputs/ 前缀
+        parts = parts[1:]
+    base = workdir / "outputs"
+    return (base / Path(*parts)).resolve() if parts else base.resolve()
+
+# Sonnet 4.6 公开价目 (per 1M tokens, USD), 用于 estimated cost.
+# OAuth Max 模式 SDK 报的 total_cost_usd 通常是 None — 我们自己按 token 算个
+# "如果走 API 等价多少钱"作为 quota 消耗的直观代理.
+PRICE_SONNET_4_6 = {
+    "input": 3.00,
+    "output": 15.00,
+    "cache_creation": 3.75,
+    "cache_read": 0.30,
+}
+
+
+def _estimate_cost_usd(usage: Dict[str, Any]) -> float:
+    if not usage:
+        return 0.0
+    return (
+        usage.get("input_tokens", 0) / 1_000_000 * PRICE_SONNET_4_6["input"]
+        + usage.get("output_tokens", 0) / 1_000_000 * PRICE_SONNET_4_6["output"]
+        + usage.get("cache_creation_input_tokens", 0) / 1_000_000 * PRICE_SONNET_4_6["cache_creation"]
+        + usage.get("cache_read_input_tokens", 0) / 1_000_000 * PRICE_SONNET_4_6["cache_read"]
+    )
+
+
+# ──── 多模态: 图片 → Anthropic content block ──────────────────────────────────
+
+_MEDIA_TYPE = {
+    ".png": "image/png",
+    ".jpg": "image/jpeg",
+    ".jpeg": "image/jpeg",
+    ".gif": "image/gif",
+    ".webp": "image/webp",
+}
+
+# client-side image cache: DSL_ROOT/.image_cache/<sha256>.<ext>
+# 同一 URL 多次跑 / resume 不重复下载. 不影响 SDK / OAuth, 纯本地 IO.
+_IMAGE_CACHE_DIR = DSL_ROOT / ".image_cache"
+
+# 浏览器 UA, 避免 mmbiz / 其他图床对裸 python-requests 默认 UA 直接 403.
+_DOWNLOAD_UA = (
+    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
+    "(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
+)
+
+
+def _url_to_cached_path(url: str, timeout: float = 15.0) -> Path:
+    """下载 url 到 _IMAGE_CACHE_DIR, 返回本地路径. 已缓存直接返回不重下.
+
+    用 URL 的 sha256 当文件名, 扩展名从 URL path 推断 (找不到默认 .png).
+    设计目的: 绕过 Anthropic 服务端对 image URL 的 robots.txt 检查
+    (mmbiz.qpic.cn 等图床 robots disallow 会让 API 直接 400).
+    """
+    import hashlib
+    from urllib.parse import urlparse
+    from urllib.request import Request, urlopen
+
+    _IMAGE_CACHE_DIR.mkdir(exist_ok=True)
+    digest = hashlib.sha256(url.encode("utf-8")).hexdigest()[:24]
+    ext = Path(urlparse(url).path).suffix.lower()
+    if ext not in _MEDIA_TYPE:
+        ext = ".png"
+    local = _IMAGE_CACHE_DIR / f"{digest}{ext}"
+
+    if local.exists() and local.stat().st_size > 0:
+        return local
+
+    req = Request(url, headers={"User-Agent": _DOWNLOAD_UA, "Accept": "image/*,*/*;q=0.8"})
+    with urlopen(req, timeout=timeout) as resp:
+        data = resp.read()
+    local.write_bytes(data)
+    return local
+
+
+def _append_image_blocks(blocks: List[Dict[str, Any]], images: List[str]) -> None:
+    """循环把 images 转成 content block 加到 blocks. 单张失败不阻塞整批.
+
+    base / variant driver 共用 — 保证 image 容错策略一致.
+    """
+    n_ok, n_fail = 0, 0
+    for ref in images:
+        try:
+            blocks.append(_image_block(ref))
+            n_ok += 1
+        except Exception as e:
+            n_fail += 1
+            print(f"[image] skip {ref[:80]}... ({type(e).__name__}: {e})", flush=True)
+    if images:
+        print(f"[image] {n_ok}/{len(images)} 成功下载并 base64 化, {n_fail} 失败已跳过", flush=True)
+
+
+def _image_block(ref: str) -> Dict[str, Any]:
+    """图 ref → Anthropic content block.
+
+    URL → 客户端下载后 base64 (不再走 server-side fetch, 绕开 robots.txt 限制).
+    本地路径 → 直接 base64.
+    下载失败 (网络问题 / 404 等) → raise, 让上层决定跳过还是阻塞.
+    """
+    if ref.startswith(("http://", "https://")):
+        local = _url_to_cached_path(ref)
+        data = base64.standard_b64encode(local.read_bytes()).decode()
+        return {
+            "type": "image",
+            "source": {
+                "type": "base64",
+                "media_type": _MEDIA_TYPE.get(local.suffix.lower(), "image/png"),
+                "data": data,
+            },
+        }
+    p = Path(ref).expanduser().resolve()
+    if not p.exists():
+        raise FileNotFoundError(f"image not found: {ref}")
+    data = base64.standard_b64encode(p.read_bytes()).decode()
+    return {
+        "type": "image",
+        "source": {
+            "type": "base64",
+            "media_type": _MEDIA_TYPE.get(p.suffix.lower(), "image/png"),
+            "data": data,
+        },
+    }
+
+
+# ──── source JSON → 自动拉 image_url_list ────────────────────────────────────
+
+def _images_from_source(source_path: Path) -> List[str]:
+    """从 procedure-dsl/input/*.json 抽 URL 列表, 兼容两套 schema:
+
+    1. 老 case-*-raw.json: `image_url_list: [{image_type, image_url}, ...]`,
+       image_type=2 (封面) 排最前, 其余维持原序.
+    2. 新 eval_case-*.json: `images: [url_str, ...]`, 无封面信号, 原序返回.
+
+    schema 错配时如果检测到疑似图字段但抽不到任何 URL, 会打 warning —
+    multimodal pipeline 静默 0 张图比报错更难排查.
+    """
+    if source_path.suffix.lower() != ".json":
+        return []
+    try:
+        with source_path.open(encoding="utf-8") as f:
+            data = json.load(f)
+    except (json.JSONDecodeError, OSError):
+        return []
+    if not isinstance(data, dict):
+        return []
+
+    # 新 schema (eval_case-*.json): 裸 URL 数组
+    flat = data.get("images")
+    if isinstance(flat, list):
+        urls = [u for u in flat if isinstance(u, str) and u]
+        if not urls and flat:
+            print(f"[image] ⚠️ {source_path.name} 有 images 字段但抽不到 URL "
+                  f"(首项类型={type(flat[0]).__name__})", flush=True)
+        return urls
+
+    # 老 schema (case-*-raw.json): {image_type, image_url} dict 数组
+    items = data.get("image_url_list")
+    if not isinstance(items, list):
+        return []
+    covers, others = [], []
+    for it in items:
+        if not isinstance(it, dict):
+            continue
+        url = it.get("image_url")
+        if not isinstance(url, str) or not url:
+            continue
+        (covers if it.get("image_type") == 2 else others).append(url)
+    return covers + others
+
+
+# ──── 初始 user 消息 (text + 图片 blocks) ─────────────────────────────────────
+
+def _build_initial_blocks(
+    source_ref: str, case_id: str, out_dir_arg: str, images: List[str], workdir: Path,
+    spec_name: str = "spec",
+) -> List[Dict[str, Any]]:
+    # 全部路径用绝对路径喂给 Agent — 它训练习惯就吃绝对, 顺水推舟省心.
+    # 用 .as_posix() 统一 forward slash, 跟 f-string 拼接的 "/..." 一致.
+    # spec_name 由 --version 决定 (spec / spec-backup / spec-test ...), 默认 "spec".
+    spec_dir    = (workdir / spec_name).as_posix()
+    spec_readme = (workdir / spec_name / "README.md").as_posix()
+    spec_tools  = (workdir / spec_name / "tools.md").as_posix()
+    # --out-dir 是 outputs/ 下的相对名 (--out-dir newdir → outputs/newdir); 绝对路径原样用.
+    _out_dir = _resolve_out_dir(out_dir_arg, workdir)
+    case_dir    = _out_dir.as_posix()
+    scratch_dir = (_out_dir / "_scratch").as_posix()
+    # source 路径直接用 source_ref (用户传的 positional arg). 不再从 case_id 推 —
+    # 否则当 --out-dir 跟 source 文件名不对齐时 (e.g. --out-dir outputs/update + source=input/case-5.json),
+    # Agent 会收到 "input/case-update-raw.json" 这种不存在路径, 浪费 10+ turn 自我探索.
+    _src = Path(source_ref)
+    case_input = _src.as_posix() if _src.is_absolute() else (workdir / _src).resolve().as_posix()
+
+    text = f"""请按 {spec_name}/ 目录里的 SKILL 处理这个 post.
+
+## 起手指令 (路径已给绝对值, 直接照搬, 不要改, 不要先 find 探查)
+
+1. `Read(file_path="{spec_readme}")` — self-driven skill 的入口, 含完整 phase 加载指南 (累积式) + 自查清单 + 工具调用规则. 读完不要再 Read 它.
+2. `Read(file_path="{spec_tools}")` — 外部脚本接口手册. 读完不要重读.
+3. 按 README phase 加载指南**累积式**前进, 中间产物是**单个 `workflow.json` 文件**, 全程用 `wf-patch.py` 演化它 (绝不 Write/Edit 手改; 怎么用见 README「🛠 运行时约定」+ tools.md):
+   - Phase 1 骨架 (想清楚 + 直接建, **不必单独写 understanding.md**) → 先在文字回复里**简述**「有几个独立工序 / 每个工序的步骤序列(每步: 用什么工具·对什么输入·做什么动作·得什么输出)」, 想清楚多步拆分(**别把多步流水线压成单步**), 然后**直接** `wf-patch.py --patch` 建 `{case_dir}/workflow.json` (扁平 patch, proc/step/IO 一次建全; 缺路径默认自动建, 填字段也不会越界)
+   - Phase 1.3 IO 闭合 → `wf-patch.py` 加 anchor + 用 `@quote` 标记 + `--resolve-quotes` 让工具自动填真实 value/directive
+   - Phase 2 归类标注 → `wf-patch.py` 加 effect/action/type/substance/form/intent + type_registry (单 Agent 一趟做完, 无 A/B/C 子步划分; 细则见 phase2-normalize.md)
+   - Phase 3 lint + 渲染 → 调 lint-case.py + render-case.py 产出 `{case_dir}/case-{case_id}-<slug>.html` (不写 case_data.json, renderer 内存组装; **.md 已取消, HTML 是唯一产物**)
+
+## ❌ 重复读取禁令 (CRITICAL: ZERO REPEATED READS)
+
+你拥有完美的长期记忆(由于 Context 累积,你读取过的所有文件内容会永远保留在你的 Context 中)。
+请**绝对不要**重复读取任何文件!任何重复的 `Read` 动作都是对 Token 和回合数 Budget 的极大浪费。
+- **禁忌 1**:不要因为看到 spec 文档中写了 `详见 [tools.md §2]` 就去重新 `Read(file_path="{spec_tools}")`。你已经在 Turn 3 读过它了,直接检索你的记忆!
+- **禁忌 2**:不要因为还在 Phase 2 里推进,就去重新 `Read` 任何 Phase 2 的 spec 文件(如 `phase2-normalize.md`)。你在进入 Phase 2 时已经读过它了,它就在你的记忆中,直接使用它!
+- 在发出任何 `Read` 指令前,必须自我核对:“我之前读过这个文件吗?”。如果读过,绝对不要再次 Read!
+
+## 输入
+
+- case 原文: `{case_input}`
+  schema (两种都可能):
+    · 老格式 (case-*-raw.json): {{title, link, body_text, image_url_list:[{{image_type,image_url}}], publish_timestamp, channel_account_name}}
+    · 新格式 (eval_case-*.json): {{title, link, body_text, images:[url_str], videos, channel, content_type, like_count, publish_timestamp, channel_content_id, ...}}
+  正文 (body_text) 和元数据从此文件 Read; 两种 schema 的 body_text 含义一致.
+- 配图: 本消息附了 {len(images)} 张图作多模态内容 (URL 抽自老格式的 image_url_list 或新格式的 images; 老格式 image_type=2 封面排最前, 新格式按原序).
+
+## 输出目录
+
+`{case_dir}/` (这一 case 的所有产物都放这里, 不要污染其他目录)
+
+## 读取范围 (硬约束)
+
+你**只能** Read 以下三处 (用绝对路径 + 子路径):
+
+1. `{spec_dir}/` 及其所有子目录 (skill 全部内容: README.md / tools.md / 各 phase 规格文件 / output/ / taxonomy/ / templates/ / tools/ — 但 tools/*.py **不要 Read 源码**, 只通过 Bash 调用; 具体子目录名以 {spec_name}/README.md 的章节地图为准, **不要脑补 part1-/part2- 这类对称目录**)
+2. `{case_input}` (当前 case 的原文, 只此一个)
+3. `{case_dir}/` 目录 (你自己的工作产物, 含其下 `_scratch/`)
+
+## 长输出 dump 区 (sanctioned scratch)
+
+如果你需要 dump 大 Bash 输出做后续分析 (e.g. `taxonomy-lookup --subtree` 输出过大想分段读, 或 `find` 结果想保留), **只写到 `{scratch_dir}/`** (runner 已预创建):
+
+✅ `python {spec_dir}/tools/taxonomy-lookup.py --dim 实质 --subtree /表象/视觉 > {scratch_dir}/subst_visual.txt`
+✅ 然后 `Read(file_path="{scratch_dir}/subst_visual.txt")` 提取需要的段
+✅ 一次性小探查 / smoke test (验证某条 tool 命令、看某段数据长啥样) 也可以放 `{scratch_dir}/`, 用完即弃
+
+❌ **不要用 Python 脚本生成 / 批量改写 `workflow.json`** — 它由你**直接 Write 骨架 + 逐字段填** 演化 (见各 phase 规格). 写 build_workflow / add_anchors / normalize 这类脚本去拼 JSON, 反而踩转义 / 控制字符坑 (LLM 拼长 JSON 极易坏), 还把本该逐 step 的语义判断埋进一次性脚本里. 几十处字段要批量改 → 用 **`spec/tools/wf-patch.py`** (path=value 清单, 工具负责安全写 JSON + 写入即校验; 见 {spec_name}/tools.md §2), 零星单处用 Edit. `_scratch/` 的 Python **只用于「dump 大 tool 输出」和「smoke test」, 不是 workflow.json 的生产线**.
+❌ **不要写到项目根 `scratch/`** (那是 dev/repo 维护用的临时区, 禁区)
+❌ **不要 ls / Read 项目根 `scratch/`** (别人的 dev 临时文件, 跟你无关; 你的 scratch 在上面的 `_scratch/`)
+
+**禁读区** (不要 Read 也不要 ls 这些位置): 项目根的 spec.md / design.md (旧文件), examples/ 全目录, input/ 下其他 case-*-raw.json, outputs/case-OTHER/ (其他 case 目录), bin/ 全目录 (已废弃), **项目根 `scratch/`** (跟你的 `_scratch/` 不是一回事 — 上面 ✅ 那个 `_scratch/` 作用类似 outputs 目录下的 `_scratch/`).
+
+## 阶段三流程 (脚本组装, 不写 case_data.json)
+
+新工作流: Phase 2 已经把所有结构化数据 in-place Edit 进 `{case_dir}/workflow.json`. Phase 3 直接调 2 个脚本命令, **不需要写 case_data.json** (renderer 在内存把 workflow + source-input + page_title + case_id 组装成 case_data 喂给 build_html).
+
+```bash
+# Step A: lint + 自动 record 新 type 到 type_suggestions.md
+python {spec_dir}/tools/lint-case.py --workflow {case_dir}/workflow.json --case-id {case_id}
+# stdout 报 "type 完整性: N 个提示" 时, 回 Phase 2 Edit workflow.json 补 procedures[i].type_registry, 重跑 lint
+# stdout 报 "已 record M 条新 type" 时, 表示 {spec_name}/taxonomy/type_suggestions.md 已自动同步
+
+# Step B: 渲染 HTML (--source-input 必带, --page-title --case-id 必带)
+python {spec_dir}/tools/render-case.py \
+    --workflow {case_dir}/workflow.json \
+    --source-input {case_input} \
+    --page-title "Case {case_id} · <主题>" \
+    --case-id {case_id} \
+    --out {case_dir}/case-{case_id}-<slug>.html
+# 渲染出的 .html 就是唯一产物 (spec/tools.md §6: .md 已取消, 不要再 Write .md)
+```
+
+**`--source-input` 行为**: renderer 自动从 raw 抽 body_text + 封面图 + 图集兜底填到 case_data.source (内存里). 微信公众号长文走 inline 图 + 封面; 小红书短文走 body + "--- 附图 ---" 末尾追加非封面图. 你**不必手工**复制 raw.body_text — 完全交给 renderer.
+
+`workflow.json` 的契约见 [{spec_name}/format/case-data.schema.json]({spec_name}/format/case-data.schema.json) 里 Procedure 的 definition (顶层 `{{procedures: [{{id, name, purpose, declarations, type_registry?, steps, return_row?}}]}}`). **不要参考其他 `outputs/case-*/` 下任何文件**.
+
+## 其他约束
+
+- 推断补全用 `inferred: true` + `inferred_reason` 标在 IO item 上, 不要静默插入.
+- 完成后用一段话总结: 工序梗概 + 输出文件路径 + 你对 DSL 的关键发现.
+"""
+    blocks: List[Dict[str, Any]] = [{"type": "text", "text": text}]
+    _append_image_blocks(blocks, images)
+    return blocks
+
+
+# ──── Trace 写盘 (outputs/case-N/_trace.md) ───────────────────────────────────
+# 每次 run 把 turn / tool_use / text / result 写到一份 markdown 流水, 实时 append.
+# Ctrl-C 后还能离线 review Agent 走过哪些 turn / 读了哪些文件 / 调了哪些 Bash.
+
+def _fmt_tool_input(name: str, inp: Any) -> str:
+    """tool_use input → 人读 1 行摘要."""
+    if not isinstance(inp, dict):
+        return f"`{repr(inp)[:200]}`"
+    if name == "Read":
+        suffix = ""
+        if inp.get("offset") or inp.get("limit"):
+            suffix = f" (offset={inp.get('offset', 0)}, limit={inp.get('limit', '-')})"
+        return f"`{inp.get('file_path', '')}`{suffix}"
+    if name == "Write":
+        return f"`{inp.get('file_path', '')}` ({len(inp.get('content', '')):,} chars)"
+    if name == "Edit":
+        return f"`{inp.get('file_path', '')}`"
+    if name == "Bash":
+        cmd = inp.get("command", "")
+        if len(cmd) > 200:
+            cmd = cmd[:200] + "..."
+        return f"`{cmd}`"
+    if name == "Grep":
+        return f"pattern=`{inp.get('pattern', '')}` path=`{inp.get('path', '')}`"
+    if name == "Glob":
+        return f"pattern=`{inp.get('pattern', '')}`"
+    if name in ("Task", "Agent"):
+        return f"`{inp.get('description', '')}` [subagent={inp.get('subagent_type', '?')}]"
+    preview = str(inp)
+    return f"`{preview[:200] + '...' if len(preview) > 200 else preview}`"
+
+
+def _trace_banner(trace_path: Path, args, resume_sid, source_path, n_images: int) -> None:
+    """session 起手 banner. Append 模式 — 历次 run 累积在同一 _trace.md."""
+    trace_path.parent.mkdir(parents=True, exist_ok=True)
+    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+    if resume_sid:
+        chunk = (
+            f"\n\n---\n\n## ▶ Resume @ {now}\n\n"
+            f"恢复 session `{resume_sid[:8]}` (case-{args.case_id})\n"
+        )
+    else:
+        chunk = (
+            f"\n\n---\n\n## ▶ Fresh @ {now}\n\n"
+            f"- case: `{args.case_id}`\n"
+            f"- source: `{source_path}`\n"
+            f"- spec: `{getattr(args, 'spec_name', 'spec')}`\n"
+            f"- images: `{n_images}`\n"
+            f"- model: `{args.model}`\n"
+            f"- max_turns: `{args.max_turns}`\n"
+        )
+    with trace_path.open("a", encoding="utf-8") as f:
+        f.write(chunk)
+
+
+def _trace_init(trace_path: Path, sid: str, data: Dict[str, Any]) -> None:
+    """SDK init → 写 session_id / model 到 trace."""
+    line = (
+        f"\n_session={sid[:8]} · model={data.get('model')!r} "
+        f"· apiKeySource={data.get('apiKeySource')!r}_\n"
+    )
+    with trace_path.open("a", encoding="utf-8") as f:
+        f.write(line)
+
+
+def _trace_turn(trace_path: Path, turn: int, msg: Any) -> None:
+    """每个 AssistantMessage → text + tool_use 摘要追加到 trace."""
+    now = datetime.now().strftime("%H:%M:%S")
+    parts = [f"\n\n### Turn {turn} · {now}\n"]
+    texts: List[str] = []
+    tools: List[tuple] = []
+    for block in msg.content:
+        if hasattr(block, "text"):
+            t = block.text.strip()
+            if t:
+                texts.append(t)
+        elif hasattr(block, "name") and hasattr(block, "input"):
+            tools.append((block.name, block.input))
+        # thinking blocks 跳过
+    if texts:
+        for t in texts:
+            for line in t.split("\n"):
+                parts.append(f"> {line}\n" if line else ">\n")
+            parts.append("\n")
+    if tools:
+        for name, inp in tools:
+            parts.append(f"- `{name}` — {_fmt_tool_input(name, inp)}\n")
+    with trace_path.open("a", encoding="utf-8") as f:
+        f.write("".join(parts))
+
+
+def _trace_result(trace_path: Path, msg: Any, elapsed: float,
+                  usage: Dict[str, Any], est_cost: float) -> None:
+    """ResultMessage → final summary 追加到 trace."""
+    now = datetime.now().strftime("%H:%M:%S")
+    sdk_cost = msg.total_cost_usd
+    sdk_cost_str = f"${sdk_cost:.4f}" if sdk_cost is not None else "None (OAuth Max)"
+    chunk = (
+        f"\n\n### ◀ Result · {now}\n\n"
+        f"- subtype: `{msg.subtype}` · is_error: `{msg.is_error}`\n"
+        f"- num_turns: `{msg.num_turns}` · duration: `{msg.duration_ms}ms` · wall: `{elapsed:.1f}s`\n"
+        f"- tokens: in={usage.get('input_tokens', 0):,} "
+        f"out={usage.get('output_tokens', 0):,} "
+        f"cache_w={usage.get('cache_creation_input_tokens', 0):,} "
+        f"cache_r={usage.get('cache_read_input_tokens', 0):,}\n"
+        f"- cost: sdk={sdk_cost_str}, est_if_api=${est_cost:.4f}\n"
+    )
+    with trace_path.open("a", encoding="utf-8") as f:
+        f.write(chunk)
+
+
+# ──── 主流程: 跑 ClaudeSDKClient ──────────────────────────────────────────────
+
+async def run(args: argparse.Namespace) -> None:
+    from claude_agent_sdk import (
+        AssistantMessage,
+        ClaudeAgentOptions,
+        ClaudeSDKClient,
+        ClaudeSDKError,
+        RateLimitEvent,
+        ResultMessage,
+        TextBlock,
+    )
+
+    workdir = Path(args.workdir or DSL_ROOT).resolve()
+    if not workdir.exists():
+        sys.exit(f"❌ workdir not found: {workdir}")
+    source_path = Path(args.source).expanduser().resolve()
+    if not source_path.exists():
+        sys.exit(f"❌ source not found: {source_path}")
+
+    auto_imgs = _images_from_source(source_path)
+    extra_imgs = args.extra_image or []
+    images = auto_imgs + extra_imgs
+
+    # 给 Agent 的路径优先用 workdir 相对路径 (它的 cwd 就是 workdir),
+    # 不在 workdir 内才回落到绝对路径.
+    try:
+        source_for_agent = source_path.relative_to(workdir).as_posix()
+    except ValueError:
+        source_for_agent = str(source_path)
+    # --out-dir 是 outputs/ 下的相对名 (--out-dir newdir → outputs/newdir); 绝对路径原样用.
+    out_dir = _resolve_out_dir(args.out_dir, workdir)
+    out_dir.mkdir(parents=True, exist_ok=True)
+    sid_file = out_dir / ".session_id"
+    # 预创建 sanctioned scratch 目录, 让 Agent 看到就在那, 不用犹豫能不能 mkdir
+    (out_dir / "_scratch").mkdir(exist_ok=True)
+
+    resume_sid = None
+    if args.resume:
+        if not sid_file.exists():
+            sys.exit(f"❌ --resume 但未找到 {sid_file}; 先正常跑一次建立 session")
+        resume_sid = sid_file.read_text(encoding="utf-8").strip() or None
+        if not resume_sid:
+            sys.exit(f"❌ {sid_file} 为空, 无法 resume")
+
+    try:
+        rel_out = out_dir.relative_to(workdir).as_posix()
+    except ValueError:
+        rel_out = out_dir.as_posix()
+
+    if resume_sid:
+        # resume 时不重发图和原始指令 (历史里都有); 只给一段 "接着做" 增量.
+        # 关键: 提醒 Agent 用户可能改过中间产物, 必须 Read 当前磁盘版本.
+        blocks = [{"type": "text", "text": (
+            f"上次中断了, 接续做 case-{args.case_id} 的提取流程.\n\n"
+            f"先 ls {rel_out}/ 看当前已落盘哪些产物;\n"
+            f"用户可能在中断期间编辑过中间产物 (workflow.json, 及 understanding.md 草稿若有) "
+            f"或改过 spec/ 内任何文件 — 务必 Read 这些**当前磁盘版本**, "
+            f"不要凭之前记忆继续. 如发现明显人工修订痕迹, 沿用用户改过的版本.\n\n"
+            f"⚠️ 第二阶段 (归类标注) 由你**自己一趟做完** (见 spec/extraction/phase2-normalize.md): "
+            f"作用/动作/类型 对词表、实质/形式 直接提炼元素点, 用 wf-patch.py 逐字段落盘. "
+            f"**不要**切任务、不要召唤子 Agent (该流程已废弃)."
+        )}]
+    else:
+        blocks = _build_initial_blocks(source_for_agent, args.case_id, args.out_dir, images, workdir, args.spec_name)
+
+    print(f"[setup] workdir       = {workdir}")
+    print(f"[setup] version       = {args.version if args.version else '(default)'}")
+    print(f"[setup] spec dir      = {args.spec_name}/")
+    print(f"[setup] source        = {source_path}")
+    print(f"[setup] → as agent    = {source_for_agent}")
+    print(f"[setup] case_id       = {args.case_id}")
+    print(f"[setup] output dir    = {out_dir}")
+    print(f"[setup] auto images   = {len(auto_imgs)} (from image_url_list)"
+          if not resume_sid else f"[setup] auto images   = -- (resume 跳过)")
+    print(f"[setup] extra images  = {len(extra_imgs)} {extra_imgs if extra_imgs else ''}"
+          if not resume_sid else f"[setup] extra images  = -- (resume 跳过)")
+    print(f"[setup] model         = {args.model}")
+    print(f"[setup] max_turns     = {args.max_turns}")
+    if resume_sid:
+        print(f"[setup] resume        = {resume_sid[:8]} (跳过初始 prompt + 图)")
+    else:
+        print(f"[setup] resume        = no (fresh start)")
+    print(flush=True)
+
+    # 起手写 trace banner. 之后每 turn / result 都会 append 到这个 _trace.md.
+    trace_path = out_dir / "_trace.md"
+    _trace_banner(trace_path, args, resume_sid, source_path, len(images))
+    print(f"[trace] -> {trace_path}", flush=True)
+
+    stderr_buf: List[str] = []
+
+    def _capture_stderr(line: str) -> None:
+        if line:
+            stderr_buf.append(line)
+            print(f"[stderr] {line}", flush=True)
+
+    options = ClaudeAgentOptions(
+        model=args.model,
+        cwd=str(workdir),
+        resume=resume_sid,
+        # 单 Agent 全程跑 (spec/tools.md §7「第二阶段不再用子助手」): Phase 2 归类标注
+        # 由主流程自己一趟做完, 不再切任务 / 召唤 phase-2a·2b 子 Agent, 故不开 Task/Agent.
+        allowed_tools=["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
+        max_turns=args.max_turns,
+        permission_mode="bypassPermissions",
+        setting_sources=[],
+        env={
+            "ANTHROPIC_API_KEY": "",
+            "ANTHROPIC_BASE_URL": "",
+            "ANTHROPIC_AUTH_TOKEN": "",
+        },
+        stderr=_capture_stderr,
+    )
+
+    turn = 0
+    usage: Dict[str, Any] = {}
+    t0 = time.time()
+
+    try:
+        async with ClaudeSDKClient(options=options) as client:
+            async def _input_stream():
+                yield {
+                    "type": "user",
+                    "message": {"role": "user", "content": blocks},
+                    "parent_tool_use_id": None,
+                    "session_id": "default",
+                }
+            await client.query(_input_stream())
+
+            async for msg in client.receive_response():
+                if isinstance(msg, AssistantMessage):
+                    turn += 1
+                    for block in msg.content:
+                        if isinstance(block, TextBlock):
+                            print(f"\n[turn {turn} · text]\n{block.text}\n", flush=True)
+                        elif hasattr(block, "name") and hasattr(block, "input"):
+                            preview = str(block.input)
+                            if len(preview) > 200:
+                                preview = preview[:200] + "..."
+                            print(f"[turn {turn} · tool_use] {block.name}({preview})", flush=True)
+                        elif hasattr(block, "thinking"):
+                            pass  # thinking 太长, 跳过
+                        else:
+                            print(f"[turn {turn} · {type(block).__name__}] {block!r}", flush=True)
+                    _trace_turn(trace_path, turn, msg)
+                elif isinstance(msg, ResultMessage):
+                    if msg.usage:
+                        usage = dict(msg.usage)
+                    elapsed = time.time() - t0
+                    sdk_cost = msg.total_cost_usd
+                    sdk_cost_str = (
+                        f"${sdk_cost:.4f}" if sdk_cost is not None
+                        else "None (OAuth Max — not metered as $)"
+                    )
+                    est_cost = _estimate_cost_usd(usage)
+                    print(
+                        f"\n[result] subtype={msg.subtype} is_error={msg.is_error} "
+                        f"turns={msg.num_turns} duration={msg.duration_ms}ms wall={elapsed:.1f}s\n"
+                        f"  tokens: in={usage.get('input_tokens', 0):,} "
+                        f"out={usage.get('output_tokens', 0):,} "
+                        f"cache_w={usage.get('cache_creation_input_tokens', 0):,} "
+                        f"cache_r={usage.get('cache_read_input_tokens', 0):,}\n"
+                        f"  cost  : sdk={sdk_cost_str}, est_if_api=${est_cost:.4f} "
+                        f"(Sonnet 4.6 价目)",
+                        flush=True,
+                    )
+                    _trace_result(trace_path, msg, elapsed, usage, est_cost)
+                    if msg.is_error:
+                        print(f"❌ result is_error=True", file=sys.stderr)
+                        sys.exit(2)
+                elif isinstance(msg, RateLimitEvent):
+                    info = getattr(msg, "rate_limit_info", None)
+                    info_status = getattr(info, "status", None) if info else None
+                    if info_status == "allowed_warning":
+                        print(f"⚠️  [rate_limit_warning] Max 订阅 5h 窗口余额较少, `claude /status` 看余量", file=sys.stderr)
+                    elif info_status and info_status not in ("allowed", "allowed_warning"):
+                        print(f"❌ [rate_limit_blocked] {info_status!r} — Max 订阅 5h 窗口已耗尽, `claude /status` 看余量", file=sys.stderr)
+                        sys.exit(3)
+                else:
+                    name = type(msg).__name__
+                    if name == "SystemMessage":
+                        data = getattr(msg, "data", {}) or {}
+                        subtype = getattr(msg, "subtype", "?")
+                        if subtype == "init":
+                            sid = data.get('session_id', '') or ''
+                            if sid:
+                                # 早写: 一拿到 sid 就落盘, Ctrl-C 再早也能 resume
+                                sid_file.write_text(sid, encoding="utf-8")
+                                _trace_init(trace_path, sid, data)
+                            print(
+                                f"[init] model={data.get('model')!r} "
+                                f"apiKeySource={data.get('apiKeySource')!r} "
+                                f"session={sid[:8]}",
+                                flush=True,
+                            )
+
+    except ClaudeSDKError as e:
+        tail = "\n".join(stderr_buf[-20:])
+        print(
+            f"❌ SDK error: {type(e).__name__}: {e}\n"
+            f"--- CLI stderr (last 20 lines) ---\n{tail}",
+            file=sys.stderr,
+        )
+        sys.exit(1)
+
+
+# ──── CLI ─────────────────────────────────────────────────────────────────────
+
+def _parse_args() -> argparse.Namespace:
+    p = argparse.ArgumentParser(
+        description="跑 procedure-dsl 提取流程 (Claude Agent SDK, OAuth Max)",
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        epilog=__doc__,
+    )
+    p.add_argument("source", help="原始 post 文件 (input/case-N-raw.json; 也接受 .md/.txt)")
+    p.add_argument("--extra-image", action="append", default=[],
+                   help="额外配图: 本地路径 or http(s) URL. 加在 image_url_list "
+                        "自动抽出的图后面. 可多次传.")
+    p.add_argument("--out-dir", type=str, required=True,
+                   help="输出工作目录名, 落在 outputs/ 下. e.g. --out-dir case-5-newflow → 实际 outputs/case-5-newflow/ . "
+                        "Agent 所有产物 (understanding.md / workflow.json / case-X.html / .md) 都落在这. "
+                        "case_id 自动从 basename 推 (e.g. --out-dir case-5-newflow → case_id='5-newflow'). "
+                        "已带 outputs/ 前缀会被容忍 (不重复嵌套); 传绝对路径则原样用.")
+    p.add_argument("--model", default="claude-sonnet-4-6",
+                   help="Claude 模型名 (default: claude-sonnet-4-6)")
+    p.add_argument("--workdir", default=None,
+                   help=f"SDK cwd. 默认 {DSL_ROOT} (即本脚本所在 procedure-dsl/)")
+    p.add_argument("--version", default=None, metavar="SUFFIX",
+                   help="spec 版本: 跑 workdir 下的 spec-<SUFFIX>/ 目录. "
+                        "e.g. --version backup → spec-backup/, --version test → spec-test/. "
+                        "不传则默认 spec/.")
+    p.add_argument("--max-turns", type=int, default=300,
+                   help="Agent 最大回合数 (default: 300, 跑完整三阶段 + lint 留足余量)")
+    p.add_argument("--resume", action="store_true",
+                   help="恢复中断的 session: 从 outputs/case-N/.session_id 读 sid, "
+                        "Agent 拿上次完整历史接着跑. 中断期间可手改任何中间产物, "
+                        "Agent 会重新 Read 磁盘版本而不是凭记忆.")
+    p.add_argument("--max-retries", type=int, default=3,
+                   help="Stream idle / 临时错误自动 --resume 重试次数 (default: 3). "
+                        "退避 10s/20s/40s, 不重试 RateLimit (exit 3) 和 Ctrl-C.")
+    return p.parse_args()
+
+
+def main() -> None:
+    # Windows 默认控制台编码 (cp1252/gbk) 撑不住 spec.md / Agent 输出里的中文 +
+    # emoji, 第一次打印就 UnicodeEncodeError. 在 main 入口统一切到 UTF-8.
+    for stream in (sys.stdout, sys.stderr):
+        if hasattr(stream, "reconfigure"):
+            stream.reconfigure(encoding="utf-8", errors="replace")
+    logging.basicConfig(level=logging.WARNING)
+    args = _parse_args()
+    # 注入派生属性: case_id 自动从 --out-dir basename 算 (去掉 case- 前缀).
+    # 下游 prompt / banner / type_suggestions record 都用这个 args.case_id.
+    args.case_id = _derive_case_id(args.out_dir)
+    # spec 目录名: --version backup → "spec-backup", 不传 → "spec".
+    args.spec_name = "spec" if not args.version else f"spec-{args.version}"
+
+    # ──── 自动重试循环 ──────────────────────────────────────────────────────
+    # exit code 约定:
+    #   0  = 成功
+    #   1  = ClaudeSDKError (含 setup 错, 一般非 transient, 不重试)
+    #   2  = ResultMessage is_error=True (含 stream idle timeout, **可重试**)
+    #   3  = RateLimitEvent (配额耗尽, 不重试 — 等 5h window 滑动)
+    #   130 = KeyboardInterrupt (用户主动中断, 不重试)
+    # 重试退避: 10s → 20s → 40s, 都在 prompt cache TTL (5min) 内
+    max_retries = args.max_retries
+    workdir_check = Path(args.workdir or DSL_ROOT).resolve()
+    out_dir_check = Path(args.out_dir)
+    sid_file_check = (out_dir_check if out_dir_check.is_absolute() else (workdir_check / out_dir_check)).resolve() / ".session_id"
+
+    # --version 选定的 spec 目录必须存在. 在进重试循环前 fail-fast:
+    # 注意 run() 里 sys.exit(字符串) 的消息会被下面 except SystemExit 吞掉,
+    # 所以这里在 main 早校验, 直接 print 到 stderr 再 exit(1).
+    spec_dir_check = workdir_check / args.spec_name
+    if not spec_dir_check.is_dir():
+        avail = sorted(p.name for p in workdir_check.glob("spec*") if p.is_dir())
+        print(
+            f"❌ spec dir not found: {spec_dir_check}\n"
+            f"   (--version {args.version!r} → 期望目录 '{args.spec_name}/')\n"
+            f"   可用版本: {avail}",
+            file=sys.stderr,
+        )
+        sys.exit(1)
+
+    for attempt in range(max_retries + 1):
+        try:
+            asyncio.run(run(args))
+            return  # 成功完成
+        except KeyboardInterrupt:
+            # session_id 在 init 时就落盘了, 已写到磁盘的产物全部保留.
+            # 加 --resume 重启即可接着跑.
+            print(
+                f"\n⚠️  中断 (Ctrl-C). {args.out_dir}/ 产物已保留.\n"
+                f"   恢复: python run_procedure_dsl.py {args.source} "
+                f"--out-dir {args.out_dir} --resume",
+                file=sys.stderr,
+            )
+            sys.exit(130)
+        except SystemExit as e:
+            code = e.code if isinstance(e.code, int) else (1 if e.code else 0)
+            # exit 2 = is_error (stream timeout 之类 transient), 可重试
+            if code == 2 and attempt < max_retries:
+                wait_s = 10 * (2 ** attempt)   # 10s / 20s / 40s
+                print(
+                    f"\n⚠️  attempt {attempt+1}/{max_retries+1} exit={code} "
+                    f"(可能 stream idle timeout). 等 {wait_s}s 后 --resume 重试...",
+                    file=sys.stderr,
+                )
+                time.sleep(wait_s)
+                # 强制 --resume (前提是 session_id 已落盘 — init 阶段就写了, 通常都在)
+                if sid_file_check.exists():
+                    args.resume = True
+                else:
+                    print(f"⚠️  {sid_file_check} 不存在, fresh restart 而非 resume",
+                          file=sys.stderr)
+                continue
+            # 不重试: exit 0 (成功) / exit 1 (SDK 错) / exit 3 (RateLimit) / 用尽 retries
+            sys.exit(code)
+
+    # 用尽 max_retries 后还到这里 (按 for-else 语义实际不会, 但保险)
+    print(f"\n❌ 用尽 {max_retries} 次重试.", file=sys.stderr)
+    sys.exit(2)
+
+
+if __name__ == "__main__":
+    main()

File diff ditekan karena terlalu besar
+ 294 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/README.md


+ 268 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/format/case-data.schema.json

@@ -0,0 +1,268 @@
+{
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
+  "$id": "https://procedure-dsl/spec/format/case-data.schema.json",
+  "title": "Procedure DSL · case_data",
+  "description": "Canonical structure consumed by spec/tools/renderer.build_html(case_data) -> str. 一篇 case 可含 1 ~ N 个独立工序 (procedures), 共享同一份 source 原帖. 单工序 case 也用 procedures 数组长度 1 的形式 — schema 不区分.",
+  "type": "object",
+  "required": [
+    "page_title",
+    "source",
+    "procedures"
+  ],
+  "additionalProperties": false,
+  "properties": {
+    "page_title": {
+      "type": "string",
+      "description": "HTML <title> + <h1>. e.g. 'Case 5 · 产品宣传图 AI 工作流可视化'"
+    },
+    "case_id": {
+      "type": ["integer", "string", "null"],
+      "description": "Optional case identifier shown in UI badge."
+    },
+    "source": {
+      "$ref": "#/$defs/Source",
+      "description": "case-level 原帖信息, 跨所有 procedures 共享 (一篇文章对应一份 source)."
+    },
+    "procedures": {
+      "type": "array",
+      "minItems": 1,
+      "description": "一篇 case 包含的工序数组. 多工序场景 (e.g. case-5 '简单工作流 + 进阶工作流 + 附加案例'). 单工序 case 也用长度 1 数组. 每个 procedure 独立含 declarations / steps / type_registry / return_row.",
+      "items": { "$ref": "#/$defs/Procedure" }
+    }
+  },
+
+  "$defs": {
+
+    "Procedure": {
+      "type": "object",
+      "description": "一个独立工序: 工序头部 (name/purpose/...) + declare 块 + 步骤 + 返回行. 一个 procedure 内的 type_registry 是该工序的 case-specific 类型扩展.",
+      "required": ["id", "name", "purpose", "category", "platform", "author", "declarations", "steps"],
+      "additionalProperties": false,
+      "properties": {
+        "id":       { "type": "string", "description": "procedure 局部 id (单 case 内唯一). e.g. 'p1' / 'p1-simple' / 'p2-advanced'." },
+        "name":     { "type": "string", "description": "工序名称, e.g. '简单工作流: 一步生成'." },
+        "purpose":  { "type": "string", "description": "One-sentence intent (该工序在做什么)." },
+        "category": { "type": "string", "description": "Top-level taxonomy, e.g. '产物创造'." },
+        "platform": { "type": "string", "description": "原帖来源 platform; 通常跟 case-level source.platform 一致." },
+        "author":   { "type": "string", "description": "原作者; 通常跟 case-level source.author 一致." },
+        "declarations": { "$ref": "#/$defs/Declarations" },
+        "type_registry": {
+          "type": "object",
+          "description": "Per-procedure case-specific type entries; 渲染期跟 spec/taxonomy/type.json 的 stdlib 叶子合并 — case 项覆盖 stdlib 项. 跨工序共享的 case-specific type 可在多个 procedure 各自声明 (允许冗余).",
+          "additionalProperties": { "$ref": "#/$defs/TypeRegistryEntry" }
+        },
+        "steps": {
+          "type": "array",
+          "description": "工序的步骤数组, 按执行顺序排. block/step 在顶层; nested 子项 kind:nested + group 指向父 block id.",
+          "items": { "$ref": "#/$defs/Step" }
+        },
+        "return_row": { "$ref": "#/$defs/ReturnRow" }
+      }
+    },
+
+    "Declarations": {
+      "type": "object",
+      "description": "工序的声明: declared inputs / resources / return type. 渲染成 declare 折叠块.",
+      "required": ["inputs", "resources", "returns"],
+      "additionalProperties": false,
+      "properties": {
+        "inputs": {
+          "type": "array",
+          "items": { "$ref": "#/$defs/DeclareItem" },
+          "description": "Caller-provided inputs to the procedure."
+        },
+        "resources": {
+          "type": "array",
+          "items": { "$ref": "#/$defs/DeclareItem" },
+          "description": "Long-lived resources (libraries, knowledge bases) read or written across runs."
+        },
+        "returns": { "$ref": "#/$defs/DeclareReturn" }
+      }
+    },
+
+    "DeclareItem": {
+      "type": "object",
+      "required": ["type", "name"],
+      "additionalProperties": false,
+      "properties": {
+        "type":    { "type": "string", "description": "Type leaf (§A.3) or case-extended type." },
+        "name":    { "type": "string" },
+        "default": { "type": "string", "description": "Optional default value/template." },
+        "desc":    { "type": "string", "description": "Optional human description." }
+      }
+    },
+
+    "DeclareReturn": {
+      "type": "object",
+      "required": ["type"],
+      "additionalProperties": false,
+      "properties": {
+        "type": { "type": "string" },
+        "note": { "type": "string", "description": "e.g. 'extends 视频成品 (序列关系)'." }
+      }
+    },
+
+    "Source": {
+      "type": "object",
+      "description": "case-level 原帖信息. 渲染成 foldable 折叠块 (default closed). 跨所有 procedures 共享.",
+      "required": ["platform", "author", "date", "title", "excerpt"],
+      "additionalProperties": false,
+      "properties": {
+        "platform":    { "type": "string" },
+        "author":      { "type": "string" },
+        "date":        { "type": "string", "description": "Free-text date, e.g. '2026 上半年'." },
+        "url":         { "type": ["string", "null"], "description": "原帖 URL; 没有干净 URL 时填 null 或省略 (不强制 uri 格式)." },
+        "title":       { "type": "string" },
+        "excerpt":     { "type": "string", "description": "1-2 sentence pipeline summary." },
+        "body_text":   { "type": "string", "description": "Optional full body of the source article." },
+        "cover_image": { "type": "string", "description": "Optional cover image URL." }
+      }
+    },
+
+    "TypeRegistryEntry": {
+      "type": "object",
+      "description": "Case-specific 类型定义 (procedures[*].type_registry). 桥接到一个 stdlib 叶子 + 人类可读描述.",
+      "required": ["extends", "desc"],
+      "additionalProperties": false,
+      "properties": {
+        "extends": { "type": "string", "description": "桥接到的 stdlib 叶子名 (spec/taxonomy/type.json $leaves 之一)." },
+        "desc":    { "type": "string", "description": "case-specific 类型的人类可读说明 (renderer drawer + type_suggestions 用)." }
+      }
+    },
+
+    "Step": {
+      "type": "object",
+      "description": "One row group in the 14-column procedure table. Renders to N <tr> where N = max(len(inputs), len(outputs), 1). effect/action MUST hit canonical leaves per spec §A; substance/form are STEP-LEVEL taxonomy paths (whole step's content, not per-IO). kind=block is a control container (effect/action/substance/form may be omitted; carries intent + via='-' + io); kind=nested/step are execution steps.",
+      "required": ["id", "kind", "via", "inputs", "outputs", "intent"],
+      "additionalProperties": false,
+      "properties": {
+        "id": {
+          "type": "string",
+          "pattern": "^s\\d+(\\.\\d+)*$",
+          "description": "Step id. Plain step / block / nested use 's' prefix (block children dotted, e.g. 's3.1')."
+        },
+        "kind": {
+          "enum": ["step", "block", "nested"],
+          "description": "step=plain; block=control-flow parent (grouping container); nested=child of a block."
+        },
+        "group": {
+          "type": "string",
+          "description": "When kind=nested, the parent block's id (e.g. 's3')."
+        },
+        "effect": {
+          "enum": [
+            "预处理", "主体生成", "装配", "后期",
+            "工艺规约", "预准备", "配套伴生", "检验", "交付"
+          ],
+          "description": "§A.1 L3 leaf. Required on step/nested — non-leaf = extraction error."
+        },
+        "substance": {
+          "type": ["string", "array", "null"],
+          "items": { "type": "string" },
+          "description": "STEP-LEVEL. What this step's content IS (理念 vs 表象 layer). Path from `分类库导出_实质_*.json`. Single path string, array of path strings, or null."
+        },
+        "form": {
+          "type": ["string", "array", "null"],
+          "items": { "type": "string" },
+          "description": "STEP-LEVEL. How this step's content is PRESENTED (呈现 vs 架构 layer). Path from `分类库导出_形式_*.json`. Single path string, array of path strings, or null."
+        },
+        "via": {
+          "type": "string",
+          "description": "Canonical L1 tool name (manus / nano_banana_pro / human / <llm-agent>) or generic placeholder for unspecified tools ('(AI 生图工具)'). Use '-' for control-flow blocks."
+        },
+        "action": {
+          "type": "string",
+          "pattern": "^[^/]+(/[^/]+)*$",
+          "description": "§A.2 path, e.g. '生成/元素生成', '提取/化学提取/反推'."
+        },
+        "directive": {
+          "type": "string",
+          "description": "字面 prompt 文本 — 真正喂给工具的 prompt 字符串. 人工/控制流 step 无 prompt 时省略或空串."
+        },
+        "inputs":  {
+          "type": "array",
+          "items": { "$ref": "#/$defs/IOItem" }
+        },
+        "outputs": {
+          "type": "array",
+          "items": { "$ref": "#/$defs/IOItem" }
+        },
+        "intent": {
+          "type": "string",
+          "description": "≤ ~25 chars natural-language sentence. Tokens `{kind:value}` with kind ∈ {effect, via, act, in-type, out-type}. NEVER use variable-name tokens, NEVER use 'X: Y → Z' pseudo-code."
+        },
+        "focus": {
+          "type": "array",
+          "items": { "type": "string" },
+          "description": "Column-cell keys to highlight on this row. Format: bare key for step-level cells ('via', 'action', 'effect', 'substance', 'form', 'idx', 'intent'), or '<col>-<io_index>' for IO cells ('in-type-0', 'out-type-1', etc.)."
+        }
+      },
+
+      "allOf": [
+        {
+          "if": { "properties": { "kind": { "enum": ["step", "nested"] } } },
+          "then": { "required": ["effect", "action"] }
+        },
+        {
+          "if": { "properties": { "kind": { "const": "nested" } } },
+          "then": { "required": ["group"] }
+        }
+      ]
+    },
+
+    "IOItem": {
+      "type": "object",
+      "description": "One row in inputs[] or outputs[]. Outputs carry an `id` (the 1:1 reference handle other steps point to); inputs reference an upstream output's id in their anchor.",
+      "required": ["type", "value", "anchor"],
+      "additionalProperties": false,
+      "properties": {
+        "id": {
+          "type": "string",
+          "description": "Short machine handle, unique within the procedure. REQUIRED on outputs (the reference target). Convention: 's<step>o<n>' (e.g. 's2o1'); single-output step may use 's<step>'. Inputs omit it. NOT a display column — surfaces only inside anchors."
+        },
+        "type": {
+          "type": "string",
+          "description": "§A.3 leaf or case-extended type name."
+        },
+        "value": {
+          "type": "string",
+          "description": "Content itself. Text data: full prose, no wrappers. Non-text data: '<整段描述>' (the whole description angle-bracketed). NEVER metadata ('[图 N 显示]', '原文: ...') or upstream refs ('← s2o1' — those go in anchor)."
+        },
+        "anchor": {
+          "type": "string",
+          "description": "Data-flow link by id. Inputs: upstream ref ('← 工序输入', '← s2o1' 指向某 output 的 id, '← s2o1[i]' 容器索引). Outputs: downstream destination ('→ s5', '→ 视频片段列表.追加', '→ 返回 X')."
+        },
+        "inferred": {
+          "type": "boolean",
+          "description": "True when this whole IO item was filled by 工艺补全 (not in source material). Renderer dyes the row's data-flow cells."
+        },
+        "inferred_reason": {
+          "type": "string",
+          "description": "REQUIRED when inferred=true. Shown on hover."
+        }
+      },
+      "if": {
+        "required": ["inferred"],
+        "properties": { "inferred": { "const": true } }
+      },
+      "then": { "required": ["inferred_reason"] }
+    },
+
+    "ReturnRow": {
+      "type": "object",
+      "description": "Bottom row of the table announcing what the procedure returns.",
+      "required": ["arrow", "text"],
+      "additionalProperties": false,
+      "properties": {
+        "arrow": {
+          "type": "string",
+          "description": "Usually '↩'."
+        },
+        "text": {
+          "type": "string",
+          "description": "May contain inline HTML fragments (chip / name / em spans) — emitted verbatim into a colspan cell."
+        }
+      }
+    }
+  }
+}

+ 402 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/action.json

@@ -0,0 +1,402 @@
+{
+  "$comment": "动作 字典树 (新结构: 获取/提取/生成/修改/存储). chip data-prefix=\"动作\". action 字段值用 根→叶 路径 (e.g. 提取/化学提取/解构). 单一来源, agent Phase 2 读. $control 是控制流类型 (与内容动作正交).",
+  "$kind": "taxonomy",
+  "$dimension": "动作",
+  "$field": "action",
+  "$path_separator": "/",
+  "$control": [
+    "并行",
+    "遍历",
+    "分支",
+    "请求",
+    "等待"
+  ],
+  "最终分类树": [
+    {
+      "分类名称": "获取",
+      "分类说明": "把已经存在的、完整的对象原样取来作为素材、参考或依据使用——动作本身不创造、不拆解、不改造对象。典型:检索 / 下载 / 调取 / 上传 / 拍摄 / 录音 / 键入 / 选取。判别口诀:输入与输出指向同一个完整对象(或对象集合),只是发生了'转移 / 引用',没有从内部抽出局部信息,也没有改变其形态。与'提取'的边界:获取拿到的是整体本身(如把一张参考图拿进工作流),提取拿到的是整体的派生物(如从这张图反推出文字 prompt)。与'生成'的边界:获取的对象是预先存在的,生成的对象是当前动作创造出来的新产物。\n\n【L2 切分维度】按'对象的来源位格'切分——搜索(工序外·公共域)/ 查询(工序外·私有·预存)/ 录入(工序外·私有·当场)/ 引用(工序内·自产)。一个获取动作的对象只可能位于这 4 个位置之一,MECE 完备。L2 本身只承担'来源位格'的目录定位,不作为 actions[] 取值。\n\n【L3 切分维度】每个 L2 内按'具体动作动词'切分。L3 节点直接作为 actions[] 字段的规范取值——本树即动作词典,不用'直接元素'承载同义词,所有近义动词在 L3 的分类说明中显式标注规范化目标。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "搜索",
+          "分类说明": "对象来自工序之外、面向公众开放的资源——互联网、公开素材库、搜索引擎、公共知识库、平台预设 / 模板、开源模型 / LoRA。判别:所有权 = 公共,任何人可访问。与'查询'的边界:搜索面向公共域,查询面向创作者 / 团队的私有积累(所有权差异)。与'录入'的边界:搜索是从公共域取来(创作者并未持有),录入是用户从自己手上当场提供。与'引用'的边界:搜索的对象来自工序外部,引用的对象来自工序内部的自产中间件。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "检索",
+              "分类说明": "输入查询 / 关键词 / 筛选条件 / 问题,从公共域里主动找出对象。涵盖:搜索引擎检索、库内关键词查询、对 LLM 的提问式知识获取、无明确 query 的浏览翻找(本质都是'在公共域里找')。与'下载'的边界:检索强调'查找定位'的过程(不知道精确位置),下载是'已知地址直接拿'(无需查询过程)。同义动作(写 actions[] 时统一规范为「检索」):查找 / 浏览 / 翻找 / 搜寻 / 问答式查询(对 LLM)。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "下载",
+              "分类说明": "已知精确地址(URL、ID、文件路径、API endpoint),直接获取指定对象。涵盖:URL 下载、API 拉取、网络抓取、按链接导入。与'检索'的边界:检索需要查询过程(不知精确位置),下载是已知位置直接取。与 L1'提取'的边界:下载是文件级整体获取(拿到完整对象本身),提取是从对象内部抽出局部 / 派生信息(拿到对象的一片或派生物)。同义动作(写 actions[] 时统一规范为「下载」):拉取 / 抓取 / 导入 / URL 拉取 / API 拉取。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "查询",
+          "分类说明": "对象来自工序之外、创作者或团队过去预存的私有资源——自建提示词库、个人素材库、团队成品库、自训风格 LoRA、参数预设、过去的成品。判别:所有权 = 私有 + 先于本次工序就已存在。与'搜索'的边界:查询走私有积累(创作者 / 团队专属),搜索走公共域。与'录入'的边界:查询的对象是预存的(先于本次工序),录入的对象是当下提供的(为本次工序专门接入)。与'引用'的边界:查询的对象在本次工序开始前就已存在于私库,引用的对象由本次工序内部前序步骤产出。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "调取",
+              "分类说明": "取用为复用目的而预存的'零件级'私有资产——这些资产以可被反复调取的单件形态存在。涵盖:自建 prompt 库的提示词、自训 LoRA / Embedding / 参数预设、私库素材(单件参考图 / 单段文案)、本地模型权重加载、个人收藏夹里的素材。与'检索'的边界:调取走的是已知地址直接拿(私库内单件资产有明确 ID / 路径),检索是面向公共域的查找定位过程。与 L1'修改'的边界:调取只是把已有资产'取来用'(对象不变),修改要在已有对象上做改动。同义动作(写 actions[] 时统一规范为「调取」):调用 / 复用 / 加载 / 引用(私库语境)/ 套用(私库模板 / 预设)。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "录入",
+          "分类说明": "对象来自用户 / 创作者在本次工序里当下提供的素材——为这次工序专门接入,不属于过去的预存积累。判别:素材的'接入时点'是本次工序开始或进行中(而非更早预存)。与'查询'的边界:录入是为本次工序专门提供(即使来自用户本地相册),查询取的是创作者过去就有的、可反复调用的私有库资产。与'搜索'的边界:来源是用户 / 创作者自己(私有),不是公共域。与'引用'的边界:录入是工序外的人为输入(用户从工序外送进来),引用是工序内的前序产物(DAG 内自循环)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "上传",
+              "分类说明": "用户提供'工序前就已存在'的既有素材——从设备本地、剪贴板等已有内容里拿出来给到工序。涵盖:本地文件上传、拖拽文件、粘贴既有内容(剪贴板里复制好的图 / 文 / 段落)、从本地相册选图。与'拍摄 / 录音 / 键入'的边界:上传的素材在用户提供时已经存在(既有),非现场制作。与'选取'(引用-工序内)的边界:上传是从工序外送入既有素材,选取是从工序内前序候选中挑选。同义动作(写 actions[] 时统一规范为「上传」):导入(本地)/ 粘贴 / 拖拽 / 上送 / 文件添加。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "拍摄",
+              "分类说明": "用户在工序中现场视觉捕获或产出图像 / 视频素材。涵盖:实时拍照、现场录像、屏幕录制(录自己的操作演示)、手绘 / 速写 / 涂鸦草图(现场画的简笔图也算'现场视觉产出')。与'上传'的边界:拍摄是现场制作(不是从既有里拿),上传是从既有里拿。与'录音 / 键入'的边界:输出形态是图像 / 视频。同义动作(写 actions[] 时统一规范为「拍摄」):录像 / 录屏(自己的)/ 手绘。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "录音",
+              "分类说明": "用户现场进行音频捕获或产出。涵盖:现场录音、口述录入、即兴配音、现场录歌。与'拍摄 / 键入'的边界:输出形态是音频。与'上传'的边界:现场录制,非既有音频文件提供。同义动作(写 actions[] 时统一规范为「录音」):录口述 / 配音录制。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "键入",
+              "分类说明": "用户现场进行文本或结构化参数录入——通过键盘、滑块、表单、选项控件等向工序输入文本或参数。涵盖:打字输入 prompt / 描述 / 文案 / 标题、调参(拖滑块 / 选下拉 / 勾选项)、表单填写。与'拍摄 / 录音'的边界:输出形态是文本或结构化参数。与'上传'的边界:现场敲入,非粘贴既有大段文本(粘贴既有归 上传)。同义动作(写 actions[] 时统一规范为「键入」):输入 / 调参 / 填写。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "引用",
+          "分类说明": "对象来自同一工序内已完成步骤的输出,被后续步骤再次拿来使用——来源是 DAG 内部,对象是工序自产的中间产物或前序成品。判别:source_id 指向的是同一工序内某个 outputs[*].id(而不是 init_input_*)。与'搜索 / 查询 / 录入'的边界:前三者来源都是工序外部(外取),引用来源是工序自身(内引)。与 L1'提取'的边界:引用拿到的是前序输出的整体本身(原样转交),提取是从前序输出里抽出局部 / 派生信息。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "选取",
+              "分类说明": "从前序步骤产生的多个候选对象中挑选一个或若干个进入下一步。涵盖:从模型出的多张候选图里挑、从生成的多个 prompt 候选里选、从多个分镜方案里取一个、从批量生成结果里筛优。判别口诀:必有'多候选 → 挑选'的过程,候选来自同一工序内的前序步骤;如果只是无差别地引用前序唯一输出(无挑选),不归选取。与'调取'的边界:选取的对象来源是工序内自产的候选池(DAG 内),调取的对象来源是工序外的私有库。与'上传'的边界:选取从工序内候选池里挑,上传从工序外(设备本地 / 剪贴板)拿既有素材。同义动作(写 actions[] 时统一规范为「选取」):挑选 / 筛选 / 评选 / 优选 / 圈选(多候选场景)。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "提取",
+      "分类说明": "从一个已有对象中抽出局部内容、属性、特征或派生信息——动作的输入是完整对象,输出是这个对象的'派生物'(描述、标签、文字、结构化数据、局部区域、轮廓、关键帧等)。典型:反推 / 识别 / OCR / 提取 / 抽取 / 分割 / 解析。判别口诀:输出在'形态'或'粒度'上不等同于输入——例如从图反推出文本 prompt(形态变了)、从图中识别物体名称(粒度变了)、从画面切出主体蒙版(粒度变了)。与'获取'的边界:获取得到的是整体本身,提取得到的是整体的派生物。与'修改'的边界:提取的输出与输入不是'同类对象的改前/改后',而是'整体与它的派生物'。\n\n【本质】提取是'信息由多到少'的压缩动作——从一个完整对象里减信息、得到一个更小的派生产物。这种压缩有两条不同的实现路径,对应 L2 切分。\n\n【L2 切分维度】按'输出与原对象的关系'切分——实体片段(输出是原对象的实体一片,能在原对象里指出来)/ 派生信息(输出是关于原对象的派生信息,原对象里指不出来)。一个提取动作的输出只可能位于这 2 类之一,MECE 完备。\n\n【L3 切分维度】每个 L2 内按'具体动作动词'切分。L3 节点直接作为 actions[] 字段的规范取值——本树即动作词典,不用'直接元素'承载同义词,所有近义动词在 L3 的分类说明中显式标注规范化目标。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "物理提取",
+          "分类说明": "输出是原对象的实体片段——能在原对象里直接指出'就是这一块',输出与输入同质且是其物理子集。判别口诀:能不能在原对象里圈出输出对应的那部分(地理 / 时间 / 结构上的子区域)?能 = 实体片段。与'派生信息'的边界:实体片段的输出是原对象的'一片'(同质、可指认),派生信息的输出是关于原对象的'描述 / 特征 / 分析'(异质、原对象里指不出来)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "裁切",
+              "分类说明": "按几何区域、时间区间或位置索引等明确规则把原对象的某一块切出来——切的边界由规则定义,不依赖语义判断。涵盖:矩形 / 自由形状裁剪、按时间轴截取视频 / 音频片段、按段落 / 句子位置取文本片段。与'抠取'的边界:裁切的边界是规则定义的几何区域(不需要理解内容),抠取的边界是语义边界(需要识别对象轮廓)。与'抽帧'(时序场景)的边界:裁切按规则切'连续段',抽帧按重要性抽'离散关键点'。同义动作(写 actions[] 时统一规范为「裁切」):裁剪 / 截取片段 / 切片 / 取段。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "抠取",
+              "分类说明": "按语义边界把特定对象 / 组件从原对象中切出——切的边界由对象本身的形状 / 层次 / 结构决定,需要识别后再切。涵盖:抠图主体(按对象轮廓切)、人物 / 物体分割、拆 PSD 图层(按图层结构切)、demux 音视频轨道(按轨道结构切)。与'裁切'的边界:抠取按对象语义切,裁切按几何规则切。同义动作(写 actions[] 时统一规范为「抠取」):分割 / 抠图 / 拆图层 / 拆轨道。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "抽帧",
+              "分类说明": "从时序媒体(视频 / 音频 / 动画)中抽出离散的关键时刻或代表性片段——抽出来的每一帧 / 段都是原时序的一个截面。涵盖:视频关键帧、代表性时刻、典型片段、采样帧。与'裁切'(时间区间切)的边界:裁切是按规则切'连续段',抽帧是按重要性抽'离散关键点'。同义动作(写 actions[] 时统一规范为「抽帧」):取关键帧 / 采样 / 取代表帧。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "化学提取",
+          "分类说明": "输出是关于原对象的派生信息——原对象里直接指不出来,是从原对象推算 / 解读 / 提炼出来的派生产物。判别口诀:能不能在原对象里圈出输出对应的那部分?不能 = 派生信息。涵盖:表层显式信息的读取(识别)、深层隐含信息的推理(反推:风格 / 情感 / 意图 / 深度 / 姿态等)、内部组成方式的结构化拆解(解构:章节 / 框架 / 要点 / 摘要)。与'实体片段'的边界:派生信息的输出与输入异质(图 → 文 / 数 / 标签 / 表征图),不是原对象的物理子集。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "识别",
+              "分类说明": "读取原对象表层显式存在、可直接观察到的信息——把眼睛能看到、耳朵能听到的东西转成可处理的标签 / 文字 / 数据。涵盖:OCR 文字识别、物体识别(detection + classification)、人脸识别、场景识别、语音转文字、命名实体识别(NER)。与'反推'的边界:识别处理的是表层显式信息(信息就在眼前,只是换种形态),反推处理的是深层隐含信息(需要推理才能得到)。同义动作(写 actions[] 时统一规范为「识别」):检测 / OCR / 转录 / 标注。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "反推",
+              "分类说明": "推理出原对象深层隐含、不可直接观察的信息——需要'从结果推回原因 / 构成'的推理过程。涵盖两大类:(1)语义反推:反推 prompt、风格分析、情感分析、意图推断、创作手法推断;(2)结构表征反推:depth map / canny 边缘 / normal map / pose 骨架 / segmentation mask 等 ControlNet 类预处理(这些 map 都不在原图直接可见,是从 RGB 推算出来的隐含结构)。与'识别'的边界:识别读表层显式(图里的字、物体),反推推深层隐含(图的风格、深度、生成原因)。与'解构'的边界:反推推理'隐含的属性 / 原因 / 表征'(风格 / 情感 / depth 结构),解构分析'显式的内部组成方式'(层级 / 框架)。同义动作(写 actions[] 时统一规范为「反推」):推断 / 分析 / 预处理(ControlNet 类)/ 估计(深度 / 姿态)/ 风格分析 / 情感分析。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "解构",
+              "分类说明": "系统性地把原对象拆解成结构化的层级分析——输出是关于原对象内部组成方式的'结构描述',而不是原对象本身的物理碎片。涵盖:拆剧情结构(场景 / 冲突 / 转折)、拆构图层级(前景 / 中景 / 背景,三分法 / 对称)、拆文章章节框架(引言 / 论点 / 论据 / 结论)、拆角色构成(服饰 / 发型 / 姿态 / 表情)、内容浓缩与提炼(摘要 / 要点提炼 / 核心信息抽取)。与'抠取'的边界:抠取是物理拆分(输出是原对象的实体片段),解构是分析拆分(输出是关于原对象组成的描述)。与'反推'的边界:反推推理'隐含的属性 / 原因 / 表征'(风格 / 情感 / depth 结构),解构分析'显式的内部组成方式'(章节 / 层次 / 框架 / 要点)。同义动作(写 actions[] 时统一规范为「解构」):拆解(结构)/ 结构分析 / 框架分析 / 层级分析 / 摘要 / 要点提炼。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "生成",
+      "分类说明": "从无到有产出新的对象——动作本身不依赖某个被改造的'前身'对象,仅依靠引导信息(如 prompt、参考、规则、知识)创造出之前不存在的产物。典型:生成 / 文生图 / 文生视频 / 合成 / 补全 / 生成草图 / 起草。判别口诀:输出是一个新对象(图、文本、视频、音频),其'实体'在输入中并不存在;输入即使含参考素材,参考也只是引导而非'被改造的本体'。与'修改'的边界:生成的输出没有可对应的'同一个对象的前一版本',修改的输出能与输入对应到'同一个对象的不同形态'。与'获取'的边界:生成的对象是当前动作产出的全新产物,获取的对象是预先就存在的。\n\n【本质】生成是'产生信息增量'的动作——给出一个之前不存在的新信息片段。\n\n【L2 切分维度】按'增量结果的形态'切分——元素生成(结果是一个自成一体的独立单元)/ 关系生成(结果是多项之间的明确关系结构)。两类 MECE 完备:要么是单件独立单元,要么是多项 + 关系。L2'元素生成'本身即叶子节点,不再向下切分;L2'关系生成'下再按关系几何形态切分 L3。\n\n【L3 切分维度】关系生成下按'关系的几何形态'切分——数组生成(一维线性顺序)/ 结构生成(非线性结构 / 共时并置)。两类 MECE 完备:要么是先后排列,要么是同时并置。\n\n【actions[] 规范取值】叶子节点(元素生成 / 数组生成 / 结构生成)直接作为 actions[] 字段的规范取值。本树即动作词典,所有近义动词在叶子分类说明中显式标注规范化目标。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "元素生成",
+          "分类说明": "生成结果是一个自成一体的单个对象——对外是一个独立单元,不论内部是简单还是复合。涵盖:文生图(一张图)/ 图生图(产出新的一张图)/ 文生视频片段(一段独立短片)/ 起草文案(一段独立文本)/ 起草脚本(一份独立脚本)/ 生成单个角色 / 生成 BGM / 生成单个模板 / 生成单条 prompt。判别口诀:结果能否被指称为'一个 X'(一张图 / 一段视频 / 一份文案 / 一条 prompt)?能即归此。与'数组生成 / 结构生成'的边界:元素生成的产物对外呈一个独立单元(即使内部含多部件也对外呈一个),关系生成的产物本质是'多项 + 关系结构'。同义动作(写 actions[] 时统一规范为「元素生成」):起草 / 写稿 / 文生图 / 文生视频(单段)/ 图生图(单张产出)/ 草图生成 / 单件生成 / 撰写。",
+          "直接元素": [],
+          "子分类": [],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "关系生成",
+          "分类说明": "生成结果是多项之间的明确关系结构——多个东西按某种顺序 / 结构关联在一起。判别口诀:结果是否本质上是'多项 + 关系'(一组镜头序列、一套配色方案、一幅多元素布置)?是 = 关系。与'原子'的边界:原子结果对外是一个独立单元,关系结果是多项的关联结构。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "数组生成",
+              "分类说明": "生成结果是多项的线性顺序——给一组项确定它们的先后排列。涵盖:剧本时序、镜头序列、步骤清单、台本顺序、视频片段时间线、分镜先后、大纲排序、章节排序、教程步骤排布。判别口诀:产物的核心信息是'若干项 + 一条单向时间 / 顺序轴',调换顺序会破坏产物意义。与'元素生成'的边界:数组生成必含多项 + 先后约束(关系是核心信息),元素生成只是单个对象(无内部先后关系)。与'结构生成'的边界:数组是一维顺序(先后排列),结构是非线性 / 共时并置。同义动作(写 actions[] 时统一规范为「数组生成」):编排 / 串联 / 排序 / 时序排布 / 序列生成 / 时间轴编排 / 章节排序 / 剧本编排。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "结构生成",
+              "分类说明": "生成结果是多项的非线性结构——多个项以某种结构关系(融合 / 配合 / 空间布置 / 层级叠加)组合在一起。涵盖:场景画面合成、配色方案、UI 布局、多元素拼贴、风格 + 内容搭配、图层组合、版式构图、信息图组装、多视图布置。判别口诀:产物的核心信息是'多项 + 共时并置 / 空间层级关系',去掉任一元素或挪位置会破坏整体。与'数组生成'的边界:结构是非线性 / 共时并置(同时呈现),数组是一维线性顺序(先后排列)。与'元素生成'的边界:结构生成必含'多项 + 组合关系',元素生成是单件独立单元。同义动作(写 actions[] 时统一规范为「结构生成」):合成 / 搭配 / 布置 / 组合 / 拼贴 / 布局生成 / 配色生成 / 图层组合生成 / 版式生成。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "修改",
+      "分类说明": "在已有对象的基础上做改动——输入是一个待改造的本体对象,输出是它被改动后的版本,对象的身份保留但形态 / 属性 / 局部已发生变化。典型:编辑 / 局部重绘 / 上色 / 重打光 / 去背景 / 换脸 / 换装 / 修饰 / 增强 / 改写 / 翻译 / 风格化 / 转换 / 超分。判别口诀:能在输入与输出之间指认出'同一个对象'的'改前 / 改后'对应关系——超分前后是同一张图,改写前后是同一段文本。与'生成'的边界:修改有明确的'被改造本体',生成没有;若产物的主体来自输入对象的延续 → 修改,若产物的主体由动作新造 → 生成。与'提取'的边界:修改的输出仍是同类完整对象,提取的输出是输入的派生物(不同粒度或不同形态)。\n\n【L2 切分维度】按'改动性质'分 3 类——增(添加新的信息片段)/ 删(去除已有的信息片段)/ 变(改变已有部分:原位置上的替换 / 重述 / 风格化 / 格式转换 / 渐变调整 / 自动增强)。三类 MECE 完备:要么加新(信息总量增加)、要么去旧(信息总量减少)、要么原位置改变(信息总量基本不变,只是某部分变成不一样的)。\n\n【L3 切分维度】每个 L2 内按'具体动作动词'切分。L3 节点直接作为 actions[] 字段的规范取值——本树即动作词典,不用'直接元素'承载同义词,所有近义动词在 L3 的分类说明中显式标注规范化目标。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "增",
+          "分类说明": "添加新的信息片段到原对象上——原对象的现有部分保留,新内容 / 形态 / 装饰被叠加 / 嵌入进去。判别口诀:动作前后比较,原对象多了一些之前没有的信息。与'删'的边界:增是加新的(信息总量增加),删是去已有的(信息总量减少),方向相反。与'变'的边界:增是单纯加新(原位置不变,多出一份),变是在原位置上把已有部分改成不一样的(替换 / 渐变,无新增独立单元)。\n\n【L3 切分维度】按增加对象的层级切分——添加(substantive 内容元素的增)/ 叠加(form 形态层 / 装饰层的增)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "添加",
+              "分类说明": "在原对象上增加新的语义内容元素——给画面新增一个主体 / 物体 / 角色,给文案新增一段内容,给视频新增一段片段,给脚本新增一段动作。判别口诀:动作前后比较,原对象多出了一个独立的语义内容元素,这个元素本身就是'被增加的内容'(有独立语义身份:人 / 物 / 段 / 镜)。与'叠加'的边界:添加加的是内容层(substantive,多出一个独立语义元素),叠加加的是形态层(form,多出一层装饰性 / 标识性 / 修饰性形态)。与'替换'的边界:添加只加不去(原对象不变,多出一份),替换是去旧 + 换新(一删一加)。与'增强'的边界:添加是主动放入新元素(创作者指定内容),增强是自动质量提升(无新增内容)。同义动作(写 actions[] 时统一规范为「添加」):新增 / 添入 / 加入 / 加段 / 加镜 / 加角色 / 加物体 / 补段 / 补镜。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "叠加",
+              "分类说明": "在原对象上叠加新的形态层 / 装饰层——给画面叠加水印 / logo / 装饰图层 / 边框、给视频叠加字幕轨 / 弹幕、给文档叠加页眉页脚、给图叠加蒙层 / 滤色层。判别口诀:动作前后比较,原对象多出了一层不属于'语义内容主体'的装饰性 / 标识性 / 修饰性形态。与'添加'的边界:叠加加的是形态层(装饰 / 标识 / 修饰,不构成独立语义内容),添加加的是内容层(独立语义元素:人 / 物 / 段 / 镜)。与'风格化'(变)的边界:叠加是在原对象上多出一层独立可见的形态元素(水印 / logo 是可指认的一层),风格化是对原对象整体外观做转换(无独立可指认的新层)。同义动作(写 actions[] 时统一规范为「叠加」):加水印 / 加 logo / 加图层 / 加装饰 / 加边框 / 加蒙层 / 加字幕轨 / overlay / 嵌入标识。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "删",
+          "分类说明": "去除原对象的某部分信息——原对象的其余部分保留,被去除的部分从对象中消失。判别口诀:动作前后比较,原对象少了一些之前有的信息(信息总量减少)。与'增'的边界:删是去已有的(少一份),增是加新的(多一份),方向相反。与'变'下'替换'的边界:删只去不补(原位置变空),替换是去掉再补上不同的(原位置仍有内容,只是换成了别的)。\n\n【L3 切分维度】按被删除信息的空间 / 时间维度切分——抹除(空间维度内的内容删除)/ 剪除(时间维度上的片段删除)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "抹除",
+              "分类说明": "去除空间内的内容元素——把对象空间维度上的某部分内容擦掉 / 去掉。涵盖:去背景、去水印、去画面里的某个角色 / 物体、抹除画面瑕疵。与'剪除'的边界:抹除针对'空间内'的内容(同一画面 / 同一帧里的某部分),剪除针对'时间维度'的片段(视频 / 序列里的某段时间)。同义动作(写 actions[] 时统一规范为「抹除」):擦除 / 移除 / 抠除 / erase。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "剪除",
+              "分类说明": "剪掉时间维度的片段——把对象时间序列上的某段去掉。涵盖:剪掉视频中的一段、删除文章中的一节、截短音频、去掉序列中的某项。与'抹除'的边界:剪除针对'时间维度'的片段,抹除针对'空间内'的内容。同义动作(写 actions[] 时统一规范为「剪除」):剪 / 截短 / 删段 / cut。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "变",
+          "分类说明": "改变已有部分——原对象的内容 / 形态 / 属性 在原位置发生变化,无论是离散切换(替换:A → B)还是连续渐变(重述 / 风格化 / 转换 / 调整 / 增强)。判别口诀:动作前后比较,原对象的某部分'变成不一样的'(不是新增、不是删除,而是原位置改变);信息总量基本不变。与'增 / 删'的边界:变不改变信息总量(原位置改),增加新信息(多一份),删去除信息(少一份)。\n\n【L3 切分维度】按改变方式切分——替换(categorical 离散切换:A → B 实体不同)/ 重述(保原意改表达)/ 风格化(换审美 / 视觉风格)/ 转换(换技术形式 / 媒介 / 格式)/ 调整(continuous 手动微调属性)/ 增强(自动质量提升)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "重述",
+              "分类说明": "实质改述——保留原意,改造表达 / 表述方式。涵盖:改写文段、翻译(中 → 英 / 英 → 中)、重构表述结构、转写口吻(书面 → 口语 / 正式 → 随意)、改述要点 / 段落润色。与'替换'的边界:重述保原意改表达(同一段意思的不同说法),替换是把整段内容主体换成不同的另一段(意思可不同)。与'风格化'的边界:重述改文字的'表达方式'(语种 / 用词 / 结构),风格化改文字 / 画面的'审美调性'(如转某文风、转某腔调、转视觉风格)。与'转换'的边界:重述走表达层(同语种内换说法 / 改写),转换走形式承载层(语种 / 格式 / 媒介整体切换)。同义动作(写 actions[] 时统一规范为「重述」):改写 / 翻译 / 重写 / 重构 / 改述 / 润色 / paraphrase / 转写口吻。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "风格化",
+              "分类说明": "换审美 / 视觉风格——同一对象在视觉风格上的转换,本体内容大致保留。涵盖:卡通化 / 油画化 / 写实化 / 水彩化、转赛博朋克风、转日漫风、文字转某文风。与'转换'的边界:风格化是'审美层面'的风格转换(卡通 / 油画 / 水彩等审美调性),转换是'技术形式'的格式 / 媒介 / 语种切换。同义动作(写 actions[] 时统一规范为「风格化」):风格转换 / 风格迁移 / stylize / style transfer。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "转换",
+              "分类说明": "换技术形式 / 媒介 / 格式 / 语种——同一对象在技术承载形式上的转换。涵盖:jpg → png(格式)、mp4 → gif(媒介格式)、横屏 → 竖屏(画幅形式)、PDF → Word(文档格式)、中 → 英(语种形式,作为形式转换而非内容改述时)、文 → 音(TTS 形式承载)。与'风格化'的边界:转换是'技术形式 / 格式'变化(容器变,呈现方式可能变),风格化是'审美 / 视觉风格'变化(容器不变,审美调性变)。与'重述'的边界:转换走形式承载层(语种 / 格式 / 媒介整体切换),重述走表达层(同语种内换说法)。与'调整'的边界:转换是 categorical 形式切换(jpg → png),调整是 continuous 属性微调(在原值附近滑动)。同义动作(写 actions[] 时统一规范为「转换」):转格式 / 转媒介 / 改格式 / convert / 转语种 / 转分辨率(格式语境)/ 转编码。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "替换",
+              "分类说明": "用不同的对象 / 元素 / 内容把原位置上的整个对应部分换掉——离散切换(categorical),新旧之间是不同的实体,不是渐变。涵盖:换脸 / 换装 / 换背景 / 换发型 / 换角色 / 换台词段 / 整段文案替换 / 整段镜头替换 / 换字体 / 换配色(指定枚举值)。判别口诀:动作前后比较,原位置上'这个东西'被换成'另一个东西'(A → B 的离散切换),不是 A 自身的渐变改造。与'重述'的边界:替换换内容主体(A 段换成 B 段,意思可不同),重述保原意改表达(同一段意思的不同说法)。与'调整'的边界:替换是 categorical 离散切换(A → B 实体不同),调整是 continuous 渐变(在原值附近滑动)。与'添加'的边界:替换是去旧 + 换新一并发生(原位置仍有内容,只是变了),添加是单纯加新不动旧。与'风格化'的边界:替换是某个具体元素被换成另一个具体元素(局部对象层),风格化是整体审美调性的切换(整图 / 整段层)。同义动作(写 actions[] 时统一规范为「替换」):换 / 替 / 换脸 / 换装 / 换背景 / 换角色 / replace / swap / 替代。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "调整",
+              "分类说明": "渐变属性值(手动微调)——属性值在原位置附近做连续 / 渐变性的微调。涵盖:调色 / 调亮 / 调对比 / 调饱和、调音量 / 调音色、调速度 / 调节奏、调透明度、调位置(局部微调)/ 调大小(局部微调)。与'替换'的边界:调整是 continuous 微调(在原值附近滑动),替换是 categorical 切换(A → B 离散值)。与'增强'的边界:调整是'手动渐变'(创作者主动指定方向 / 幅度),增强是'自动质量提升'(系统智能修复 / 提升,无创作者主观方向)。与'风格化'的边界:调整改的是低层属性数值(亮度 / 对比 / 速度),风格化改的是高层审美调性(卡通化 / 油画化)。同义动作(写 actions[] 时统一规范为「调整」):调 / 校 / 微调 / fine-tune / adjust / 校色 / 调音。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "增强",
+              "分类说明": "自动质量提升——系统智能算法对对象做自动质量改善,无需创作者指定具体方向 / 数值。涵盖:超分(提分辨率)、降噪、锐化、补帧、修复瑕疵 / 自动修图、画质增强、音频降噪 / 增强、人像自动美化、自动去模糊。判别口诀:算法自己决定怎么改、改多少(创作者只决定'要不要做'),且不增减语义内容(不改变'画面里有什么')。与'调整'的边界:增强是'自动算法'提升质量(创作者只按按钮),调整是'手动渐变'微调属性(创作者指定方向 / 幅度)。与'添加'的边界:增强是属性维度的整体质量提升(不增减语义内容),添加是新增独立语义元素(多出一个新对象)。与'替换'的边界:增强不改变对象身份(只是更清晰 / 更干净),替换是把对象换成不同的另一个。同义动作(写 actions[] 时统一规范为「增强」):超分 / 降噪 / 锐化 / 补帧 / 修复 / 画质提升 / enhance / 自动修图 / 一键美化。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "存储",
+      "分类说明": "把当前持有的对象保存到某个存储位格,使其在未来可被再次取用——动作本身不创造、不改变对象,只是把对象的拷贝放到指定的存储位格。典型:保存 / 暂存 / 入库 / 沉淀 / 归档 / 留底。判别口诀:输入是工序内已有的对象,输出是'同一对象被放到了某个存储位格里'(对象本身不变,只是落地位置发生变化)。与'获取'的边界:存储是把工序内的对象往外送到存储位格(工序内 → 存储位格,写入侧),获取是从存储位格取回到工序内(存储位格 → 工序内,读取侧),二者方向相反。与'生成'的边界:存储不产生新对象(只是搬运现有对象的拷贝),生成产出之前不存在的新产物。与作用树'交付'的边界:交付是把产物推向终态对外(功能性归宿,发布意义),存储侧重把产物保留到可被未来调用的位置(持久化意义,可不对外)。\n\n【L2 切分维度】按'存储位格的位置 / 时效'切分——暂存(工序内·临时缓存,per-batch 用完即释)/ 沉淀(工序外·私有·长效,跨工序反复调用)/ 归档(工序外·长期封存,被动留底)。三种位格 MECE 完备,且与'获取'L2 形成对称关系(沉淀对应查询、暂存对应引用)。\n\n【L3 切分维度】每个 L2 内按'具体动作动词'切分。L3 节点直接作为 actions[] 字段的规范取值——本树即动作词典,不用'直接元素'承载同义词,所有近义动词在 L3 的分类说明中显式标注规范化目标。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "暂存",
+          "分类说明": "对象被存放在本次工序内 / 当前会话内的临时缓存——只在本次工序内可被再次引用,工序结束后不保证存活。判别:存放位置是工序自身的中间缓存,不是跨工序的持久化位格。与'沉淀'的边界:暂存是 per-batch / 本次工序内的临时态(用完即释),沉淀是跨工序的长效私库(可被未来工序反复调取)。与获取树'引用'的边界:暂存是'把对象放到工序内缓存里'(写入侧),引用是'从工序内缓存取出来用'(读取侧),二者配对完成 DAG 内自循环。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "缓存",
+              "分类说明": "把对象放到工序内 / 会话内的临时缓存里,供本次工序后续步骤复用。涵盖:节点输出缓存 / 中间产物保留 / 临时变量存放 / session 级 cache / 草稿暂存。判别:存放期限仅限本次工序 / 当前会话,工序结束后通常被释放。同义动作(写 actions[] 时统一规范为「缓存」):暂存 / 临时保存 / 草稿存 / cache / hold / 中间产物保存。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "沉淀",
+          "分类说明": "对象被存进创作者 / 团队的私有积累库,作为未来跨工序复用的资产。判别:存放位置是跨工序的长效私库(个人库 / 团队库 / 模板库),未来可被反复'查询.调取'取出。与'暂存'的边界:沉淀是跨工序长效(可被未来反复调用),暂存是本工序临时(用完即释)。与'归档'的边界:沉淀的目的是'供未来反复调用'(活跃资产 / 高频复用),归档的目的是'长期封存留底'(被动留底 / 低频访问)。与获取树'查询'的边界:沉淀是'把对象放进私库里'(写入侧),查询.调取是'从私库里取出来用'(读取侧),二者配对完成私库读写循环。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "入库",
+              "分类说明": "把对象作为私有零件级资产存进库里,供未来反复调用。涵盖:提示词入库 / 素材入库 / 模板入库 / 风格预设入库 / 参考图收藏入库 / 文案模板入库 / 镜头库入库 / LoRA 与 Embedding 等权重文件入库。判别:被存入的对象以'可被反复调取的单件形态'存在,目的是为下一次生产复用。与'存档'的边界:入库的对象是为'活跃复用'而存(高频调取),存档的对象是为'长期留底'而存(低频回溯)。同义动作(写 actions[] 时统一规范为「入库」):存入私库 / 收藏 / 加入收藏 / 模板沉淀 / 提示词沉淀 / 素材沉淀 / 加入素材库 / 权重入库。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "归档",
+          "分类说明": "对象被长期封存留底——目的不是供未来反复调用,而是保留历史记录 / 留底备查 / 合规存档 / 法定保留期。判别:存放位置是冷存储 / 历史归档,调用频率极低(被动访问 / 偶发回溯)。与'沉淀'的边界:归档强调'长期封存留底'(被动留底,访问稀少),沉淀强调'供未来反复调用'(活跃资产,频繁取用)。与作用树'交付'的边界:交付是把产物推到对外终态(功能完成意义),归档是把产物(无论是否已交付)存进历史档案(留底意义,可发生在已交付之后)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "存档",
+              "分类说明": "把对象(含成片、底稿、流程配置、版本快照)存进长期档案中,留底备查。涵盖:项目归档 / 版本快照存档 / 成片冷存档 / 流程配置存档 / 历史版本封存 / 工程文件归档 / 工作流配置存档。判别:存储动作的目的是'留底'而非'复用'。同义动作(写 actions[] 时统一规范为「存档」):归档 / 封存 / 冷存 / 留底 / archive / 版本快照 / 工程归档。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    }
+  ],
+  "$leaves": [
+    "检索",
+    "下载",
+    "调取",
+    "上传",
+    "拍摄",
+    "录音",
+    "键入",
+    "选取",
+    "裁切",
+    "抠取",
+    "抽帧",
+    "识别",
+    "反推",
+    "解构",
+    "元素生成",
+    "数组生成",
+    "结构生成",
+    "添加",
+    "叠加",
+    "抹除",
+    "剪除",
+    "重述",
+    "风格化",
+    "转换",
+    "替换",
+    "调整",
+    "增强",
+    "缓存",
+    "入库",
+    "存档"
+  ]
+}

File diff ditekan karena terlalu besar
+ 69 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/effect.json


+ 21 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/feature.json

@@ -0,0 +1,21 @@
+{
+  "title": "特性 (执行特征 + 控制流)",
+  "desc": "随机/幂等/写外部/读外部/人工/本地; 控制流: 并行/遍历/分支/请求/等待",
+  "tree": {
+    "执行特征": {
+      "随机": "非确定性输出",
+      "幂等": "相同输入相同输出",
+      "人工": "由人执行",
+      "本地": "本地完成",
+      "写外部": "修改外部状态",
+      "读外部": "读取外部状态"
+    },
+    "控制流": {
+      "并行": "同时执行多分支",
+      "遍历": "对序列每项",
+      "分支": "条件分支",
+      "请求": "请求外部",
+      "等待": "等待外部"
+    }
+  }
+}

+ 562 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/type.json

@@ -0,0 +1,562 @@
+{
+  "$comment": "类型 字典树 (新结构, 按功能角色组织: 程序控制/数据复用/内容/知识). 单一来源, agent Phase 2 直接读. $leaves 由 最终分类树 终端节点自动派生 (scratch/build_taxonomy.py 生成), 供 lint-case.py 校验 + renderer in_tree 标记. case-specific 新 type 走 workflow.json 各 procedure 的 type_registry (extends 一个本表叶子).",
+  "$kind": "taxonomy",
+  "$dimension": "类型",
+  "$field": "type",
+  "最终分类树": [
+    {
+      "分类名称": "程序控制类型",
+      "分类说明": "L0 大类——这个产出物的作用是控制一次或多次内容产出'要做成什么、用什么参数、怎么评、按什么流程跑'。判别口诀:它本身不是内容、不参与组装产物,而是被某次加工参考来左右生成过程或评判结果的控制信号 / 自动化配置。下辖的指令 / 参数 / 评估 / 流程 都是程序控制的一种:指令直接指挥单个内容单元'要什么 / 不要什么 / 长什么样',参数设定生成 / 加工的技术配置或装载件,评估通过对已产出物的评判驱动修改或取舍,流程把多步加工编排成可被自动跑通的配置。与'内容类型'的边界:程序控制不构成交付内容本身,内容类型是被生产、被交付的内容实体。与'数据复用类型'的边界:程序控制服务于生产过程的执行控制,数据复用是被反复装载 / 填充的内容性资产。与'知识类型'的边界:程序控制是被执行的指令 / 配置(机械生效),知识是被理解 / 借鉴的认知储备。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "指令",
+          "分类说明": "作用类别——这个产出物会被一次生成 / 加工当作'要做成什么'的规约来执行,下游步骤照着它产出一个内容单元。判别口诀:它对应一次具体生成、一个内容单元,规定这一个单元的内容长什么样。与'编排'的边界:指令管单个生成单元的内容(这一个具体要什么),编排管多部分作品的骨架与顺序(整体分几块、什么顺序)。与'约束'的边界:指令规定'要什么内容'(内容侧),约束规定'结构落在哪个区域 / 骨架'(空间侧)。与'参照'的边界:指令是被读懂、被执行的文字规约,参照是被看着模仿的样本实体。与'复用'的边界:指令是为当次产出专门写的、用完即弃的规约,复用是跨任务反复取用的。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "提示词",
+              "分类说明": "向生成模型发出的正向提示词,作为模型调用的指令载体——可以是一条,也可以是成库的多条。与'负向提示词'的边界:方向相反(一个吸引、一个排斥),是独立的字段位。同义术语(写 category 时统一规范为「提示词」):prompt / 正向提示词 / positive prompt / 提示词库。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "负向提示词",
+              "分类说明": "向生成模型发出的负向约束词,告诉模型'不要出现什么'。与'提示词'的边界:方向相反(一个吸引、一个排斥),是独立的字段位,不要混入正向提示词。同义术语(写 category 时统一规范为「负向提示词」):negative prompt / 反向提示词。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "描述",
+              "分类说明": "对某一对象的文字刻画——以'描述'这个制作形式角色命名,被描述的具体对象(人物 / 场景 / 妆容 / 风格 / 构图 / 氛围 等内容实质)写入 value 字段,不进入叶子名。判别:是描述性文字,在工序里作为生成的内容依据被执行。与'提示词'的边界:描述是'被描述的对象内容',提示词是'喂给模型的指令'(描述可作为提示词的一部分,但其本身的角色是描述文本)。同义术语(写 category 时统一规范为「描述」):人物描述 / 场景描述 / 妆容描述 / 风格描述 / 运镜描述(若不带时序)。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "参数",
+          "分类说明": "作用类别——这个产出物是控制一次生成 / 加工'技术参数 / 工具运转方式'的配置。判别口诀:它不规定内容、不限定空间,而是设定模型 / 工具按什么参数跑、产出什么规格。与'指令'的边界:指令管'要什么内容',参数管'用什么参数生成'。与'约束'的边界:约束限定空间边界,参数设定技术配置。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "生成参数",
+              "分类说明": "一次生成 / 加工所用的模型运行参数——涵盖:采样步数 / CFG / 采样器 / 随机种子 seed / 去噪强度 / LLM 温度 等。被设定的具体目的由 value 承载。与'规格参数'的边界:生成参数是'模型怎么算',规格参数是'产出物什么格式'。同义术语(写 category 时统一规范为「生成参数」):采样参数 / 模型参数 / seed / 生成配置。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "规格参数",
+              "分类说明": "对产出物格式规格的设定——涵盖:分辨率 / 尺寸 / 画幅比例 / 时长 / 帧率 / 码率 / 文件格式 等。与'生成参数'的边界:规格参数是产出物的格式形态,生成参数是模型运行的算法参数。同义术语(写 category 时统一规范为「规格参数」):分辨率 / 画幅 / 比例 / 时长设定 / 输出规格。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "模型权重",
+              "分类说明": "训练或微调得到的模型权重文件——套用时加载到生成模型上,改变模型的生成行为。涵盖:LoRA / Embedding / checkpoint / Hypernetwork / DreamBooth。被定制的具体目标由 value 字段承载,不进入叶子名。同义术语(写 category 时统一规范为「模型权重」):LoRA / Embedding / checkpoint / 权重包。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "评估",
+          "分类说明": "作用类别——这个产出物是对另一个产出物的评判 / 意见,会被采纳来驱动对被评对象的修改或取舍。判别口诀:它一定指向一个已存在的产出物、对它下判断(好不好、改哪里、选哪个),而不是凭空规定要做什么。与'指令'的边界:指令是前置的、凭空规定要做什么的规约,评估是后置的、针对已有产出的评判(评估必然预设一个被评对象,指令不预设)。与'知识'的边界:评估针对某一个具体产出、一次性、驱动当次迭代,知识是跨任务沉淀的通用认知。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "评分",
+              "分类说明": "对某个产出物给出的定量评判——分数 / 等级 / 排名,用于驱动取舍(如从候选里挑高分的)。与'评语'的边界:评分是定量结论(数字 / 等级),评语是定性的文字意见。同义术语(写 category 时统一规范为「评分」):打分 / 评级 / 排名 / score。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "评语",
+              "分类说明": "对某个产出物给出的定性文字评判——指出问题、给出修改方向,用于驱动下一轮修改。涵盖:审核意见 / 修改意见 / 质检报告 / 选择理由 / 测评结论。与'评分'的边界:评语是定性文字意见,评分是定量结论。与'指令'的边界:评语针对一个已存在的产出物提改进意见,指令是凭空规定要做什么。同义术语(写 category 时统一规范为「评语」):评审意见 / 审核意见 / 修改意见 / 反馈意见 / 质检报告 / review。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "流程",
+          "分类说明": "作用类别——可反复套用的'流程':描述多个加工步骤如何串接,套用时驱动整条流水线运转。判别口诀:它是一套'套上去能自动跑完多步'的编排配置。与'结构'的边界:流程是会跑起来的多步编排,结构是一份静态骨架。与'编排(控制)'的边界:流程是'制作过程'的步骤配置(可反复套用),编排是某一次内容作品的骨架。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "工作流",
+              "分类说明": "单任务的多步流程编排——一套流程跑一份输入得一份输出。涵盖:ComfyUI workflow / 自动化 pipeline 配置 / 跨工具协作流程 / Agent 流程编排。与'批处理'的边界:工作流是单任务编排(一次跑一份输入),批处理是多任务批量执行(一次跑多份输入)。同义术语(写 category 时统一规范为「工作流」):workflow / pipeline / 节点图。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "批处理",
+              "分类说明": "同一流程跑多份输入的批量执行配置——套用时对一组输入按同一套流程处理,得到一组对应输出。涵盖:X/Y/Z plot / 批量生成脚本 / Grid 出图配置 / 批量调参方案。与'工作流'的边界:工作流是单任务的多步流程,批处理是多任务的批量执行。同义术语(写 category 时统一规范为「批处理」):batch / 批量任务 / X/Y/Z plot。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "数据复用类型",
+      "分类说明": "L0 大类——这个产出物是跨任务沉淀下来、被反复装载或填充的'内容性资产':不服务于某一次具体产出,而是攒下来在很多次生产里反复被装载或填充。判别口诀:它的价值在'一次做好、多次复用',且自身是带内容性的实体(虚拟形象 / 视觉骨架 / 内容槽位),而非控制信号或评判。下辖的原子 / 序列 按结构形态切分:原子是不依赖串接的独立单件,序列是把多个槽位按顺序串接的有序骨架。与'程序控制类型'的边界:数据复用是带内容性的可装载 / 可填充资产,程序控制是左右生产过程的控制信号 / 配置。与'内容类型'的边界:数据复用是跨任务常备、反复取用的资产储备,内容是某一次产出的实体。与'知识类型'的边界:数据复用是被机械装上 / 填上即生效的资产,知识要被理解借鉴后才起作用。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "原子",
+          "分类说明": "作用类别——可反复套用的'单件原子级复用件':每一个本身就是一个完整的、不可再拆的复用单元,可独立装载到生成环节使用,不依赖与其他单元串接。判别口诀:装上 / 套上即用,不需要顺序衔接。与'序列'的边界:原子是单件不带顺序,序列是把多个槽位按顺序串接成连续骨架。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "数字人",
+              "分类说明": "一个可被反复驱动来产出口播 / 表演视频的完整虚拟人物形象——给它脚本 / 音频,它就产出该形象说话、表演的视频,套到不同脚本上产出不同视频、自身不变。与'模型权重'的边界:模型权重是加载进别的生成模型、改变其行为的增量权重(LoRA / Embedding / checkpoint),数字人是本身就能被驱动、独立产出视频的完整虚拟形象。与'视频成品(成品)'的边界:数字人是可复用的虚拟形象,某条数字人口播的具体成片是视频成品(value 写口播内容)。与'参考图(参照)'的边界:参考图是被静态模仿的图,数字人是被驱动产出视频的形象。同义术语(写 category 时统一规范为「数字人」):数字分身 / 虚拟人 / AI 分身 / 虚拟主播 / avatar / 口播数字人。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "版式",
+              "分类说明": "以视觉空间布局为核心的可复用骨架——套用时把内容填入预定义的空间位置。涵盖:海报版式 / PPT 版式 / 杂志版式 / 网页版式 / 信息图版式。与'模板'的边界:版式侧重视觉空间布局,模板侧重内容侧的可填充槽位。与'构图布局(约束)'的边界:构图布局是某一次具体内容的空间安排(一次性),版式是带占位槽位的可反复套用骨架。同义术语(写 category 时统一规范为「版式」):layout / 版面 / 排版骨架。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "序列",
+          "分类说明": "作用类别——可反复套用的'有序骨架':把多个槽位按顺序排成一条结构链,套用时按位置依次填入新内容,骨架本身不变。判别口诀:套用时需要按顺序填入多份内容,单点拆出来不成立。与'原子'的边界:序列由多个有序槽位组成,原子是单件不带顺序。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "模板",
+              "分类说明": "带可填充槽位的内容侧结构骨架——套用时把新内容填进对应槽位,骨架本身保持不变。涵盖:提示词模板 / 视频剪辑模板 / 设计模板 / 文档模板 / 分镜模板。被填充的具体内容类型由 value 字段承载,不进入叶子名。与'版式'的边界:模板侧重内容侧的可填充槽位(哪里填什么),版式侧重视觉空间布局(哪里放哪里)。同义术语(写 category 时统一规范为「模板」):template / 骨架 / 提示词模板 / 剪辑模板。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "内容类型",
+      "分类说明": "L0 大类——这个产出物本身就是被生产、流转、最终交付的内容实体。判别口诀:它是产线主流上的'那个东西'本身,不是用来左右它的控制信号、也不是跨任务的复用资产。下辖的素材 / 半成品 / 准成品 / 成品 是同一份内容在生命周期不同阶段的形态:素材是被拼接 / 影响生成的零件态(含被原样剪入的物理变化、与参与改变生成性质的化学变化),半成品是还要被继续改造 / 筛选 / 换形态的在制态,准成品是已定稿但需嵌入或陪同更大成品的组件级终态,成品是独立完整、可作为最终交付物的终态。与'程序控制类型'的边界:内容是被加工的对象本身,程序控制是左右加工结果的信号。与'数据复用类型'的边界:内容是某一次产出的实体,数据复用是跨任务反复取用的资产储备。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "素材",
+          "分类说明": "作用类别——这个产出物会被组装 / 剪辑 / 合成进更大的产物,当作其中一个零件,自身形态基本不变。判别口诀:它是更大产物的一个现成零件,被拼接 / 混入而不是被改造。与'半成品'的边界:素材被拼装进产物(形态不变,只是被放进去),半成品是被继续改造的对象(形态会变)。与'参照'的边界:素材被'吃进'产物,参照只被'看'。与'成品'的边界:素材服务于下游组装,不是工序终点。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "化学变化",
+              "分类说明": "作用类别——这类素材在被引入工序时不直接成为产物的'内容零件',而是参与改变后续生成的'内容性质':可作为被生成器模仿的范本、框定生成结果的空间 / 运动边界、或叠加到产出物的呈现层。判别口诀:它本身不被剪入产物,但参与决定'生成出来长什么样'——类比化学反应,影响产物性质而非堆叠位置。与'物理变化'的边界:化学变化改变结果性质 / 行为,物理变化是把素材原样搬进产物。",
+              "直接元素": [],
+              "子分类": [
+                {
+                  "分类名称": "参考图",
+                  "分类说明": "被生成步骤看着模仿的图像——以'参考'这个用途角色命名,被参考的具体对象(人物 / 场景 / 风格 / 构图 / 姿态 等内容实质)写入 value 字段,不进入叶子名;可以是一张,也可以是成库的多张。判别:在工序里承担'范本'角色(自身形态不被改造,也不被拼进产物)。与'底图'的边界:参考图被引用为锚(自身不被改造),底图是后续编辑会落在其上改造的对象。与'控制图'的边界:参考图作软引导(影响风格 / 主体形象),控制图作强空间约束。同义术语(写 category 时统一规范为「参考图」):人物参考图 / 场景参考图 / 风格参考图 / ref / style ref / 参考图库。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "参考视频",
+                  "分类说明": "被生成步骤看着模仿的视频——常用于动作迁移、风格迁移、镜头模仿的输入。判别:在工序里承担'范本'角色(生成器看着模仿,自身不被改造、不被剪入产物)。与'视频片段(素材)'的边界:参考视频只被'看',视频片段会被剪入更大的视频产物。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "参考音频",
+                  "分类说明": "被生成步骤看着模仿的音频样本——影响音色 / 语气 / 唱腔 / 配乐风格,自身不被剪入产物。判别:在工序里承担'声音范本'角色(被模仿,不被混入成片)。与'参考视频'的边界:模态不同、作用相同,都是被模仿的范本。与'配音 / BGM(素材)'的边界:参考音频只被'听着模仿',配音 / BGM 是被混入成片的音轨。同义术语(写 category 时统一规范为「参考音频」):参考音色 / 音色样本 / 参考配乐 / voice reference。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "对标内容",
+                  "分类说明": "被整体研究、借鉴打法的成功案例作品——一条爆款视频 / 一篇高赞笔记 / 一个标杆案例,用来学它的整体结构、钩子与表达方式。判别:它是一个完整的成品案例,被当作'整体范本'来对标。与'参考图 / 参考视频'的边界:参考图 / 参考视频是低层模仿(风格 / 动作 / 镜头等局部特征),对标内容是高层借鉴(整篇作品的打法与结构)。与'知识.方法论'的边界:对标内容是那个案例本身(被模仿的样本),方法论是从一批案例里提炼出的做法规律(被理解的认知)。同义术语(写 category 时统一规范为「对标内容」):对标案例 / 标杆案例 / 爆款参考 / benchmark / 参考范例。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "分镜图",
+                  "分类说明": "脚本规划阶段画出的逐镜设定图——每张对应一个镜头,供后续拍摄 / 生成时看着还原。判别:在工序里作为镜头画面的'范本'被模仿。与'分镜脚本'的边界:分镜图是画出来的视觉设定,分镜脚本是文字形态的逐镜规划。与'关键帧(素材)'的边界:分镜图是规划阶段的镜头设定图,关键帧是已有 / 将有视频里某时刻抽出的帧。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "转场",
+                  "分类说明": "作用于两段内容之间衔接处的过渡效果配置——套用时定义前一段结尾到后一段开头的过渡方式。涵盖:淡入淡出 / 推拉 / 擦除 / 闪白 / 模糊过渡 / 缩放过渡。与'特效'的边界:转场作用在段间衔接,特效作用在段内。与'转场片段(素材)'的边界:转场片段是已渲染出的实际视频,转场是可反复套用的过渡效果配置。同义术语(写 category 时统一规范为「转场」):transition / 过渡效果。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "蒙版",
+                  "分类说明": "标记图像中可编辑 / 受保护区域的黑白图——承载'哪里能改、哪里不能改'的空间信息。与'控制图'的边界:蒙版给的是区域划分(哪块能改),控制图给的是结构骨架。同义术语(写 category 时统一规范为「蒙版」):mask / 遮罩。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "控制图",
+                  "分类说明": "用于约束生成模型空间结构的图——涵盖:pose 骨架图 / canny 边缘图 / depth 深度图 / normal 法线图 等。与'蒙版'的边界:控制图给的是结构骨架(pose / 边缘 / 深度),蒙版给的是可编辑 / 受保护的区域划分。同义术语(写 category 时统一规范为「控制图」):ControlNet 输入 / 结构图。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "运动轨迹",
+                  "分类说明": "约束画面主体或镜头随时间运动路径的输入——给生成模型一条轨迹 / 运动笔刷,限定'谁、往哪、怎么动'。判别:它约束的是运动路径(空间位置随时间变化),而非单帧的静态结构。与'控制图'的边界:控制图约束单帧的静态结构骨架(pose / 边缘 / 深度),运动轨迹约束的是跨帧的运动路径。同义术语(写 category 时统一规范为「运动轨迹」):运动笔刷 / motion brush / 运镜轨迹 / 轨迹控制 / motion path。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "滤镜",
+                  "分类说明": "作用于内容呈现层的静态效果配置——套用时改变颜色 / 质感 / 氛围 / 视觉风格 / 音色,呈现层定型不动。涵盖:风格滤镜 / LUT / 调色方案 / 美颜方案 / 音色滤镜 / EQ。与'特效'的边界:滤镜是静态效果(套上不动),特效是动态效果(套上动起来)。同义术语(写 category 时统一规范为「滤镜」):filter / LUT / 调色预设 / 风格化方案。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "构图布局",
+                  "分类说明": "对画面中多元素空间位置 / 大小 / 主次关系的安排方案——作为后续生成的空间约束被遵守,以布局结构为核心信息,不强调元素本身的实例化细节。与'版式(复用·结构)'的边界:构图布局是某一次具体内容的空间安排(一次性产物),版式是带占位槽位的可反复套用的布局骨架。同义术语(写 category 时统一规范为「构图布局」):layout / 构图 / 布局方案。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                }
+              ],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "物理变化",
+              "分类说明": "作用类别——这类素材会被原样'搬进'产物:被截取 / 剪入 / 混入到更大的成品中,作为它的物质组成,自身形态基本不变。判别口诀:它就是产物的一块现成零件,被堆叠 / 拼接 / 混合——类比物理变化,只移动位置不改性质。涵盖图像 / 视频 / 音频 各模态的现成零件。与'化学变化'的边界:物理变化是被堆进产物的物质本体,化学变化是参与决定生成结果的影响信号。",
+              "直接元素": [],
+              "子分类": [
+                {
+                  "分类名称": "截图",
+                  "分类说明": "从屏幕、视频或公共内容中截取得到的图像——作为素材被投入后续加工 / 组装。与'底图 / 成品图'的边界:截图来源于现成呈现的截取,不是工序生成或精修产出。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "视频片段",
+                  "分类说明": "作为素材被剪入更大视频产物的视频——一个镜头、一个动作演示、一段独立画面;可以是一段,也可以是成库的多段(镜头库)。与'参考视频'的边界:视频片段会被剪入产物,参考视频只被看着模仿。同义术语(写 category 时统一规范为「视频片段」):clip / 单镜 / 镜头库 / 素材镜头。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "转场片段",
+                  "分类说明": "用于连接前后两个镜头的过渡视频——本身是一段视频,会被剪入更大视频产物的衔接处。与'转场(复用·效果)'的边界:转场片段是已渲染出的实际视频,转场是可反复套用的过渡效果配置。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "关键帧",
+                  "分类说明": "视频 / 动画中具有代表性的单帧画面——作为静止图像被抽出、供后续步骤取用。与'分镜图'的边界:关键帧是已有 / 将有视频里某时刻抽出的帧,分镜图是规划阶段画的镜头设定图。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "音效",
+                  "分类说明": "用于点缀 / 强调的声音效果——作为音轨素材被混入视频产物;可以是一条,也可以是成库的多条(音效库)。同义术语(写 category 时统一规范为「音效」):sound effect / SFX / 音效库。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "特效",
+                  "分类说明": "作用于单段内容内部的动态效果配置——套用时叠加时间维度上的变化(动画、粒子、变形、闪烁、回声、混响等)。涵盖:粒子特效 / 动画特效 / 变形特效 / 慢动作 / 快放 / 音频混响。与'滤镜'的边界:滤镜套上不动,特效套上动起来。与'转场'的边界:特效作用在单段内容内部,转场作用在两段内容之间。同义术语(写 category 时统一规范为「特效」):effect / VFX / 动态效果。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                }
+              ],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "半成品",
+          "分类说明": "作用类别——这个产出物是工序中产出、还要被后续步骤继续加工 / 改造 / 筛选的中间态内容,尚未定稿。判别口诀:它处在'还要被改 / 被挑'的状态,后续步骤会落在它身上把它推向最终形态。与'素材'的边界:半成品会被改造(形态会变),素材是被原样拼装进产物的零件(形态不变)。与'成品'的边界:半成品是可被进一步处置的中间态,成品是不再改动、直接交付的终态。与'参照'的边界:半成品被改造,参照只被看、不被动。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "序列",
+              "分类说明": "作用类别——这类半成品本身是一份'有序的多段文字骨架'(章节 / 场 / 镜 / 时间轴 / 段落),尚未定稿,还要被后续步骤继续展开、拍摄、生成、剪辑或录音渲染。判别口诀:内部能数出有序的多个部分(章 / 场 / 镜 / 段),且整段还在被处置——按它去拍、去生、去剪、去读。与'半成品·原子'的边界:序列是有序的多段文字骨架,原子是独立的视觉中间件。与'半成品·组合'的边界:序列是文字层面的顺序骨架,组合是多层 / 多块拼合的视觉工作文件。",
+              "直接元素": [],
+              "子分类": [
+                {
+                  "分类名称": "大纲",
+                  "分类说明": "按章节 / 段落 / 议题组织的纲要文字——以条目化层级列出主体内容的骨架,指挥后续展开创作。涵盖:文章大纲 / 视频大纲 / 教程大纲 / 章节纲要 / 内容提纲 / 演讲提纲。判别:只列骨架要点不展开。与'脚本'的边界:大纲只列骨架要点,脚本展开具体叙事 / 动作 / 对白。与'分镜脚本'的边界:大纲是内容层骨架(章节 / 议题),分镜脚本是制作层骨架(镜头 / 画面)。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "脚本",
+                  "分类说明": "按时间 / 情节 / 操作顺序组织的有序文本——包含若干场景 / 段落 / 动作 / 对白等元素,指挥后续拍摄 / 生成。被组织的具体内容(剧情对白 / 动作流程 / 操作步骤 / 教程演示 等内容实质)写入 value 字段,不进入叶子名。与'分镜脚本'的边界:脚本以叙事 / 动作 / 操作为基本单位,分镜脚本以镜头切分为基本单位。与'大纲'的边界:脚本展开具体叙事 / 动作 / 对白,大纲只列骨架要点。同义术语(写 category 时统一规范为「脚本」):剧本 / 文本脚本 / 动作脚本 / 操作脚本 / 教程脚本。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "分镜脚本",
+                  "分类说明": "按镜头组织的拍摄 / 生成规划文本——每个镜头有编号、画面、动作、运镜、时长等,指挥后续逐镜拍摄 / 生成。涵盖运镜描述(作为分镜脚本中每个镜头的子字段而非独立产物)。与'脚本'的边界:分镜脚本以镜头为基本单位、包含视觉化细节,脚本以叙事 / 动作 / 操作为基本单位。与'分镜图'的边界:分镜脚本是文字形态的逐镜规划,分镜图是画出来的逐镜设定图。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "剪辑脚本",
+                  "分类说明": "成片剪辑阶段的时间轴编排——规定'用哪段素材、按什么顺序、各自的入出点与时长'拼成最终视频。判别:它是面向'已有素材如何组装成片'的骨架,处在剪辑环节。与'分镜脚本'的边界:分镜脚本是拍摄 / 生成前的镜头规划(要产出哪些镜头),剪辑脚本是把已有素材组装成片的时间轴安排。与'工作流(复用·流程)'的边界:剪辑脚本是这一条片子的具体编排,工作流是可反复套用的制作流程配置。同义术语(写 category 时统一规范为「剪辑脚本」):剪辑表 / 时间轴 / timeline / 卡点表。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "配音文案",
+                  "分类说明": "配音 / 解说内容的文字形态——承载'要被读出来'的语义内容,是配音的在制态:经配音 / 录音步骤渲染成音频。与'配音(素材)'的边界:配音文案是文字形态的在制内容,配音是已渲染出的音频音轨。与'脚本(编排)'的边界:配音文案是单纯的旁白 / 解说文本本身,脚本是带分镜 / 动作 / 台词的多段落骨架。与'正文(成品)'的边界:正文直接以文字交付、即为终态,配音文案要再被渲染成音频才到终态。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                }
+              ],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "原子",
+              "分类说明": "作用类别——这类半成品本身是一份独立的、形态完整的视觉中间件(一张图 / 一段视频 / 一组分镜),尚未定稿,等着被后续步骤继续编辑 / 挑选 / 合成推向最终形态。判别口诀:它是一份独立单件的视觉中间产物,单点拿出来就能看,但还要被处置。与'半成品·序列'的边界:原子是独立的视觉中间件,序列是有序的多段文字骨架。与'半成品·组合'的边界:原子是单一中间件,组合是多层 / 多块拼装而成的可编辑整体。",
+              "直接元素": [],
+              "子分类": [
+                {
+                  "分类名称": "底图",
+                  "分类说明": "作为后续编辑(局部重绘、风格化、叠加)基础的图像——判别口诀:身份后续会被保留并继续改造的对象。与'成品图'的边界:底图是会被继续改造的中间态,成品图是不再改动的终态。与'参考图'的边界:底图是后续编辑会落在其上改造的对象,参考图只被引用为锚、自身不被改造。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "样图",
+                  "分类说明": "工序中产出、用于挑选或对照的候选图——常用于'从候选里挑选'的场景;可以是一张候选,也可以是一批候选(候选图集)。与'成品图'的边界:样图是待挑选 / 待定的候选态,成品图是定稿态。同义术语(写 category 时统一规范为「样图」):候选图 / draft / 候选图集。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "分镜视频",
+                  "分类说明": "按镜头顺序排出的多段视频——尚未做最终合成,作为粗剪半成品等待后续合成 / 调整。与'视频成品'的边界:分镜视频是未做最终合成的镜头序列(待加工),视频成品是已合成交付的整片。与'视频片段(素材)'的边界:分镜视频是面向最终成片的粗剪半成品,视频片段是被剪进来的零件。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                }
+              ],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "组合",
+              "分类说明": "作用类别——这类半成品由多个子元素按图层 / 格子拼装而成的可编辑整体,每个子元素仍可辨识 / 可调整,未拍平定稿。判别口诀:它内部能看出多层 / 多块的拼合结构,且整体还能被继续改动(换层、挪位、调比例)。与'半成品·序列'的边界:组合是空间维度的拼合(多层 / 多块),序列是文字层面的顺序骨架。与'半成品·原子'的边界:组合是多层 / 多块拼装而成,原子是单一独立的视觉中间件。与'成品·合成图'的边界:组合保留子元素的可辨识 / 可调整性(半成品态),合成图是已拍平 / 已融合定稿的成品。",
+              "直接元素": [],
+              "子分类": [
+                {
+                  "分类名称": "图层组合",
+                  "分类说明": "多个图层按层级叠加形成的可编辑整体——每层有独立内容,常见于设计稿、PSD 文件、合成模板,作为可继续调整的工作文件。与'合成图(成品)'的边界:图层组合保留分层、可继续改动(半成品),合成图是已拍平交付的成品。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                },
+                {
+                  "分类名称": "拼图",
+                  "分类说明": "将多个素材格子化并置在一张图上的图像——多元素同时呈现、各自仍可辨认,作为整体交付。被并置的具体对象(多视角 / 多变体 / 多角度 / 多人物 / 对比 等内容实质)写入 value 字段,不进入叶子名。与'合成图'的边界:拼图强调并置式格子布局,合成图强调融合 / 叠加成新画面。同义术语(写 category 时统一规范为「拼图」):九宫格 / 对比图 / collage。",
+                  "直接元素": [],
+                  "子分类": [],
+                  "分类性质": "内容"
+                }
+              ],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "准成品",
+          "分类说明": "作用类别——这类产出物本身已是定稿的'组件级终态'(不再被改造 / 筛选),但相比成品粒度更小,通常作为更大成品的组件被搭载或陪同交付。判别口诀:它自己已经定稿,但单独交付往往不是完整作品,要嵌进或陪同更大的载体。与'半成品'的边界:准成品已定稿不再被改 / 筛选,半成品还要被继续加工 / 换形态。与'成品'的边界:成品是独立完整的最终交付物,准成品是单模态的组件级定稿、常嵌入或陪同更大的成品。与'素材'的边界:素材是通用、可候选取用的现成零件(往往多份备选),准成品是为这一次作品专门定稿好的组件(单一确定件)。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "歌词",
+              "分类说明": "歌曲内容的文字形态(词作)——承载'要被唱出来'的内容,是歌曲的在制态:经谱曲 / 演唱渲染成歌曲音频。与'配音文案'的边界:歌词被唱(终态是歌曲),配音文案被读(终态是配音)。与'正文(成品)'的边界:正文直接以文字交付即为终态,歌词要再被渲染成歌曲音频。同义术语(写 category 时统一规范为「歌词」):词 / lyrics / 歌词文案。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "配音",
+              "分类说明": "为视频 / 内容配上的人声音频——作为音轨素材被混入视频产物,与 BGM / 音效 同为音轨。与'配音文案'的边界:配音文案是文字形态的在制内容,配音是已读出的音频音轨。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "BGM",
+              "分类说明": "作为背景音乐的音频——作为音轨素材被混入视频产物;可以是一段,也可以是成库的多段(BGM库)。同义术语(写 category 时统一规范为「BGM」):背景音乐 / bgm / BGM库。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "字幕",
+              "分类说明": "覆盖在视频画面上的文字内容——作为视频成品的呈现层组成被交付。与'配音文案'的边界:字幕是呈现在画面上的文字,配音文案是被读出的文字稿。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "标题",
+              "分类说明": "作品 / 内容的标题文本——简短文字,用于命名 / 概括 / 引流。涵盖:视频标题 / 文章标题 / 笔记标题 / 章节标题 等。与'正文'的边界:标题是高度浓缩的命名 / 概括文字(通常一行),正文是展开陈述的主体文字(多段连续)。与'描述(指令)'的边界:标题是被交付的终态文字,描述是喂给生成的依据。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "正文",
+              "分类说明": "作品 / 内容的主体文字部分——较长的连续陈述文本,承载完整叙述 / 说明 / 论述,作为终态文字被交付。涵盖:文章正文 / 帖子正文 / 公众号文章主体 / 笔记正文 / 长文案。与'标题'的边界:正文是展开陈述的主体(通常多段),标题是浓缩命名(通常一行)。与'脚本(编排)'的边界:正文是被交付的终态文字本身,脚本是指挥后续拍摄 / 生成的规约。与'配音文案(半成品)'的边界:正文直接以文字交付、即为终态,配音文案要再被渲染成音频才到终态。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        },
+        {
+          "分类名称": "成品",
+          "分类说明": "作用类别——这个产出物会被作为终态内容交付 / 呈现给受众,不再进入后续加工。判别口诀:它是工序链路的终点,被受众消费或作为最终交付物。与'半成品'的边界:成品定稿不再改,半成品还要被继续处置。与'素材'的边界:成品是工序终点,素材是给下游组装当零件。",
+          "直接元素": [],
+          "子分类": [
+            {
+              "分类名称": "成品图",
+              "分类说明": "作为终态内容交付的图像——处于工序末端、不再被继续改造;可以是一张,也可以是成组交付的多张(成品图集 / 图集)。被汇集时的具体对象(多角度 / 多视角 / 多变体 等内容实质)写入 value 字段。与'底图 / 样图'的边界:成品图是定稿态,底图 / 样图是仍会被改造 / 挑选的中间态。同义术语(写 category 时统一规范为「成品图」):成品图集 / 图集 / 定稿图。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "视频成品",
+              "分类说明": "经过分镜剪辑、合成、配音后形成的完整视频——作为终态内容整体交付。与'分镜视频(半成品)'的边界:视频成品是已合成交付的整片,分镜视频是未做最终合成的粗剪半成品。与'视频片段(素材)'的边界:视频成品是交付的整片,视频片段是被剪进来的零件。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            },
+            {
+              "分类名称": "合成图",
+              "分类说明": "将多张素材融合为一张的图像——元素之间有空间叠加 / 拼接 / 融合关系,已拍平为一张交付。与'图层组合(半成品)'的边界:合成图是已拍平交付的成品,图层组合保留分层、可继续改动。与'拼图'的边界:合成图强调融合 / 叠加成新画面(看不出独立单元),拼图强调格子化并置(各元素仍可辨)。同义术语(写 category 时统一规范为「合成图」):融合图 / 拼合图。",
+              "直接元素": [],
+              "子分类": [],
+              "分类性质": "内容"
+            }
+          ],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    },
+    {
+      "分类名称": "知识类型",
+      "分类说明": "L0 大类——这个产出物是沉淀下来、跨任务复用的认知性内容,会被检索 / 学习 / 借鉴,为未来的生产提供认知依据。判别口诀:它不服务于某一次具体产出,而是攒下来反复查、反复用的认知储备;不会被装载 / 填充 / 剪入产物,而是要被理解后才起作用。与'数据复用类型'的边界:数据复用是可机械装载 / 填充的资产实体(装上即生效),知识要被理解 / 借鉴后才起作用。与'程序控制·指令'的边界:指令是为当次产出专门写的、用完即弃的规约,知识是跨任务沉淀、反复复用的。与'程序控制·评估'的边界:知识是跨任务的通用认知,评估是针对某一个具体产出的一次性评判。与'内容类型'的边界:知识不是被生产 / 交付的内容实体,而是支撑生产的认知背景。",
+      "直接元素": [],
+      "子分类": [
+        {
+          "分类名称": "知识库",
+          "分类说明": "由知识条目(事实 / 概念 / 规则 / 操作要点)汇集而成的资料库——沉淀下来供检索 / 引用 / 喂给模型作背景,是陈述性知识的复用储备。与'方法论'的边界:知识库是'是什么'的事实 / 概念资料,方法论是'怎么做'的做法经验。同义术语(写 category 时统一规范为「知识库」):knowledge base / 资料库 / 背景资料。",
+          "直接元素": [],
+          "子分类": [],
+          "分类性质": "内容"
+        }
+      ],
+      "分类性质": "内容"
+    }
+  ],
+  "$leaves": [
+    "提示词",
+    "负向提示词",
+    "描述",
+    "生成参数",
+    "规格参数",
+    "模型权重",
+    "评分",
+    "评语",
+    "工作流",
+    "批处理",
+    "数字人",
+    "版式",
+    "模板",
+    "参考图",
+    "参考视频",
+    "参考音频",
+    "对标内容",
+    "分镜图",
+    "转场",
+    "蒙版",
+    "控制图",
+    "运动轨迹",
+    "滤镜",
+    "构图布局",
+    "截图",
+    "视频片段",
+    "转场片段",
+    "关键帧",
+    "音效",
+    "特效",
+    "大纲",
+    "脚本",
+    "分镜脚本",
+    "剪辑脚本",
+    "配音文案",
+    "底图",
+    "样图",
+    "分镜视频",
+    "图层组合",
+    "拼图",
+    "歌词",
+    "配音",
+    "BGM",
+    "字幕",
+    "标题",
+    "正文",
+    "成品图",
+    "视频成品",
+    "合成图",
+    "知识库"
+  ]
+}

+ 297 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/taxonomy/type_suggestions.md

@@ -0,0 +1,297 @@
+# Type 字典扩展建议 · Agent 跑 case 时累积
+
+> **这个文件由 Agent 在 Phase 2 类型归一时自动 append**, 不要手工编辑 (除非 spec 维护者在做"审阅 → 合并到 type.json" 的工作)。
+>
+> 何时写: Phase 2 把 case-specific 新类型挂靠进 `type_registry`(extends 桥到标准叶子)后, 第三阶段跑 `lint-case.py` 会**自动 record** 一条到下面的「累积条目」段(工具代劳, 不用手写)。
+>
+> spec 维护者怎么用: 定期扫这个文件, 看哪些新类型在多个 case 反复出现 / 语义独立性强 — 这些值得升级到 `type.json` 的 `$leaves` (顶级叶子) 或长驻 `registry` (跨 case extends 库)。
+
+---
+
+## 升级判断准则 (维护者用)
+
+| 信号 | 应该升级 |
+|---|---|
+| 同一新类型在 ≥3 个不同 case 出现 | ✅ 升 `$leaves` (说明跨 case 通用) |
+| 单 case 出现但语义跟 `$leaves` 无重叠 + 内容创作领域常用 | ✅ 升 `registry` (跨 case extends 库) |
+| 跟某 `$leaves` 是同义异写 (e.g. "人物图" vs 已有 "参考图") | ❌ 别升, 在 spec 提一句"X 直接归到 leaf Y" |
+| 只是单 case 的窄场景 (e.g. "苏晚的肖像图") | ❌ 留在该 case 的 `case_type_registry`, 不升 |
+
+---
+
+## 累积条目
+
+> ⚠ 本段已由维护者**手工清理过一轮**(2026-06-09)。原始自动累积有 ~360 条, 大量是
+> ① 同类型在 `case-5` / `case-case_5` 等不同 case_id 下重复记录、② 单 case 窄场景的冗长名
+> (`核心人物参考图集` / `注意力分数矩阵` / `含关键词骨架`)、③ 跟 extends 父叶或标准叶同义的换皮
+> (`生成图`≈`成品图`、`需求描述`/`需求文本`/`需求文档`≈`描述`)。这些已删 (追溯见 git 历史 / `spec-back-1`)。
+> **保留标准: 名字相对简洁 + 语义跟标准叶/父叶有实质区别。**
+>
+> Format: `- \`<新类型名>\`: <一句描述>  (extends \`<leaf>\`[, 备注])`
+
+### 结构化分析产物 (多 case 反复出现, 值得升 `$leaves`/`registry`)
+- `视觉风格JSON`: 从参考图反推提取的结构化视觉风格(JSON: 颜色/构图/光影/材质/氛围/复刻关键词)  (extends `描述`, 跨 ≥6 case 复现)
+- `分镜分析`: 对参考视频逐分镜解构的结构化分析(每镜含画面/主体/运镜/光影/台词/音效/画质 + 生成提示词)  (extends `提示词`, 跨多 case 复现)
+- `JSON提示词`: 以 JSON 结构描述的图像提示词(subject/color_palette/lighting/composition/aesthetic 多层级)  (extends `提示词`)
+- `元提示词`: 驱动 AI 生成代码/网页界面的系统提示词(含框架槽位), 与图像正向 prompt 不同  (extends `提示词`)
+- `提示词模板`: 带 `[变量名]` 占位符的可复用提示词骨架, 填入变量值即可执行  (extends `模板`)
+
+### 字典暂缺的类别 (状态/凭证/配额 — type.json 没有对应叶子)
+- `账户权限`: 使用 AI 功能的前置状态: 已登录 / 功能解锁 / 算力配额充足  (extends `描述`, ⚠ 字典缺"状态/配额"类叶子)
+- `API密钥`: 第三方平台 API 访问凭证字符串, 用于接口鉴权  (extends `生成参数`)
+- `调色预设`: 可跨次调用复刻同款色调的调色参数套装(色温/饱和度/色调)  (extends `滤镜`)
+
+### 内容创作领域常用 (简洁且与 `描述`/`脚本` 有别)
+- `剧本`: 完整剧集本 / 分集剧情, 含人物关系与情节冲突  (extends `脚本`)
+- `题材`: 短剧 / 内容创作的题材方向(含人设标签 + 爽点元素)  (extends `描述`)
+- `选题`: 经爆款潜力与定位双重验证后确定的具体写作选题角度  (extends `描述`)
+
+- `爆款题材`: 用于调研和选择爆款题材的输入  (来自 case-2-test-3, extends `提示词`)
+- `完整剧本`: 豆包生成的完整短剧剧本  (来自 case-2-test-3, extends `脚本`)
+- `人物形象参考图`: 核心角色的人物形象参考图  (来自 case-2-test-3, extends `参考图`)
+- `分镜视频片段`: Seedance 2.0 生成的分镜视频片段  (来自 case-2-test-3, extends `视频片段`)
+- `成品短剧视频`: 剪辑合成后的成品短剧视频  (来自 case-2-test-3, extends `视频成品`)
+
+- `视觉风格分析 JSON 数据`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `复刻图片成品`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `成品图`)
+- `分镜拆解分析报告`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `视频片段成品`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `视频成品`)
+
+- `原文要点`: (无 desc)  (来自 case-A_xhs_69abf820, extends `描述`)
+- `要点总结`: (无 desc)  (来自 case-A_xhs_69abf820, extends `描述`)
+- `参数表`: (无 desc)  (来自 case-A_xhs_69abf820, extends `生成参数`)
+- `参数与词汇表`: (无 desc)  (来自 case-A_xhs_69abf820, extends `生成参数`)
+
+- `视觉风格分析报告`: 对参考图的视觉元素、构图、色彩和风格的分析报告  (来自 case-A_xhs_6963be77, extends `知识库`)
+- `AI绘画提示词`: 用于AI绘画工具的详细提示词  (来自 case-A_xhs_6963be77, extends `提示词`)
+- `优化后的提示词`: 针对特定城市优化后的AI绘画提示词  (来自 case-A_xhs_6963be77, extends `提示词`)
+
+- `参考图片`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `参考图`)
+- `结构化视觉风格分析JSON`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `复刻图片`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `成品图`)
+- `分镜分析报告`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+
+- `HTML功能边界说明`: HTML功能边界分析  (来自 case-B, extends `知识库`)
+- `PPT要素文档`: PPT要素文档  (来自 case-B, extends `脚本`)
+- `Skill与模板`: Skill与模板  (来自 case-B, extends `模板`)
+- `创作需求`: 用户对PPT的制作需求  (来自 case-B, extends `提示词`)
+
+- `视觉风格分析`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `视觉风格结构`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `分镜提示词`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `提示词`)
+- `复刻视频`: (无 desc)  (来自 case-A_gzh_8f5fbfb0, extends `视频成品`)
+
+- `视觉风格分析JSON`: AI分析的图片视觉风格JSON  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `生成指令`: 用户自定义的生图指令  (来自 case-A_gzh_8f5fbfb0, extends `提示词`)
+- `分镜分析JSON`: AI拆解的分镜分析数据  (来自 case-A_gzh_8f5fbfb0, extends `描述`)
+- `分镜提示词集合`: 视频生成的分镜提示词  (来自 case-A_gzh_8f5fbfb0, extends `提示词`)
+- `复刻视频片段`: 根据分镜生成的视频片段  (来自 case-A_gzh_8f5fbfb0, extends `视频成品`)
+
+- `参考图副本`: 用于分析的参考图片副本  (来自 case-A_gzh_8f5fbfb0, extends `参考图`)
+- `主体描述提示词`: 用户输入的生图主体描述  (来自 case-A_gzh_8f5fbfb0, extends `提示词`)
+- `复刻成品图`: AI生成的复刻风格图片  (来自 case-A_gzh_8f5fbfb0, extends `成品图`)
+- `视频生成提示词列表`: 用于生成视频的提示词列表  (来自 case-A_gzh_8f5fbfb0, extends `提示词`)
+
+- `题材思路`: 用户输入的短剧题材构思  (来自 case-2-test-0, extends `描述`)
+- `剧本大纲+台词`: 豆包生成的完整短剧剧本、大纲及台词  (来自 case-2-test-0, extends `脚本`)
+- `人物设定图`: AI生成的人物形象参考图  (来自 case-2-test-0, extends `参考图`)
+- `短剧视频片段`: Seedance 2.0生成的15秒视频片段  (来自 case-2-test-0, extends `视频片段`)
+- `成品短剧视频`: 剪辑合成后的最终短剧视频  (来自 case-2-test-0, extends `视频成品`)
+
+- `原文章节`: 原文教程章节  (来自 case-A_gzh_69b20c7a, extends `参考图`)
+- `工具介绍`: 工具功能介绍  (来自 case-A_gzh_69b20c7a, extends `参考图`)
+- `参考图素材`: 反推素材  (来自 case-A_gzh_69b20c7a, extends `参考图`)
+- `反推提示词`: 反推结果  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `简短提示词`: 扩写输入  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `扩写提示词`: 扩写结果  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `提示词素材`: 词库素材  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `管理后的提示词库`: 词库管理结果  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `提示词规则模板`: 工程模板  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+- `自定义提示词工程`: 工程结果  (来自 case-A_gzh_69b20c7a, extends `提示词`)
+
+- `原文素材`: 公众号文章原文  (来自 case-A_gzh_d144766d, extends `参考图`)
+- `反推需求分析表`: 分析后的需求结构  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `通用基础版提示词模板`: 通用基础提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `要素版提示词模板`: 要素拆解提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `城市地标复刻提示词模板`: 地标复刻提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `时尚摄影复刻提示词模板`: 摄影复刻提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `创意裂变提示词模板`: 创意裂变提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `社群海报复刻提示词模板`: 社群海报复刻提示词  (来自 case-A_gzh_d144766d, extends `提示词`)
+
+- `视觉要素分析`: 对参考图进行视觉要素拆解的分析结果  (来自 case-A_gzh_d144766d, extends `描述`)
+- `提示词模板`: 用于AI绘画的结构化提示词模板  (来自 case-A_gzh_d144766d, extends `提示词`)
+- `复刻成品图`: 基于反推提示词生成的复刻或裂变图片  (来自 case-A_gzh_d144766d, extends `成品图`)
+
+- `题材思路`: 爆款题材思路  (来自 case-2-test-3.1, extends `参考图`)
+- `剧本大纲及分集剧情`: 豆包生成的完整剧本  (来自 case-2-test-3.1, extends `脚本`)
+- `分镜说明及台词`: 每一集的分镜说明及台词  (来自 case-2-test-3.1, extends `脚本`)
+- `人物设定思路`: 人物设定思路  (来自 case-2-test-3.1, extends `参考图`)
+- `人物参考图集`: 核心人物参考图  (来自 case-2-test-3.1, extends `参考图`)
+- `分镜视频片段列表`: 生成的视频片段列表  (来自 case-2-test-3.1, extends `视频片段`)
+- `成品短剧视频`: 最终合成的短剧视频  (来自 case-2-test-3.1, extends `视频成品`)
+
+- `视频配置`: 反推视频提示词时,对输入通道、采样率、媒体分辨率等参数的技术配置  (来自 case-A_zhihu_20434415, extends `生成参数`)
+- `视频观察稿`: 对视频中主体、动作、镜头、声音等显式信息的文字观察记录  (来自 case-A_zhihu_20434415, extends `描述`)
+- `结构化中间层`: 将视频观察稿按照 JSON Schema 提取出的结构化数据,包含时间块和可复用字段  (来自 case-A_zhihu_20434415, extends `描述`)
+- `长提示词`: 包含主体、空间、镜头、音频等多层要素的完整视频生成提示词  (来自 case-A_zhihu_20434415, extends `提示词`)
+- `短提示词`: 更偏好短 prompt 的目标平台所使用的硬字段版视频生成提示词  (来自 case-A_zhihu_20434415, extends `提示词`)
+- `镜头表`: 将视频拆解出的多镜头时序和动作变化列表  (来自 case-A_zhihu_20434415, extends `描述`)
+- `未指定说明`: 列出没有证据、宁可先空着的镜头参数、seed 或后期步骤的说明  (来自 case-A_zhihu_20434415, extends `描述`)
+- `生成视频`: 使用反推出的提示词重新生成的目标视频  (来自 case-A_zhihu_20434415, extends `视频成品`)
+- `验收表`: 用于判断生成视频与参考视频在主体、动作、镜头、节奏、质感上偏差的验收表  (来自 case-A_zhihu_20434415, extends `评估标准`)
+- `验收结果`: 对照验收表对生成视频进行评估后得出的偏差结论与下一步修复方向  (来自 case-A_zhihu_20434415, extends `评估报告`)
+- `字段资产库记录`: 将反推的字段和验收结果整理并沉淀到资产库中的可检索记录  (来自 case-A_zhihu_20434415, extends `描述`)
+
+- `真人照片`: 用户提供的真人照片  (来自 case-2-test-3.5, extends `参考图`)
+- `AI人物图片`: 合规的AI人物图片  (来自 case-2-test-3.5, extends `参考图`)
+- `虚拟分身`: 在豆包APP中创建的虚拟分身  (来自 case-2-test-3.5, extends `数字人`)
+- `手绘插画或三视图`: 手绘电影分镜插画风格或三视图的合规图片  (来自 case-2-test-3.5, extends `参考图`)
+- `校色图`: 使用校色代替真人特征的合规图片  (来自 case-2-test-3.5, extends `参考图`)
+- `爆款题材案例`: 抖音、快手上已经验证过的爆款类型案例  (来自 case-2-test-3.5, extends `对标内容`)
+- `剧本创作思路`: 从爆款题材中提炼出的核心剧情梗概和风格思路  (来自 case-2-test-3.5, extends `大纲`)
+- `剧本大纲及分集剧情`: 豆包生成的15集全剧大纲和分集剧情  (来自 case-2-test-3.5, extends `大纲`)
+- `人物设定`: 豆包生成的男女主角和配角的核心人设  (来自 case-2-test-3.5, extends `描述`)
+- `人物参考图`: 苏晚和顾晏辰等核心角色的多角度、不同表情参考图  (来自 case-2-test-3.5, extends `参考图`)
+- `分镜视频列表`: 多集15秒分镜视频组成的列表  (来自 case-2-test-3.5, extends `分镜视频`)
+- `短剧视频`: 拼接、调整速度、剪掉部分镜头、添加字幕后的完整AI短剧视频  (来自 case-2-test-3.5, extends `视频成品`)
+
+- `输入内容`: 用户输入的待拆解内容  (来自 case-A_xhs_69663d9d, extends `参考图`)
+- `拆解后的图片列表结构`: 拆解后的图片逻辑结构  (来自 case-A_xhs_69663d9d, extends `参考图`)
+- `系列信息图提示词列表`: 系列信息图的生成提示词列表  (来自 case-A_xhs_69663d9d, extends `提示词`)
+
+- `intent`: AI绘画真实感优化  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `substance`: AI人物局部特写  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `form`: 图文拆解  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `action`: 特征分析与技巧提取  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `effect`: 提升AI人物真实感  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+
+- `原文正文`: 原文正文内容  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `AI人物一眼假特征列表`: AI人物一眼假特征列表  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `配图OCR文本`: 配图OCR文本  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+- `AI真实感提升关键词和提示词建议列表`: AI真实感提升关键词和提示词建议列表  (来自 case-xhs_6a1e980f000000003503a2e5, extends `?`)
+
+- `书籍名称`: 用户输入的书名  (来自 case-xhs_69e3a0f9000000002103b24a, extends `参考图`)
+- `知识卡片图`: AI生成的书籍拆解知识卡片  (来自 case-xhs_69e3a0f9000000002103b24a, extends `成品图`)
+
+- `用户需求`: 用户想要制作的国风信息图需求  (来自 case-xhs_696e01e8000000002202f8fb, extends `参考图`)
+- `设计题材与思路`: 确定的设计题材和布局思路  (来自 case-xhs_696e01e8000000002202f8fb, extends `参考图`)
+- `AI生成图表成品`: AI生成的最终国风信息可视化图表  (来自 case-xhs_696e01e8000000002202f8fb, extends `成品图`)
+
+- `用户需求`: 用户制作非遗信息图的需求描述  (来自 case-xhs_69d10d860000000020039486, extends `参考图`)
+- `AI生成图`: AI生成的非遗信息图  (来自 case-xhs_69d10d860000000020039486, extends `成品图`)
+- `非遗产品图`: 用户上传的非遗产品图片  (来自 case-xhs_69d10d860000000020039486, extends `参考图`)
+- `参考版式`: 参考的版式设计图  (来自 case-xhs_69d10d860000000020039486, extends `参考图`)
+
+- `教程原文`: 小红书教程原文  (来自 case-xhs_68e637550000000004029bf4, extends `参考图`)
+- `主视觉风格关键词`: 主视觉风格转化关键词  (来自 case-xhs_68e637550000000004029bf4, extends `提示词`)
+- `主视觉生成图`: AI生成的粘土风主视觉图  (来自 case-xhs_68e637550000000004029bf4, extends `成品图`)
+- `标题设计关键词`: 标题设计关键词  (来自 case-xhs_68e637550000000004029bf4, extends `提示词`)
+- `标题设计图`: AI生成的粘土风标题图  (来自 case-xhs_68e637550000000004029bf4, extends `成品图`)
+- `配图元素关键词`: 配图元素生成关键词  (来自 case-xhs_68e637550000000004029bf4, extends `提示词`)
+- `配图元素图列表`: AI生成的粘土风配图元素图列表  (来自 case-xhs_68e637550000000004029bf4, extends `成品图`)
+
+- `用户需求描述`: 用户输入的设计需求  (来自 case-xhs_69dcdcf6000000002301365a, extends `描述`)
+
+- `原文正文`: (无 desc)  (来自 case-A_zhihu_19067665, extends `正文`)
+- `风格框架描述`: (无 desc)  (来自 case-A_zhihu_19067665, extends `描述`)
+- `画面描述提示词`: (无 desc)  (来自 case-A_zhihu_19067665, extends `提示词`)
+- `生成图成品`: (无 desc)  (来自 case-A_zhihu_19067665, extends `成品图`)
+
+- `用户需求`: 用户对AI生成图片真实感的需求  (来自 case-A_xhs_69d51b97, extends `参考图`)
+- `提示词公式`: 用于生成真实感人像的提示词结构  (来自 case-A_xhs_69d51b97, extends `提示词`)
+- `AI生成图`: AI生成的真实感人像图片  (来自 case-A_xhs_69d51b97, extends `成品图`)
+
+- `原文正文`: 原文正文内容  (来自 case-A_xhs_6a040130, extends `知识库`)
+- `提示词分析结果`: 对AI感原因的分析  (来自 case-A_xhs_6a040130, extends `评语`)
+- `通用减AI感提示词`: 用于去除AI感的提示词  (来自 case-A_xhs_6a040130, extends `提示词`)
+
+- `模型文件`: divingZImageTurbo_v60Fp16.safetensors 基础模型权重  (来自 case-A_zhihu_20424074, extends `模型权重`)
+- `CLIP模型`: qwen_3_4b.safetensors CLIP文本编码器权重  (来自 case-A_zhihu_20424074, extends `模型权重`)
+- `VAE模型`: ae.sft VAE自编码器权重  (来自 case-A_zhihu_20424074, extends `模型权重`)
+- `已配置的ComfyUI环境`: WSL连接Windows主机上已加载好模型和配套权重的ComfyUI工作流  (来自 case-A_zhihu_20424074, extends `工作流`)
+- `提示词技巧`: 中英文提示词技巧、强调光线和材质细节、必备负面提示词等  (来自 case-A_zhihu_20424074, extends `提示词`)
+- `最佳参数配置`: Steps 9-12, CFG 1.0, Euler, Simple 等推荐生成参数  (来自 case-A_zhihu_20424074, extends `生成参数`)
+- `生成参数与提示词模板`: 包含最佳生成参数与提示词技巧的ComfyUI生成模板  (来自 case-A_zhihu_20424074, extends `模板`)
+- `风格场景列表`: 评测覆盖的十组不同风格场景的描述列表  (来自 case-A_zhihu_20424074, extends `脚本`)
+- `单组风格提示词要点`: 单组风格场景的提示词要点描述  (来自 case-A_zhihu_20424074, extends `描述`)
+- `风格人像图`: ComfyUI直接生成出来的单组风格女性写实人像样图  (来自 case-A_zhihu_20424074, extends `样图`)
+- `推荐搭配`: DetailDeamonZ-SliderLoRA、niceasiansZimage、OpenPose、Depth等LoRA与ControlNet搭配  (来自 case-A_zhihu_20424074, extends `模型权重`)
+- `最终优化人像图`: 经过LoRA、ControlNet优化并使用SUPIR或4x-UltraSharp后期放大的最终写实人像图  (来自 case-A_zhihu_20424074, extends `成品图`)
+- `综合评测报告`: 包含模型优势、不足、适用场景、不适合场景以及综合评分的评测报告  (来自 case-A_zhihu_20424074, extends `评语`)
+
+- `人像图列表`: 十组不同风格场景的亚洲女性写实人像图列表  (来自 case-A_zhihu_20424074, extends `样图`)
+
+- `原文正文`: 文章原始文本  (来自 case-A_gzh_34767dfb, extends `知识库`)
+- `提示词框架`: AI画图的提示词结构  (来自 case-A_gzh_34767dfb, extends `大纲`)
+- `AI生成图`: AI生成的最终信息图  (来自 case-A_gzh_34767dfb, extends `成品图`)
+
+- `展板原图`: 竞赛展板原始图片  (来自 case-xhs_69eb3c58000000001f031002, extends `截图`)
+- `切分板块列表`: 按展板逻辑切分后的板块列表  (来自 case-xhs_69eb3c58000000001f031002, extends `分镜脚本`)
+- `高清板块列表`: ChatGPT 生成的高清板块列表  (来自 case-xhs_69eb3c58000000001f031002, extends `分镜脚本`)
+- `拼合展板`: PS 拼合后的展板  (来自 case-xhs_69eb3c58000000001f031002, extends `图层组合`)
+- `成品展板`: 最终成品展板  (来自 case-xhs_69eb3c58000000001f031002, extends `成品图`)
+
+- `设计需求`: 展板制作的北京四合院信息可视化需求  (来自 case-xhs_6948a40c000000001e03739c, extends `提示词`)
+- `提示词框架`: 展板核心板块内容与知识解析  (来自 case-xhs_6948a40c000000001e03739c, extends `提示词`)
+- `生成图成品`: 最终生成的北京四合院信息可视化展板  (来自 case-xhs_6948a40c000000001e03739c, extends `成品图`)
+
+- `知识点提示词`: 用户输入的知识点内容  (来自 case-xhs_69e50218000000002200e44b, extends `提示词`)
+
+- `教程原文`: 原文教程  (来自 case-gzh_c34f8de4ea91891d724543886c25a75f, extends `知识库`)
+- `提示词框架`: AI生成的提示词框架  (来自 case-gzh_c34f8de4ea91891d724543886c25a75f, extends `提示词`)
+- `生成图`: AI生成的初步图片  (来自 case-gzh_c34f8de4ea91891d724543886c25a75f, extends `底图`)
+- `优化后信息图`: 人工优化后的信息图  (来自 case-gzh_c34f8de4ea91891d724543886c25a75f, extends `成品图`)
+
+- `视觉信息图成品`: ProcessOn AI 生成的视觉信息图  (来自 case-gzh_2504ec0f40b34505227c5cd4be2303dc, extends `成品图`)
+
+- `需求描述`: 用户对图表类型、核心模块、模块关系、风格及输出要求的描述  (来自 case-gzh_34767dfbf64944f44eccd18ec2129812, extends `描述`)
+- `图表要素清单`: 从需求中提取的图表类型、模块、关系等要素清单  (来自 case-gzh_34767dfbf64944f44eccd18ec2129812, extends `大纲`)
+- `最终成品图`: 经过后期优化调整后的最终信息图  (来自 case-gzh_34767dfbf64944f44eccd18ec2129812, extends `成品图`)
+
+- `用户需求描述`: 职场信息图的初步构思  (来自 case-A_gzh_34767dfb, extends `提示词`)
+- `具体场景应用示例列表`: 五大典型场景的示例  (来自 case-A_gzh_34767dfb, extends `模板`)
+- `风格化调整指南`: 不同场景下的风格调整建议  (来自 case-A_gzh_34767dfb, extends `知识库`)
+- `文章/笔记内容`: 待总结的原始文章内容  (来自 case-A_gzh_34767dfb, extends `提示词`)
+- `知识卡片图`: 总结后的知识卡片  (来自 case-A_gzh_34767dfb, extends `成品图`)
+
+- `改写主题`: AI改写提示词的主题列表  (来自 case-gzh_76e957e88deb584843889d1392a2fc5a, extends `提示词`)
+- `提示词列表`: AI改写生成的提示词模版列表  (来自 case-gzh_76e957e88deb584843889d1392a2fc5a, extends `提示词`)
+
+- `提示词描述`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `提示词`)
+- `信息图成品图`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `成品图`)
+- `业务流程描述`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `描述`)
+- `项目管理流程图成品图`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `成品图`)
+- `概念解释文本`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `描述`)
+- `概念解释图成品图`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `成品图`)
+- `部署需求描述`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `描述`)
+- `部署方式对比图成品图`: (无 desc)  (来自 case-gzh_95a965c6b06e4d001214d1c110f0c569, extends `成品图`)
+
+- `产品图`: 客户提供的原始产品图片  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `参考图`)
+- `产品场景合成图`: AI生成的包含产品和场景的合成图  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `合成图`)
+- `文字信息`: 海报所需的文案信息  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `描述`)
+- `AI排版海报`: AI自主排版生成的初步海报  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `成品图`)
+- `最终海报成品`: 设计师PS优化后的最终海报  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `成品图`)
+- `版式技巧`: 整理的排版设计技巧  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `知识库`)
+- `教程推广图`: 用于推广教程的海报  (来自 case-gzh_9ddd55069eda0e211952e56a4c9575b0, extends `成品图`)
+
+- `笔记内容`: (无 desc)  (来自 case-gzh_58a26a6991c8af72ce1d9c5269f630dc, extends `正文`)
+- `HTML代码`: (无 desc)  (来自 case-gzh_58a26a6991c8af72ce1d9c5269f630dc, extends `成品图`)
+- `图片成品`: (无 desc)  (来自 case-gzh_58a26a6991c8af72ce1d9c5269f630dc, extends `成品图`)
+- `Markdown代码`: (无 desc)  (来自 case-gzh_58a26a6991c8af72ce1d9c5269f630dc, extends `成品图`)
+
+- `教程原文`: (无 desc)  (来自 case-gzh_d462098b1d656f156cb7152a9a5e8a9b, extends `知识库`)
+- `信息图结构`: (无 desc)  (来自 case-gzh_d462098b1d656f156cb7152a9a5e8a9b, extends `大纲`)
+- `布局提示词框架`: (无 desc)  (来自 case-gzh_d462098b1d656f156cb7152a9a5e8a9b, extends `提示词`)
+- `优化后提示词`: (无 desc)  (来自 case-gzh_d462098b1d656f156cb7152a9a5e8a9b, extends `提示词`)
+
+- `信息图`: 复杂信息可视化图解  (来自 case-gzh_04797d4d2716bdddf94cef980dbd559a, extends `成品图`)
+
+- `提示词模板`: 去AI味视频提示词公式与参数模板  (来自 case-A_xhs_69d51b97, extends `模板`)
+
+- `自拍照片`: 用户上传的日常自拍  (来自 case-A_gzh_3443445b, extends `参考图`)
+- `AI模型选择结果`: 用户选择的AI模型配置  (来自 case-A_gzh_3443445b, extends `提示词`)
+- `个性化参数设置结果`: 用户设置的个性化参数  (来自 case-A_gzh_3443445b, extends `提示词`)
+- `风格选择结果`: 用户选择的风格模板  (来自 case-A_gzh_3443445b, extends `提示词`)
+- `专业人像成品图`: AI生成的专业人像成品图  (来自 case-A_gzh_3443445b, extends `成品图`)
+
+- `编辑指令`: 用户对图片进行P图操作的指令  (来自 case-A_gzh_d6cb8419, extends `提示词`)

+ 246 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools.md

@@ -0,0 +1,246 @@
+# 脚本怎么用(工具手册)
+
+> 跑这道 skill 时会用命令行调用几个脚本,这里讲它们**怎么用**。脚本都在 `spec/tools/` 下,**你不用读脚本源码,会调就行**。
+
+## 1. `spec/tools/wf-patch.py` — workflow.json 安全批量字段设置器
+
+**做什么**:批量给 `workflow.json` 的步骤/输入输出填字段(第一阶段连"来源",第二阶段填作用/动作/类型/实质/形式)。**凡是"给一批字段赋值"都用它,别写 Python 脚本去拼/改 workflow.json**(脚本拼 JSON 容易把文件弄坏)。分工:**你出判断(哪个字段填什么),工具负责安全写入 + 当场检查对错**。
+
+**两个保证**:
+- **不会写坏文件**:由工具读取→修改→写回,你从不直接碰 JSON 文本。
+- **当场检查,有错全不写**:每条赋值都立刻对照词表/类型登记/格式校验;**只要有一条不合法,就报出是哪条、整批都不写**(不会产出悄悄出错的文件)。检查规则和最后的 lint 一致——**这里通过了,lint 一定过**。
+
+**用法**:
+```bash
+# 单条 / 多条 --set (path=value, 只在第一个 = 处切; value 可含 = 和空格, 整体加引号)
+python spec/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json \
+    --set 'p1.s1.inputs[0].anchor=← s0.主角图' \
+    --set 'p1.s2.effect=主体生成' \
+    --set 'p1.s2.action=生成/图像生成/文生图'
+
+# 批量: 几十处 anchor / 字段一次过 — 写一份 patch 清单 (你仍逐条显式决策每个值), 一条命令应用
+# 推荐加 --prune: 成功的项自动从 patch 文件删掉, 失败的留下并标 _error 原因 → 文件即"剩余待修清单"
+python spec/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json --patch _scratch/anchors.json --prune
+#   anchors.json = [{"path":"p1.s1.inputs[0].anchor","value":"← s0.x"}, ...]
+
+# 只校验不写
+python spec/tools/wf-patch.py --workflow ... --set '...' --dry-run
+
+# 透传回填: anchor 设好后, 自动把"原样透传"的 value/directive 从源逐字抄过来
+python spec/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json --resolve-passthrough
+
+# 建骨架: 缺失的 procedure/step/IO 元素**默认自动创建 (upsert)**、文件不存在也从空建 —— 不必 write_file 手写嵌套 JSON
+python spec/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json --patch _scratch/skeleton.json
+#   skeleton.json = 扁平 [{"path":"p1.s1.inputs[0].type","value":"参考图"}, ...]: 列全所有 step/IO 路径, 一条命令建出整个骨架
+#   (你只写扁平清单——工具负责拼成合法嵌套 JSON; output 的 id 会自动补 sNo1)
+#   ⚠️ 默认自动建; 只有「纯填已存在结构、想抓路径 typo」时才加 --no-create (路径不存在就报错)
+
+# @quote 回填 --resolve-quotes: value/directive 写短标记 @quote|起锚|止锚 (或 @quote|关键词),
+#   工具顺标记从 --source 原文 / --ocr 配图文本匹配真实内容【批量替换】(省得手动粘长内容; 跟 anchor patch 一起跑)
+python spec/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json --patch _scratch/anchors.json \
+    --resolve-quotes --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt
+```
+
+> **`@quote` 回填(强烈推荐填真实 value/directive 的方式)**: 别手动 quote-source 再粘长内容——直接把 value/directive 的值设成 `@quote|<起锚>|<止锚>`(两个独特短串, 框出原文那段)或 `@quote|<关键词>`(命中落 JSON 块返回整块, 否则返回所在行/段), 然后跑 `--resolve-quotes --source <原文> [--ocr <ocr.txt>]`, 工具按空白无关匹配从原文/配图把真实内容**一次性批量**替换进去。匹配不到会 `⚠` 提示(标记原样留着, 回去改锚点)。
+
+**`--resolve-passthrough`(省得重复抄内容)**:规矩是"值"要写真实内容,不能写"(同上)""见 s1o1"这类引用(那是"来源"该干的,lint 会报)。但同一段内容被后面好几步原样复用时,手抄好几遍很烦。用这个:**只在源头那个输出里填一次真内容**,其余引用处把"来源"设成 `← 源的编号`,工具就顺着编号把真内容**逐字抄到**每个"值"还空着的输入(链式引用也会一路抄到底)。源头找不到的会用 `⚠` 提示。可单独跑,也可跟在 `--set/--patch` 后面。
+
+**`--prune`(把 patch 文件变成"剩余待修清单")**:跟 `--patch` 配合。wf-patch 本就是"值合法的照写、不合法的跳过(进度不丢)"。加 `--prune` 后,**应用成功的条目从 patch 文件里删掉**(它们已落盘 workflow.json,留着只会重复应用),**没成功的留下并每条带 `_error` 失败原因**。于是修复循环变成:`--patch ... --prune` → 看文件里还剩哪几条 + 为什么挂(`_error`)+ 报错末尾的合法值清单 → 只改这几条的 value → 重跑同一文件 → 直到文件清空为 `[]`(报「patch 已全部完成」exit 0)。不用再从 console 输出里考古哪条挂了,也别整批重写。注:`--dry-run` 不动文件;结构错(路径对不上)整批未应用时不裁剪(都还 pending)。
+
+**路径语法** (**文档统一用 id 式** `pN.sM.字段`: proc 用 id `p1`、step 用 id `s1`、`inputs/outputs` 才用 `[i]` 下标、嵌套步 id 带点如 `s2.1`。**下标式 `procedures[N].steps[M].inputs[i].字段` 工具也接受**——镜像 workflow 结构时不会挂):
+
+| 路径 | 设的字段 |
+|---|---|
+| `p1.s2.effect` | step 标量 (effect / substance / form / via / action / directive / kind / intent / group) |
+| `p1.s1.inputs[0].anchor` | IO 字段 (anchor / type / value / id) |
+| `p1.s2.1.outputs[0].type` | 嵌套步的 IO |
+| `p1.s2.focus` | step 的 focus 数组 (逗号分隔: `focus=via,action,out-type-0`) |
+| `p1.purpose` | procedure 头部 (name / purpose / category / platform / author) |
+| `p1.declarations.inputs[0].desc` | declarations 内任意字段 (通用下钻) |
+| `source.url` | case-level 原帖信息 (platform / author / date / url / title / excerpt) |
+| `p1.type_registry.场景图.extends` | 注册 case-specific 类型 (自动建 type_registry 段) |
+
+⚠️ **`--set` 别用单引号包参数**(Cyber 引擎跑 cmd.exe,**不剥单引号** → 路径会带个 `'` → 报「找不到 procedure id='p1」)。工具已兜底自动剥成对引号,但仍建议:值含空格/特殊字符用**双引号**,或干脆把一批改动写进 `--patch` 清单文件(JSON,无引号坑)。
+
+**`--unset PATH`** (删字段, 可重复): 删掉某字段, 取代手 Edit 删. e.g. `--unset p1.declarations.inputs[0].inferred` (declarations 不收 inferred, schema 会拒). 字段本就不存在 → 跳过 (幂等, 不报错).
+
+**各字段校验规则**:
+- `effect` → effect.json 叶子 (给全路径会自动归一到叶名)
+- `action` → action.json 叶子 / 叶路径 (给叶名自动展开成全路径)
+- `type` → **自由文本, 不校验**(Phase 1 随便起描述标签;归一到标准叶子 / 注册 type_registry 是 Phase 2 的事,最终由 lint Check 1 + render schema 兜底)
+- `extends` → 必须桥到 type.json 叶子
+- `substance` / `form` → 自由提炼的元素点 (字符串或数组), **不查词表、不校验**; `url` → 自由文本; 三者均可传 `__null__` 设 JSON null
+- `anchor` → 必须 `←` (输入引用, 指向某 output id) 或 `→` (输出去向) 开头
+- `kind` → {step / block / nested}
+- `focus` → 逗号分隔 → 数组 (空串 → `[]`)
+- 其余 (name / value / intent / via / desc / purpose / ...) → 自由文本, 不校验
+
+**骨架创建推荐用 `--create`**(免手写嵌套 JSON, 见上)。**仍可用 Write 从 template 写骨架, 但弱模型易漏逗号崩 JSON, 不推荐**。 改字段 / 删字段 / 改 source 现在都走 wf-patch (`directive` 也是普通标量字段, 直接 `--set`), **不要再 Read→Edit 改 workflow.json** (那会反复重读、烧 token).
+
+**退出码**: `0` 全通过并写入 (或 `--dry-run` 通过) / `1` 有校验失败 (整批未写) / `2` CLI 错 / 文件不存在 / JSON 损坏.
+
+---
+
+## 1.5 `spec/tools/quote-source.py` — 原文片段捞取 (填 value / directive 用)
+
+**做什么**: value / directive 要填原文真实内容(那段 JSON 风格分析、那句完整提示词)时, 用它按字符匹配从原文 case json 把那段**逐字捞出来**再粘进 workflow.json。别凭记忆缩写、别写 `<JSON 数据>` 这种空壳。
+
+**匹配空白无关**: 原文 body_text 常有乱换行 / 前导空格, 工具匹配时忽略所有空白, 但返回的是**原文逐字片段**。
+
+**用法**:
+```bash
+# 普通: 按关键词捞周边 (默认前后各 300 字)
+python spec/tools/quote-source.py --source input/case-{N}.json --query "视觉风格分析"
+# 捞整段 JSON: 命中点落在 {...} 内时返回整块 (适合捞结构化分析)
+python spec/tools/quote-source.py --source input/case-{N}.json --query "视觉风格分析" --json-block
+# 捞一句完整提示词当 directive
+python spec/tools/quote-source.py --source input/case-{N}.json --query "结构化数据的形式"
+# 范围引用: 用首尾两个短锚点引出之间的整段长原文 (比 --window 猜长度精确, 适合整段 JSON / 多段提示词)
+python spec/tools/quote-source.py --source input/case-{N}.json --from "请以 JSON" --to "500 字以内"
+python spec/tools/quote-source.py --source input/case-{N}.json --from "视觉风格分析" --to "电影感人像"
+# 放宽窗口 (关键词模式)
+python spec/tools/quote-source.py --source input/case-{N}.json --query "主色调" --window 800
+# 连配图 OCR 文本一起搜 (prompt/JSON/参数常只在截图里, 不在 body_text)
+python spec/tools/quote-source.py --source input/case-{N}.json --query "主色调" --ocr outputs/case-{N}/_scratch/ocr.txt
+```
+
+> **关于 `--ocr`**: runner 执行前会把每张配图 OCR 成文本落到 `outputs/case-{N}/_scratch/ocr.txt`。带上 `--ocr <该文件>` 就能在原文 body_text **和图片文字**里一起搜(命中分别标 `[原文]` / `[配图OCR]`)。
+
+**小贴士**: query 用**一段独特的短语**(4-10 字)最稳; 整句带标点时可能因全/半角差异落到 `~approx`(仍返回最接近的一段, 核对即可)。
+
+**退出码**: `0` 有命中(含 approx) / `1` 找不到 / `2` CLI/IO 错。
+
+---
+
+## 2. `spec/tools/render-case.py` — 阶段三 workflow.json → HTML 渲染 + schema 校验
+
+**用途**: 阶段三. 接收 `workflow.json` (多工序 `procedures:[]`), 在内存组装成 case_data (merge `--source-input` 原帖 + `--page-title` + `--case-id`), 跑 schema 校验, 渲染输出 HTML. **不落盘 case_data.json**.
+
+**Agent 用法** (推荐): workflow.json 已含全部 procedures + 标注后:
+
+```bash
+# 1. 只校验, 看 schema 错 (建议带 --source-input, 让校验看到的就是 merge 后的最终版)
+python spec/tools/render-case.py \
+    --workflow outputs/case-{N}/workflow.json \
+    --source-input input/case-{N}-raw.json \
+    --page-title "Case {N} · <主题>" \
+    --case-id {N} \
+    --validate
+
+# 2. 校验通过后渲染输出 (--source-input 必带, 否则 HTML 折叠原文区只剩 60 字 excerpt)
+python spec/tools/render-case.py \
+    --workflow outputs/case-{N}/workflow.json \
+    --source-input input/case-{N}-raw.json \
+    --page-title "Case {N} · <主题>" \
+    --case-id {N} \
+    --out outputs/case-{N}/case-{N}-<slug>.html
+```
+
+**关于 `--source-input`** (2026-05-22 新增): renderer 直接从原帖 raw json 抽 `body_text` + 封面 + 图集兜底, in-place 填到 `case_data.source` —— Agent 不必手工复制原文内容. 行为:
+- `body_text` / `cover_image` 直接覆盖 case_data 同字段
+- `title` / `url` 仅在 case_data 缺时填
+- `excerpt` / `author` / `date` / `platform` **不动** (那些是 Agent 推断的友好版本)
+- **图集兜底**: 检查 raw.body_text 已 inline 的 `[image:URL]` 标记, 把 raw.image_url_list 里没 inline 也不是封面的图 append 到 body 末尾 (加 `--- 附图 ---` 分隔符). 适配"小红书短文 + 多图独立列" 和 "微信公众号长文 + inline 图" 两种平台
+
+**输入契约**: 见 [`spec/format/case-data.schema.json`](format/case-data.schema.json) (canonical JSON Schema Draft 2020-12, 受控字段 + enum + 条件约束 `if/then`).
+
+**模板**: 见 [`README.md`](README.md) 的「workflow.json 结构」节 (canonical 骨架, 含 source / procedures / steps / IO 各字段).
+
+⚠ **绝对不要参考其他 `outputs/case-*/` 下的产物文件当模板** — 那些是 case-specific 产物. 唯一 canonical 骨架在 README「workflow.json 结构」节.
+
+**输出码**:
+- `0` — 成功 (渲染或校验通过)
+- `1` — IO / schema / 渲染异常
+- `2` — CLI 参数错误
+
+**依赖**:
+- 必需: `spec/tools/renderer.py` (跟本脚本同目录, 自动 import)
+- 可选: `jsonschema` (装了用 Draft 2020-12 完整校验; 没装走 minimal check fallback)
+
+---
+
+## 3. `spec/tools/lint-case.py` — 轻量 lint + 自动 record 新 type
+
+**用途**: 阶段三. 跑完 `render-case.py` 后跑一次. 干八件事:
+0. **归类完成度 hint**: 每个非控制块步骤要有 effect+action、有 IO 的步骤 intent 要用标记格式 (Phase 2.1 做完没; runner 的自动续跑兜底也消费这条, 经 `--json`)
+0b. **@quote 残留 hint**: value/directive 里没解析成功的 `@quote|...` 标记 (锚点没匹配上, wf-patch 只警告不拦) — render-case 同时把它当硬门禁, 残留即拒绝出 HTML
+1. **type 完整性 hint**: 扫 workflow.json 各 procedure 的 IO type 字段, 找出"用了 case-specific type 但该 procedure 的 `type_registry` 漏注册 / 缺 extends / 缺 desc"的情况, 打 stdout 给 Agent / 用户看
+2. **value 自包含 hint**: 扫每个 IO 的 value + 每个 directive, 揪出「(同 sN 输出)」「见 sN」「← sN」这类**引用占位** —— spec 要求 value 逐字回填数据本身 (引用归 anchor), 这种占位 schema/type 检查抓不到. 命中会提示跑 `wf-patch.py --resolve-passthrough` 自动回填
+3. **value/directive 真实性 hint**: 揪出 `<…>` 占位 value、以及工具步骤(`via` 是具体工具)**缺失的 directive**, 提示用 `quote-source.py` 从原文/配图 OCR 捞真内容回填(弱模型常把 value 全填 `<…>` 占位、漏 directive)。
+4. **章节覆盖 hint (结构强制, 需 `--source`)**: 按原文 `0N` 章节标号切段, 逐章节算骨架覆盖率, 把整段漏抽的章节(<40%)报出来 —— 弱模型"按成品图扫"常漏掉**无独立成品图的框架/案例章节**. 缺 `--source` 则跳过.
+5. **value 逐字 hint (值强制, 需 `--source`)**: 文本类 value 应是原文里**一整段连续文本**; 算"最长连续命中原文"比例, <80% 判**缩写/改写/截断**(典型: 抄了开头第一句、后面用原文小标题拼盘)并报出, 提示用 `@quote` 重填. 缺 `--source` 则跳过.
+6. **副作用: auto-record**: 把各 procedure.type_registry 里的 case-specific entry 自动 append 到 `spec/taxonomy/type_suggestions.md` 累积条目段 (Agent **不必手工 Write** suggestions, 工具代劳)
+
+**幂等**: dedup key = `(type_name, case_id)` 二元组. 同 case 重跑不重复; 不同 case 同名允许 (跨 case 频次是升级信号).
+
+**用法**:
+```bash
+# 推荐: 带 --source 原文(+ --ocr 配图文本)才会跑「章节覆盖」+「value 逐字」两条结构/值强制
+python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N} \
+    --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt
+
+# 不带 --source: 只跑前 3 项 + record (结构/值强制跳过)
+python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N}
+
+# 只检测不写
+python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N} --no-record
+
+# 机器可读 (runner / 脚本消费): {"checks": {检查名: [提示...]}, ...}
+python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N} --json --no-record
+```
+
+**输出范例** (case 含 silent gap 的情况):
+```
+[lint] case-1 (workflow.json)
+  · type 完整性: 2 个提示
+      - [p1] step[1].outputs[0].type='主角图' 是 case-specific 但该 procedure 的 type_registry 没注册
+      - [p1] step[8].inputs[1].type='主角图' 是 case-specific 但该 procedure 的 type_registry 没注册
+  · 无新 type 可 record (type_registry 为空 — 全部 type 命中字典叶子)
+```
+
+**退出码**: 始终 0 (不阻塞流程). 解析 2 = CLI 参数错 / 文件不存在.
+
+**设计哲学**: 不严格. 检测项是 hint 不是 fail; record 是副作用不是核心契约. Agent 看 stdout 决定回不回去补 case_data.type_registry.
+
+---
+
+## 4. `spec/tools/renderer.py` — HTML 渲染主模板 (Python 模块)
+
+**做什么**:把数据渲染成网页的主程序,被 `render-case.py` 在内部调用。
+
+**你不用读它**——通过 `render-case.py` 调用即可。要了解格式,看 [`format/case-data.schema.json`](format/case-data.schema.json)(机器清单)和 [`README.md`](README.md)「workflow.json 结构」节(格式说明)就够了。
+
+---
+
+## 5. `run_procedure_dsl.py` — runner 本身 (不在 skill 内)
+
+跑 Agent 的入口脚本. **Agent 不读它** — 它在跑 Agent. 但 Agent 可能想知道**自己被怎么起的**:
+
+- OAuth Max 模式 (走 ~/.claude 凭证, 不计 API 费)
+- `allowed_tools = ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]`  # 单 Agent 全程, 不开 Task/Agent (第二阶段不再用子助手, 见 §7)
+- `permission_mode = "bypassPermissions"` (Agent 全自动, 不停下来问)
+- `cwd = procedure-dsl/` (Agent 的工作目录)
+- `--resume` 支持 (中断后续跑)
+- runner 实时把每 turn 写到 `outputs/case-{N}/_trace.md`
+
+---
+
+## 6. 文件路径约定 (per case)
+
+| 路径 | 内容 | 谁负责 |
+|---|---|---|
+| `input/case-{N}-raw.json` | 原 case 素材 (title / link / body_text / image_url_list / ...) | 人 (Agent 读, 不写) |
+| `outputs/case-{N}/` | Agent 工作目录 (一 case 一目录) | Agent (写产物) |
+| `outputs/case-{N}/.session_id` / `.trace_id` | 续跑凭据 (`--resume` 用; Claude SDK 路写 .session_id, Cyber 路写 .trace_id) | runner 写, Agent 不动 |
+| `outputs/case-{N}/_trace.md` | runner 写的实时执行流水 | runner (Agent 别 Read) |
+| `outputs/case-{N}/_scratch/` | **sanctioned scratch 区** — 只用于 dump 大 Bash 输出 (taxonomy --subtree 长结果 / find 结果) 之后 Read 切片, 或一次性 smoke test. runner 预创建. **不要用项目根的 `scratch/`**. ⚠ **不是写 build/normalize 脚本生成 workflow.json 的地方** —— 那个用 §2 `wf-patch.py` | Agent (随便 dump, 跟着 case 一起清理) |
+| `outputs/case-{N}/understanding.md` | 阶段一 1.1 心智模型 (Claude SDK 路 Agent 手写; **Cyber 路不产它** — 计划经 `plan_procedures` 提交, 留档在 `_scratch/understanding.json`) | Agent / plan 工具 |
+| `outputs/case-{N}/workflow.json` | **唯一中间产物** — Phase 1.2 用 `wf-patch.py --create` 建骨架 (扁平清单, 免手写嵌套 JSON; 也可 Write 模板但易错), 之后**逐字段演化**: 批量结构化字段 (1.3 anchor / 2 effect·action·type + step 级 substance·form) 用 `wf-patch.py`, 单处零星用 Edit. **绝不写 Python 脚本生成 / 批改它**. 符合 case-data.schema.json (`procedures:[]`) | Agent |
+| `outputs/case-{N}/case-{N}-<slug>.html` | 阶段三 .html 输出 (跑 render-case.py 生成; **唯一产物, .md 已取消**) | render-case.py |
+
+---
+
+## 7. 第二阶段不再用子助手
+
+第二阶段(作用/动作/类型 归类 + 实质/形式 提炼)现在**由主流程自己一趟做完**——不再切任务、不再召唤子助手、不再查"实质/形式"大词表(实质/形式 改为自由提炼元素点)。具体见 [README.md](README.md) 的「第二阶段」章节。
+

+ 802 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/lint-case.py

@@ -0,0 +1,802 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+lint-case.py — workflow.json 轻量 lint + 自动 record 新 type 到 type_suggestions.md.
+
+设计哲学: **不严格**.
+  - 不分 error/warning 等级, 不卡 exit code (都返 0)
+  - 主要副作用是 record 新 type 到 spec/taxonomy/type_suggestions.md
+  - 检测项打 stdout 给 Agent / 用户看, 决定要不要回去修
+
+用法:
+    python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N}
+    python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N} --no-record   # 只校验不写
+    python spec/tools/lint-case.py --workflow ... --case-id {N} --json   # 机器可读输出 (runner 完成度判据消费)
+
+退出码:
+    0  始终 (不阻塞流程)
+    2  CLI 参数错误 / 文件不存在
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import re
+import sys
+from pathlib import Path
+
+# spec/tools/lint-case.py → procedure-dsl/
+DSL_ROOT = Path(__file__).resolve().parent.parent.parent
+TYPE_JSON = DSL_ROOT / 'spec' / 'taxonomy' / 'type.json'
+SUGGESTIONS = DSL_ROOT / 'spec' / 'taxonomy' / 'type_suggestions.md'
+
+
+# Windows 控制台 UTF-8
+for _s in (sys.stdout, sys.stderr):
+    if hasattr(_s, 'reconfigure'):
+        try:
+            _s.reconfigure(encoding='utf-8', errors='replace')
+        except Exception:
+            pass
+
+
+def load_type_leaves() -> set[str]:
+    """读 spec/taxonomy/type.json 的 $leaves 集合."""
+    if not TYPE_JSON.exists():
+        return set()
+    return set(json.loads(TYPE_JSON.read_text(encoding='utf-8')).get('$leaves', []))
+
+
+# ===========================================================================
+# Check 1: type 完整性提示
+# ===========================================================================
+
+def _iter_procedures(case_data: dict):
+    """遍历 workflow.json 的 procedures.
+
+    Yields: (procedure_label, procedure_dict) — 含 steps + type_registry.
+    """
+    for p in case_data.get('procedures') or []:
+        label = p.get('id') or p.get('name') or '?'
+        yield (label, p)
+
+
+def check_type_completeness(case_data: dict) -> list[str]:
+    """IO 用了 case-specific type 但 type_registry 漏写 entry → 提示.
+
+    只 hint 不 fail. Agent 看输出回去修.
+    多工序时, hint 前缀加 [proc_id] 让用户知道是哪个工序的问题.
+    """
+    leaves = load_type_leaves()
+    hints: list[str] = []
+
+    for proc_label, proc in _iter_procedures(case_data):
+        type_reg = proc.get('type_registry') or {}
+
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, item in enumerate(step.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    t = item.get('type', '') or ''
+                    if not t:
+                        continue
+                    if t in leaves:
+                        continue   # 字典叶子, OK
+                    if t not in type_reg:
+                        hints.append(
+                            f"[{proc_label}] step[{i}].{kind}[{j}].type={t!r} 是 case-specific "
+                            f"但 type_registry 没注册"
+                        )
+                    else:
+                        entry = type_reg[t]
+                        if isinstance(entry, dict):
+                            if not entry.get('extends'):
+                                hints.append(f"[{proc_label}] type_registry[{t!r}] 缺 extends 字段")
+                            if not entry.get('desc'):
+                                hints.append(f"[{proc_label}] type_registry[{t!r}] 缺 desc 字段 (renderer drawer 显示需要)")
+    return hints
+
+
+# ===========================================================================
+# Check 2: value / directive 自包含性 (禁止引用占位)
+# ===========================================================================
+
+# value/directive 应填数据本身, 不是 anchor 的引用. 命中即「没真正回填」.
+META_REF = re.compile(r'[((]?\s*同\s*s[\d]|见\s*s[\d]|←\s*s[\d]|同上')
+
+
+def check_value_selfcontained(case_data: dict) -> list[str]:
+    """扫每个 IO 的 value + 每个 directive, 找「引用占位」文案 (同 sX / 见 sX / ← sX ...).
+
+    spec: value 逐字回填数据本身, 引用归 anchor (README「第二阶段 · 2.0.2 连数据流」).
+    这种占位 schema/type 检查抓不到, 专门一条. 只 hint. 可用
+    `wf-patch.py --resolve-passthrough` 自动从源回填.
+    """
+    hints: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, item in enumerate(step.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    v = item.get('value')
+                    if isinstance(v, str) and META_REF.search(v):
+                        hints.append(f"[{proc_label}] step[{i}].{kind}[{j}].value 是引用占位 {v[:24]!r} — 应逐字回填数据本身")
+            t = step.get('directive')
+            if isinstance(t, str) and META_REF.search(t):
+                hints.append(f"[{proc_label}] step[{i}].directive 是引用占位 {t[:24]!r} — 应填实际 prompt 原文")
+    return hints
+
+
+# ===========================================================================
+# Check 2b: anchor 闭合 (透传输入回填了没 + anchor 格式对不对)
+# ===========================================================================
+
+# JSON 路径式 anchor (错): ← p1.s1.outputs[0] / ← s3.inputs[1] / ...outputs[0].id;
+# 正确写法是输出**编号** ← s1o1 (或 ← 工序输入 / ← sNoM[i])。只认 .outputs[/.inputs[ 这种
+# 明确的路径序列化, 不误伤 ← s2.正向提示词 这类按名引用、← s5o1[-1] 这类带索引的合法编号。
+_ANCHOR_JSONPATH = re.compile(r'\.(?:outputs|inputs)\[')
+
+
+def check_anchor_closure(case_data: dict) -> list[str]:
+    """透传输入(带 ← anchor)有没有真把 value/type 回填 + anchor 是不是写成了 JSON 路径。
+
+    case-2-test-1 暴露的静默丢数据: 模型给输入设了 anchor 却——
+      A. 漏跑 `wf-patch --resolve-passthrough` → value/type 一直空, verify/lint 当时都没拦;
+      B. anchor 写成 JSON 路径 `← p1.s1.outputs[0]` 而非编号 `← s1o1` → resolve 永远匹配不上。
+    两者都是**确定性**判断(空/非空、是不是路径), 适合做硬门禁(render 前也跑, 逼回填)。
+    只查输入(透传方向 ←); 按名引用 `← s2.正向提示词`、带索引 `← s5o1[-1]` 都放行。
+    """
+    issues: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for j, io in enumerate(step.get('inputs') or []):
+                if not isinstance(io, dict) or io.get('inferred'):
+                    continue
+                anchor = (io.get('anchor') or '').strip()
+                if not anchor.startswith('←'):
+                    continue
+                ref = anchor[1:].strip()
+                # B. JSON 路径式 anchor (resolve 永远匹配不上)
+                if _ANCHOR_JSONPATH.search(ref):
+                    issues.append(
+                        f"[{proc_label}] step[{i}].inputs[{j}] anchor={anchor[:32]!r} 是 JSON 路径写法 — "
+                        f"数据流来源要用**输出编号**(如 ← s1o1), 不是 ← p1.s1.outputs[0]; "
+                        f"否则 --resolve-passthrough 匹配不到、value 永远空")
+                    continue
+                # 外部/工序输入 (← 工序输入 / ← 输入) 是参数, 上游无 step 输出可抄, value 可空 → 不强制
+                ref_base = ref.split('[')[0].strip()
+                if ref_base in ('工序输入', '输入') or ref_base.startswith('工序输入'):
+                    continue
+                # A. 引用了上游 step 输出却 value/type 空 = 透传没回填
+                v, t = io.get('value'), io.get('type')
+                v_empty = v is None or (isinstance(v, str) and not v.strip())
+                t_empty = t is None or (isinstance(t, str) and not t.strip())
+                miss = [n for n, e in (('value', v_empty), ('type', t_empty)) if e]
+                if miss:
+                    issues.append(
+                        f"[{proc_label}] step[{i}].inputs[{j}] 有 ← anchor({anchor[:20]!r}) 但 {'/'.join(miss)} 空 — "
+                        f"透传没回填: 跑 `wf-patch.py --resolve-passthrough` 顺编号自动抄上游内容, "
+                        f"或确认 anchor 指向的输出本身非空")
+    return issues
+
+
+def check_skeleton_filled(case_data: dict) -> list[str]:
+    """Phase 1 干骨架(via/value/anchor 空)必须由 Phase 2.0 填满, 这些空字段不该活到 render。
+
+    case-2-test-2 暴露的「填充整体没做」: 步骤 via 空、输入 value 和 anchor 都空——schema 把它们
+    声明成无 minLength 的 string, 空串合法; 占位门禁只抓 <占位>; anchor 门禁只查带 ← 的输入,
+    于是「连 ← 都没有、value 也空」的纯骨架残留一路漏到成品。这条专补这个洞:
+      - kind=step/nested 的 via 空 = 步骤没工具(控制块 kind=block 用 via='-' 合法, 不算);
+      - kind=step/nested 的 inputs / outputs **数组为空** = 步骤没有输入或没有产物
+        (README: 步骤=对已有数据执行操作产生新产物 — 没 IO 的"步骤"是骨架洞, 不是步骤;
+        ⚠ 只查每条 IO 的质量会教模型"删掉报错的条目"过关, 所以必须同时查条目存在性);
+      - IO 的 type 空 = 没标签 (Phase 1 就该有粗略标签);
+      - 输入 value 和 anchor 都空 = 既无内容(字面量)也无来源(数据流);
+      - 输出 value 空 = 这步没产物。输出的 → anchor 是去处不是内容, 所以输出**必须有 value**
+        (文本类逐字内容 / 媒体类 <描述>), 没有"用 anchor 顶替"的退路。
+    都是确定性判断, 适合做硬门禁。inferred IO 豁免 (条目级); 整条 IO 确实不存在时
+    用 inferred:true 的条目显式补上, 不允许留空数组。
+    """
+    issues: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            kind = step.get('kind', 'step')
+            via = (step.get('via') or '').strip()
+            if kind in ('step', 'nested') and not via:
+                issues.append(
+                    f"[{proc_label}] step[{i}](id={step.get('id')}) via 空 — 步骤要写用的工具"
+                    f"(如 nano_banana / human / 剪映); 只有控制块 kind=block 才用 via='-'")
+            if kind in ('step', 'nested'):
+                for io_kind, label in (('inputs', '输入'), ('outputs', '输出')):
+                    if not step.get(io_kind):
+                        issues.append(
+                            f"[{proc_label}] step[{i}](id={step.get('id')}) {io_kind} 为空数组 — "
+                            f"步骤必有{label}(对已有数据操作→产生新产物); 用 wf-patch 补上这条 IO "
+                            f"(原文没明写就按工艺推断, 标 inferred:true + inferred_reason), **不要**为过校验而删 IO")
+            for io_kind in ('inputs', 'outputs'):
+                for j, io in enumerate(step.get(io_kind) or []):
+                    if isinstance(io, dict) and not str(io.get('type') or '').strip():
+                        issues.append(
+                            f"[{proc_label}] step[{i}].{io_kind}[{j}] type 空 — 每个 IO 都要有类型标签"
+                            f"(Phase 1 粗略标签即可, Phase 2 归一到词表)")
+            for j, io in enumerate(step.get('inputs') or []):
+                if not isinstance(io, dict) or io.get('inferred'):
+                    continue
+                v, a = io.get('value'), (io.get('anchor') or '').strip()
+                v_empty = v is None or (isinstance(v, str) and not v.strip())
+                if v_empty and not a:
+                    issues.append(
+                        f"[{proc_label}] step[{i}].inputs[{j}] type={io.get('type', '')!r} 的 value 和 anchor 都空 — "
+                        f"输入要么填字面量 value(@quote 拽原文), 要么用 anchor ← 上游编号 引数据流; 二者必有其一")
+            for j, io in enumerate(step.get('outputs') or []):
+                if not isinstance(io, dict) or io.get('inferred'):
+                    continue
+                v = io.get('value')
+                if v is None or (isinstance(v, str) and not v.strip()):
+                    issues.append(
+                        f"[{proc_label}] step[{i}].outputs[{j}] type={io.get('type', '')!r} 的 value 空 — "
+                        f"输出是这步的产物, 必须有值: 文本类填逐字内容、媒体类填 <描述>; "
+                        f"原文确无则用 <占位>(原文未提供) 或标 inferred:true")
+    return issues
+
+
+def check_dataflow_connected(case_data: dict) -> list[str]:
+    """多步工序却一个 anchor 都没有 = 2.0.2 连数据流整段没做。
+
+    弱模型常把内容当字面量塞进每个 IO、步骤间不连任何 ← / →; 渲染出来"来源/去处"全空,
+    去处也无从反推(反推需要输入 ← 作来源)。一个真·工序是一条数据流水线, ≥2 步必有跨步传递,
+    所以"≥2 步 & 0 anchor"是确定性的"流程没连"信号 (单步工序豁免; 任何非空 anchor 都算已连)。
+    """
+    issues: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        steps = [s for s in (proc.get('steps') or []) if isinstance(s, dict)]
+        if len(steps) < 2:
+            continue
+        n_anchor = sum(
+            1 for s in steps for k in ('inputs', 'outputs')
+            for io in (s.get(k) or [])
+            if isinstance(io, dict) and (io.get('anchor') or '').strip())
+        if n_anchor == 0:
+            issues.append(
+                f"[{proc_label}] {len(steps)} 个步骤却 0 个 anchor — 数据流(2.0.2 连来源/去处)整段没做: "
+                f"下游输入用 `← 上游输出编号`(如 ← s1o1)引数据、别把内容当字面量重抄; "
+                f"至少把工序内的传递链连起来, 否则 HTML 里来源/去处全空")
+    return issues
+
+
+# ===========================================================================
+# Check 3: value 占位 / directive 缺失 (提示用 quote-source 回填真内容)
+# ===========================================================================
+
+# 纯 <...> 占位 (value 该填真实内容, <...> 仅限无文字的图/视频)
+PLACEHOLDER_RE = re.compile(r'^\s*<[^>]*>\s*$')
+
+# 「原文确无该信息」逃生标记 → 占位/逐字检查放行 (等同 inferred)。常见措辞都要认:
+# 原文未提供 / 原文确无 / 原文中没有 / 原帖里无 …。render-case.py 的 _NOSRC_RE 与此保持一致。
+NOSRC_RE = re.compile(r'原[文帖].{0,2}(未提供|未给出|未写|没有|没写|确无|无)')
+
+# 模态分类关键词 (TEXT 优先于 MEDIA, 因 "配音文案" 这类既含媒体词又是文本)
+_TEXT_KW = ('提示词', '描述', '参数', '评', '大纲', '脚本', '文案', '歌词', '字幕',
+            '标题', '正文', '词', '知识', '工作流', '对标', '规格', '批处理', '模板', '版式',
+            '数据', '分析', '报告', '记录', '方案', '思路', '设定', '依据', '标准', '清单', '列表', '文本', '文字')
+_MEDIA_KW = ('图', '视频', '音频', '帧', '片段', '截图', '蒙版', '音效', '配音', 'BGM',
+             '数字人', '滤镜', '海报', '封面')
+
+
+def _type_modality(type_name: str, type_reg: dict) -> str:
+    """按类型名(case-specific 类型先经 type_registry.extends 解析到 stdlib 叶子)判模态.
+
+    返回 'media' (图/视频/音频 — 可 <描述>) / 'text' (提示词/数据/报告 — 必须真实文本) / 'unknown'.
+    media 用关键词可靠识别; 非 media 一律按"需真实文本"对待 (data/text 占多数, 宁严勿漏).
+    """
+    base, seen = type_name, set()
+    while base in (type_reg or {}) and base not in seen:
+        seen.add(base)
+        ent = type_reg[base]
+        ext = ent.get('extends') if isinstance(ent, dict) else None
+        if not ext:
+            break
+        base = ext
+    nm = base or type_name or ''
+    if any(k in nm for k in _TEXT_KW):
+        return 'text'
+    if any(k in nm for k in _MEDIA_KW):
+        return 'media'
+    return 'unknown'
+
+
+def check_placeholder_content(case_data: dict) -> list[str]:
+    """逐 IO 按模态审计 value + 工具步骤 directive → 提示用 quote-source 回填真内容.
+
+    规则 (README「第二阶段 · 2.0.1 填 value」): 文本类 IO(提示词/数据/报告)的 value 必须是从原文匹配到的真实内容,
+    不能写 <…> 占位; 原文确实没有 → 标 inferred:true + inferred_reason 显式说明 (本检查放行).
+    媒体类 IO(图/视频/音频)允许 <具体描述>. 工具步骤(via 是具体工具)必须带原文那段 prompt 当 directive.
+    弱模型常把所有 value 写成 <…> 占位、整个漏 directive (实测 test-7 全踩), 这条逐 IO 抓, 只 hint.
+    """
+    hints: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        type_reg = proc.get('type_registry') or {}
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, item in enumerate(step.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    if item.get('inferred'):       # 已显式标 inferred 说明 → 放行
+                        continue
+                    v = item.get('value')
+                    if not isinstance(v, str):
+                        continue
+                    if NOSRC_RE.search(v):
+                        continue                   # 显式标「原文未提供/确无」→ 放行 (LLM 确认原文确无)
+                    if not PLACEHOLDER_RE.match(v):
+                        continue                   # value 不是 <…> 占位 (已填真内容)
+                    t = item.get('type', '') or ''
+                    mod = _type_modality(t, type_reg)
+                    if mod == 'media':
+                        continue                   # 图/视频/音频 用 <描述> 合理
+                    label = '文本类' if mod == 'text' else '非媒体(疑似数据/文本)'
+                    # 输出占位 = 步骤产出物没回填; 原文/OCR 里通常紧跟在 prompt 后展示了它
+                    extra = (';这是步骤**产出物**, 原文/配图 OCR 里常紧跟 prompt 展示了它, '
+                             '用 quote-source --from/--to 把那段产出也捞进 value') if kind == 'outputs' else ''
+                    hints.append(
+                        f"[{proc_label}] step[{i}].{kind}[{j}] type={t!r}({label}) value={v.strip()!r} 仍是占位 "
+                        f"—— 你即便已 quote 到原文也**必须把真实内容替换进 value**(别只填 directive){extra}; "
+                        f"原文确无则标 inferred:true + inferred_reason; 若其实是无文字图/视频, 让类型/描述体现"
+                    )
+            via = (step.get('via') or '').strip()
+            directive = (step.get('directive') or '').strip()
+            if step.get('kind', 'step') == 'step' and via and via not in ('human', '-') and not directive:
+                hints.append(
+                    f"[{proc_label}] step[{i}](via={via!r}) directive 空 — 若原文有给工具的提示词/指令, "
+                    f"用 quote-source 捞原文那段填进 directive"
+                )
+            # substance/form 缺失 (Phase 2 该提炼实质/形式; 纯技术步可显式设 null, 但别整个漏掉 key)
+            if step.get('kind', 'step') in ('step', 'nested'):
+                miss = [f for f in ('substance', 'form') if f not in step]
+                if miss:
+                    hints.append(
+                        f"[{proc_label}] step[{i}] 缺 {'/'.join(miss)} — Phase 2 漏做了实质/形式提炼; "
+                        f"读懂这步内容提炼元素点填上(纯技术步可显式设 null, 但别漏掉字段)"
+                    )
+            # intent 缺失 (Phase 2 每步都要填目的列, 一句话概括)
+            if step.get('kind', 'step') in ('step', 'block', 'nested') and not (step.get('intent') or '').strip():
+                hints.append(
+                    f"[{proc_label}] step[{i}] 缺 intent — Phase 2 每步都要填目的列(一句话概括这步在做什么, ≤25 字)"
+                )
+    return hints
+
+
+# ===========================================================================
+# Check 3a: 未解析的 @quote 标记残留
+# ===========================================================================
+
+def check_unresolved_quotes(case_data: dict) -> list[str]:
+    """value/directive 里残留的 `@quote|起锚|止锚` 标记 → 报出 (确定性, render 前必须清零).
+
+    @quote 是喂给 wf-patch --resolve-quotes 的**中间态**: 锚点没匹配上时 wf-patch 只 ⚠ 警告、
+    标记原样留下。它不是 <占位>(占位门禁不认)、逐字检查又显式跳过它(resolve 后才比) ——
+    之前没有任何检查管它, 会一路漏进 HTML 当正文显示。修法: 改锚点(两段独特短串, 来自原文/OCR
+    逐字)重跑 --resolve-quotes, 或放弃标记直接填真实内容。
+    """
+    issues: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, io in enumerate(step.get(kind) or []):
+                    if not isinstance(io, dict):
+                        continue
+                    v = io.get('value')
+                    if isinstance(v, str) and v.lstrip().startswith('@quote'):
+                        issues.append(
+                            f"[{proc_label}] step[{i}].{kind}[{j}] value 是未解析的 @quote 标记 "
+                            f"({v.strip()[:48]!r}…) — 锚点没匹配上原文/OCR; 改锚点重跑 "
+                            f"`wf-patch --resolve-quotes --source <原文> [--ocr <ocr.txt>]`, 或直接填真实内容")
+            d = step.get('directive')
+            if isinstance(d, str) and d.lstrip().startswith('@quote'):
+                issues.append(
+                    f"[{proc_label}] step[{i}].directive 是未解析的 @quote 标记 ({d.strip()[:48]!r}…) — "
+                    f"改锚点重跑 --resolve-quotes, 或直接填真实内容")
+    return issues
+
+
+# ===========================================================================
+# Check 3b: 归类完成度 (Phase 2.1 做完没 — effect/action 填了、intent 是标记格式)
+# ===========================================================================
+
+# intent 标记格式 (README「目的列」): 合法标记类别 effect/via/act/in-type/out-type
+_INTENT_MARKERS = ('in-type:', 'out-type:', 'act:', 'via:', 'effect:')
+
+
+def check_classification_done(case_data: dict) -> list[str]:
+    """Phase 2.1 归类是否做完: 每个非控制块步骤要有 effect+action; 有 IO 的步骤 intent 要用标记格式.
+
+    runner 的自动续跑兜底用这条判「还差什么」(via --json), 规则只活在这里, 别在 runner 里复刻.
+    """
+    missing: list[str] = []
+    intent_bad: list[str] = []
+    for proc_label, proc in _iter_procedures(case_data):
+        for s in proc.get('steps') or []:
+            if not isinstance(s, dict) or s.get('kind') == 'block':
+                continue   # 控制块不要求 effect/action
+            sid = f"{proc_label}.{s.get('id')}"
+            if not (s.get('effect') or '').strip() or not (s.get('action') or '').strip():
+                missing.append(sid)
+            has_io = bool(s.get('inputs') or s.get('outputs'))
+            intent = (s.get('intent') or '').strip()
+            if has_io and (not intent or '{' not in intent
+                           or not any(m in intent for m in _INTENT_MARKERS)):
+                intent_bad.append(sid)
+    hints: list[str] = []
+    if missing:
+        hints.append(f"{len(missing)} 个步骤缺 effect/action (Phase 2.1 没做完): "
+                     f"{', '.join(missing[:8])}{' …' if len(missing) > 8 else ''}")
+    if intent_bad:
+        hints.append(f"{len(intent_bad)} 个步骤的 intent 没用标记格式 (README「目的列」: 写成带 "
+                     f"{{in-type:X}}/{{out-type:Y}}/{{act:Z}} 的句子): "
+                     f"{', '.join(intent_bad[:8])}{' …' if len(intent_bad) > 8 else ''}")
+    return hints
+
+
+# ===========================================================================
+# Check 4: 章节覆盖 (结构强制 — 需 --source) + value 逐字 (值强制 — 需 --source)
+# ===========================================================================
+#
+# 弱模型在 Phase 1 骨架阶段走两条最省力的路, 都靠"看原文"才抓得到:
+#   (结构) 只挑两个最显眼的工序就收工, 整段章节(框架/附加案例/总结)漏抽
+#   (值)   挑中的 value 也打字缩写成标题纲要, 不是逐字原文 (能过 render 门禁因为不是 <占位>)
+# 这两条 check 都需要原文 (--source input/case-N.json [--ocr ocr.txt]) 才能比对.
+
+# 比对噪声: 空白 + 各式引号 (原文 “”、骨架常写成 「」/"",内容一致只是引号风格不同, 不该算缩写)
+_QUOTE_NOISE = dict.fromkeys(map(ord, '「」『』“”‘’"\'"''), None)
+
+
+def _norm(s: str) -> str:
+    """归一化用于子串比对: 去所有空白 (原文常把一个词拆到两行) + 抹掉引号风格差异."""
+    return re.sub(r'\s+', '', s or '').translate(_QUOTE_NOISE)
+
+
+def _load_source_corpus(source_path: Path | None, ocr_path: Path | None) -> tuple[str, str]:
+    """读原文语料: 返回 (raw_text, normed). raw 用来切章节, normed 用来子串比对.
+
+    source = input/case-N.json 的 title + body_text; ocr = 配图 OCR 文本 (可选).
+    """
+    parts: list[str] = []
+    if source_path and source_path.exists():
+        try:
+            sd = json.loads(source_path.read_text(encoding='utf-8'))
+            parts.append(sd.get('title', '') or '')
+            parts.append(sd.get('body_text', '') or sd.get('content', '') or '')
+        except Exception:
+            parts.append(source_path.read_text(encoding='utf-8'))
+    if ocr_path and ocr_path.exists():
+        parts.append(ocr_path.read_text(encoding='utf-8'))
+    raw = '\n'.join(parts)
+    return raw, _norm(raw)
+
+
+def _sections(body: str) -> list[tuple[str, str, str]]:
+    """切原文章节: 按行首 `NN |` 两位标号 (01..99; 行首要求天然排除 `图 0N |` 配图说明). 返回 [(号, 标题, 正文段)]."""
+    marks = [(m.start(), m.group(1)) for m in re.finditer(r'(?m)^\s*(\d{2})\s*[||]', body)]
+    out: list[tuple[str, str, str]] = []
+    for idx, (pos, num) in enumerate(marks):
+        end = marks[idx + 1][0] if idx + 1 < len(marks) else len(body)
+        seg = body[pos:end]
+        after = re.split(r'[||]', seg, 1)
+        tail = after[-1] if len(after) > 1 else seg
+        title = ''
+        for line in tail.splitlines():
+            line = line.strip()
+            if line:
+                title = line[:24]
+                break
+        out.append((num, title, seg))
+    return out
+
+
+# 章节正文里的"要点标记": 思路X / 第X层 / 第X步 / 案例X / 冒号短标签 (人物特征:…)
+_POINT_MARKER = re.compile(
+    r'(?m)^\s*(思路[一二三四五]|第[一二三四五六七八九十]+[层步]|案例[一二三四五六七八九十]+)')
+_POINT_COLON = re.compile(r'(?m)^\s*([^\n::((]{2,12})\s*[::]')
+
+
+def _section_points(seg: str) -> list[str]:
+    """抽一节正文的要点短语 (用来量化它被骨架覆盖了多少)."""
+    pts: list[str] = []
+    for m in _POINT_MARKER.finditer(seg):
+        line = seg[m.start():].splitlines()[0].strip()
+        pts.append(line[:16])
+    for m in _POINT_COLON.finditer(seg):
+        lab = m.group(1).strip()
+        # 纯序号标记 (第X步/第X层/思路X/案例X) 是结构序号不是内容要点, 骨架改写成动作后必然对不上 → 跳过
+        if re.fullmatch(r'(思路[一二三四五]|第[一二三四五六七八九十]+[层步]|案例[一二三四五六七八九十]+)', lab):
+            continue
+        if re.search(r'[一-龥]', lab):
+            pts.append(lab)
+    seen: set[str] = set()
+    out: list[str] = []
+    for p in pts:
+        if p and p not in seen:
+            seen.add(p)
+            out.append(p)
+    return out
+
+
+def _point_covered(point: str, wf_norm: str) -> bool:
+    """要点是否被骨架覆盖: 去掉结构前缀后, 任一 4-gram 命中 workflow 文本即算覆盖 (从宽)."""
+    core = re.sub(r'^(思路[一二三四五]|第[一二三四五六七八九十]+[层步]|案例[一二三四五六七八九十]+)', '', point)
+    core = _norm(core) or _norm(point)
+    if len(core) < 4:
+        return core in wf_norm
+    return any(core[k:k + 4] in wf_norm for k in range(len(core) - 3))
+
+
+def check_section_coverage(case_data: dict, source_raw: str, wf_norm: str) -> list[str]:
+    """结构强制: 逐章节算骨架覆盖率, 整段漏抽的章节 (<40%) 报出来 + 给缺失要点样例."""
+    hints: list[str] = []
+    secs = _sections(source_raw)
+    if not secs:
+        return hints
+    for num, title, seg in secs:
+        pts = _section_points(seg)
+        if len(pts) < 2:
+            continue   # 没足够要点 (纯过渡/口号段), 不评判
+        missed = [p for p in pts if not _point_covered(p, wf_norm)]
+        ratio = 1 - len(missed) / len(pts)
+        if ratio < 0.40:
+            sample = '、'.join(missed[:5])
+            hints.append(
+                f"章节『{num} {title}』覆盖率 {ratio:.0%} ({len(pts) - len(missed)}/{len(pts)} 要点) "
+                f"—— 疑似整段漏抽; 缺: {sample}{' …' if len(missed) > 5 else ''}; "
+                f"回去为它补 procedure/step (每个 0N 章节至少对应一个工序或子步骤)"
+            )
+    return hints
+
+
+def _longest_run(v_norm: str, source_norm: str) -> int:
+    """value 在原文里能连续命中的最长子串长度. 逐字原文应是原文一整段连续文本;
+    拼接/缩写出来的(把分散的小标题用、串起来)最长连续命中会很短."""
+    n = len(v_norm)
+    best = 0
+    for i in range(n):
+        if n - i <= best:
+            break                       # 剩余长度已不可能超过 best
+        lo, hi = 0, n - i
+        while lo < hi:                  # 二分该起点能命中的最长长度
+            mid = (lo + hi + 1) // 2
+            if v_norm[i:i + mid] in source_norm:
+                lo = mid
+            else:
+                hi = mid - 1
+        if lo > best:
+            best = lo
+    return best
+
+
+def check_value_verbatim(case_data: dict, source_norm: str) -> list[str]:
+    """值强制: 文本类 value 必须是原文里的「一整段连续文本」. 最长连续命中 <80% 判缩写/改写/截断.
+
+    跳过: 占位<…>(归 check3)、inferred、原文未提供、未 resolve 的 @quote、媒体类、短值(<12字).
+    用最长连续命中而非逐子句覆盖: 后者会被「人物、产品、环境」这种"原文小标题拼盘"骗过
+    (每个词单独在原文里, 但整体不是任何一段原文 — 真正的逐字细节全被丢了).
+    """
+    hints: list[str] = []
+    if not source_norm:
+        return hints
+    for proc_label, proc in _iter_procedures(case_data):
+        type_reg = proc.get('type_registry') or {}
+        for i, step in enumerate(proc.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, item in enumerate(step.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    if item.get('inferred'):
+                        continue
+                    v = item.get('value')
+                    if not isinstance(v, str) or not v.strip():
+                        continue
+                    if PLACEHOLDER_RE.match(v):
+                        continue                          # 占位 → check3 管
+                    if v.startswith('@quote'):
+                        continue                          # 未回填的 quote, resolve 后才比
+                    if NOSRC_RE.search(v):
+                        continue
+                    if _type_modality(item.get('type', '') or '', type_reg) == 'media':
+                        continue                          # 媒体描述不要求逐字
+                    vn = _norm(v)
+                    if len(vn) < 12:
+                        continue                          # 短标签不查 (无所谓缩写)
+                    run = _longest_run(vn, source_norm)
+                    ratio = run / len(vn)
+                    # 绝对护栏: 连续命中 ≥80 字 = 铁证级真引用 (没人会"凑巧"逐字打 80 字),
+                    # 哪怕整体比例因中途一处微小偏差掉到 80% 也放行, 只抓"短值缩写"。
+                    if run >= 80:
+                        continue
+                    if ratio < 0.80:
+                        hints.append(
+                            f"[{proc_label}] step[{i}].{kind}[{j}] value 最长连续命中原文仅 {run}/{len(vn)} 字"
+                            f"({ratio:.0%}) —— 整体不是一整段原文(疑似开头逐字后就缩写/改写); value={v[:40]!r}…; "
+                            f"用 @quote|起锚|止锚 + wf-patch --resolve-quotes 把整段原文逐字拽进来(原文那段提示词约 350 字)"
+                        )
+    return hints
+
+
+# ===========================================================================
+# Side effect: record 新 type 到 type_suggestions.md
+# ===========================================================================
+
+def record_new_types(case_data: dict, suggestions_path: Path = SUGGESTIONS) -> list[str]:
+    """把 case_data.type_registry 里的 case-specific type append 到 suggestions.
+
+    幂等: 同一 (type_name, case_id) 二元组只 append 一次. Dedup 靠 grep 现有文件,
+    抽 `(来自 case-{N})` + 类型名 二元组.
+
+    Returns:
+        本次新写入的条目 list (空 list = 没新东西要 record).
+    """
+    # 合并所有 procedures.type_registry
+    type_reg: dict = {}
+    for p in case_data.get('procedures', []):
+        type_reg.update(p.get('type_registry') or {})
+    if not type_reg:
+        return []
+
+    leaves = load_type_leaves()
+    case_id = case_data.get('case_id') or '?'
+    text = suggestions_path.read_text(encoding='utf-8') if suggestions_path.exists() else ''
+
+    # 已 record 过的 (type_name, case_id) — 用 regex 抓 markdown list entry
+    existing = set(re.findall(
+        r'^- `([^`]+)`:.*?\(来自 case-([^,)\s]+)', text, re.M
+    ))
+
+    new_lines: list[str] = []
+    for tname, entry in type_reg.items():
+        if not isinstance(entry, dict):
+            continue
+        if tname in leaves:
+            continue   # 已是字典叶子, 不是新 type (Agent 误把 stdlib type 加进 case_data.type_registry)
+        if (tname, str(case_id)) in existing:
+            continue
+        ext = entry.get('extends', '?')
+        desc = entry.get('desc') or '(无 desc)'
+        new_lines.append(f'- `{tname}`: {desc}  (来自 case-{case_id}, extends `{ext}`)')
+
+    if new_lines:
+        # 确保 suggestions 文件存在 (没有就建个空骨架)
+        if not suggestions_path.exists():
+            suggestions_path.write_text(
+                '# Type 字典扩展建议\n\n## 累积条目\n\n', encoding='utf-8'
+            )
+        # append 末尾
+        with suggestions_path.open('a', encoding='utf-8') as f:
+            f.write('\n' + '\n'.join(new_lines) + '\n')
+
+    return new_lines
+
+
+# ===========================================================================
+# main
+# ===========================================================================
+
+def main() -> None:
+    ap = argparse.ArgumentParser(
+        prog='lint-case.py',
+        description='workflow 轻量 lint + 自动 record 新 type 到 type_suggestions.md',
+    )
+    ap.add_argument('--workflow', type=Path, required=True,
+                    help='workflow.json (含 procedures 数组). lint 内部读 procedures + type_registry')
+    ap.add_argument('--case-id', type=str, default=None,
+                    help='record suggestions 用的 case_id. 不传就 fallback workflow.case_id 或 ?')
+    ap.add_argument('--source', type=Path, default=None,
+                    help='原文 input/case-N.json. 传了才启用「章节覆盖」+「value 逐字」两条结构/值强制校验')
+    ap.add_argument('--ocr', type=Path, default=None,
+                    help='配图 OCR 文本 (可选). 并入原文语料, 让逐字校验也认配图里的文字')
+    ap.add_argument('--no-record', action='store_true',
+                    help='只校验, 不写 suggestions')
+    ap.add_argument('--json', action='store_true',
+                    help='输出机器可读 JSON ({"checks": {名: [提示...]}}); runner 的完成度判据消费它')
+    args = ap.parse_args()
+
+    target_path = args.workflow
+    if not target_path.exists():
+        print(f'lint-case: 文件不存在 {target_path}', file=sys.stderr)
+        sys.exit(2)
+
+    try:
+        case_data = json.loads(target_path.read_text(encoding='utf-8'))
+    except json.JSONDecodeError as e:
+        print(f'lint-case: {target_path} 不是合法 JSON: {e}', file=sys.stderr)
+        sys.exit(2)
+
+    # workflow 模式: 注入 case_id (suggestions record 需要)
+    if args.case_id is not None and 'case_id' not in case_data:
+        try:
+            case_data['case_id'] = int(args.case_id)
+        except ValueError:
+            case_data['case_id'] = args.case_id
+
+    case_id = case_data.get('case_id', '?')
+
+    # 全部检查跑进 results (检查名 → 提示列表); --json 和人读输出共用这一份
+    results: dict[str, list[str]] = {
+        'type_completeness': check_type_completeness(case_data),
+        'value_selfcontained': check_value_selfcontained(case_data),
+        'placeholder_content': check_placeholder_content(case_data),
+        'unresolved_quotes': check_unresolved_quotes(case_data),
+        'classification_done': check_classification_done(case_data),
+    }
+    source_checked = args.source is not None
+    if source_checked:
+        source_raw, source_norm = _load_source_corpus(args.source, args.ocr)
+        wf_norm = _norm(json.dumps(case_data, ensure_ascii=False))
+        results['section_coverage'] = check_section_coverage(case_data, source_raw, wf_norm)
+        results['value_verbatim'] = check_value_verbatim(case_data, source_norm)
+
+    # side effect: record 新 type
+    recorded: list[str] = []
+    if not args.no_record:
+        recorded = record_new_types(case_data)
+
+    if args.json:
+        print(json.dumps({'case_id': case_id, 'checks': results,
+                          'source_checked': source_checked,
+                          'recorded': len(recorded)}, ensure_ascii=False, indent=1))
+        sys.exit(0)
+
+    print(f'[lint] case-{case_id} ({target_path.name})')
+    _HEADERS = {
+        'type_completeness': ('type 完整性', '个提示'),
+        'value_selfcontained': ('value 自包含', '个引用占位 (跑 wf-patch.py --resolve-passthrough 自动回填)'),
+        'placeholder_content': ('value/directive 真实性', '处占位/缺失 (用 quote-source.py 从原文/配图 OCR 捞真内容回填)'),
+        'unresolved_quotes': ('@quote 残留', '处未解析标记 (改锚点重跑 --resolve-quotes 或直接填真实内容)'),
+        'classification_done': ('归类完成度', '项未完成 (Phase 2.1: effect/action 对词表填, intent 用标记格式)'),
+        'section_coverage': ('章节覆盖(结构强制)', '个章节疑似漏抽 —— 骨架要覆盖原文每个章节'),
+        'value_verbatim': ('value 逐字(值强制)', '处疑似缩写/改写 —— 文本类 value 要逐字搬原文(用 @quote)'),
+    }
+    for name, hints in results.items():
+        title, suffix = _HEADERS[name]
+        if hints:
+            print(f'  · {title}: {len(hints)} {suffix}')
+            for h in hints:
+                print(f'      - {h}')
+        else:
+            print(f'  · {title}: OK')
+    if not source_checked:
+        print('  · 章节覆盖 + value 逐字: skipped (传 --source input/case-N.json [--ocr ocr.txt] 启用结构/值强制)')
+
+    if not args.no_record:
+        if recorded:
+            print(f'  · 已 record {len(recorded)} 条新 type 到 {SUGGESTIONS.name}:')
+            for ln in recorded:
+                print(f'      {ln}')
+        else:
+            merged_reg: dict = {}
+            for p in case_data.get('procedures', []):
+                merged_reg.update(p.get('type_registry') or {})
+            if not merged_reg:
+                print('  · 无新 type 可 record (type_registry 为空 — 全部 type 命中字典叶子)')
+            else:
+                print('  · 无新 type 可 record (type_registry 里的项已全部 record 过)')
+
+    # 不卡 exit code
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+    main()

+ 239 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/quote-source.py

@@ -0,0 +1,239 @@
+#!/usr/bin/env python3
+"""quote-source.py — 从原文 case json 按字符匹配查找并**原样返回**片段, 供填 value / directive。
+
+为什么需要: value / directive 要填原文里的真实内容(那段 JSON 风格分析、那句完整提示词),
+不能写 "<JSON 风格分析数据>" 这种空壳, 也不能凭记忆缩写。用本工具把原文那段逐字捞出来,
+再粘进 workflow.json 的 value / directive。
+
+匹配是**空白无关**的: 原文 body_text 常有乱换行 / 前导空格("交给\\n AI"), 直接子串匹配
+多词查询会落空。本工具匹配时忽略所有空白, 但返回的是**原文逐字片段**(连原排版一起)。
+
+用法 (Agent 走 bash_command 调):
+    # 按几个关键词捞出周边片段 (默认前后各 300 字)
+    python spec/tools/quote-source.py --source input/case-N.json --query "视觉风格分析"
+    # 捞大块时放宽窗口
+    python spec/tools/quote-source.py --source input/case-N.json --query "主色调" --window 800
+    # 命中点落在 {...} 里时, 返回整个 JSON 块 (适合捞那段结构化分析)
+    python spec/tools/quote-source.py --source input/case-N.json --query "视觉风格分析" --json-block
+    # 捞一句完整提示词当 directive
+    python spec/tools/quote-source.py --source input/case-N.json --query "请以 JSON 结构化"
+    # 范围引用: 用首尾两个短锚点引出之间的整段长原文 (比 --window 猜长度精确)
+    python spec/tools/quote-source.py --source input/case-N.json --from "请以 JSON" --to "500 字以内"
+    python spec/tools/quote-source.py --source input/case-N.json --from "视觉风格分析" --to "电影感人像"
+
+输出: 命中的原文逐字片段 (多处命中各自分隔)。无精确命中时给出最接近的一段 (标 ~approx)。
+退出码: 0 有命中(含 approx) / 1 完全找不到 / 2 CLI/IO 错。
+"""
+import argparse
+import json
+import sys
+from pathlib import Path
+
+for _s in (sys.stdout, sys.stderr):
+    if hasattr(_s, "reconfigure"):
+        try:
+            _s.reconfigure(encoding="utf-8", errors="replace")
+        except Exception:
+            pass
+
+
+def _source_text(path: Path) -> str:
+    """从 case json 抽可搜索文本: title + body_text (两套 schema 都有 body_text)。"""
+    data = json.loads(path.read_text(encoding="utf-8"))
+    if not isinstance(data, dict):
+        return str(data)
+    parts = []
+    for k in ("title", "body_text"):
+        v = data.get(k)
+        if isinstance(v, str) and v:
+            parts.append(v)
+    return "\n".join(parts)
+
+
+def _build_norm(text: str):
+    """去掉所有空白, 返回 (norm_str, idxmap)。idxmap[i] = norm 第 i 个字符在原文里的下标。"""
+    chars, idxmap = [], []
+    for i, ch in enumerate(text):
+        if ch.isspace():
+            continue
+        chars.append(ch)
+        idxmap.append(i)
+    return "".join(chars), idxmap
+
+
+def _find_all(ns: str, nq: str, max_hits: int):
+    hits, start = [], 0
+    while len(hits) < max_hits:
+        p = ns.find(nq, start)
+        if p < 0:
+            break
+        hits.append(p)
+        start = p + max(1, len(nq))
+    return hits
+
+
+def _enclosing_braces(text: str, lo: int, hi: int):
+    """找包住 [lo,hi] 的最小 {...} (按花括号配平)。找不到返回 None。"""
+    # 向左找候选 '{'
+    depth = 0
+    open_pos = None
+    i = lo
+    while i >= 0:
+        if text[i] == "}":
+            depth += 1
+        elif text[i] == "{":
+            if depth == 0:
+                open_pos = i
+                break
+            depth -= 1
+        i -= 1
+    if open_pos is None:
+        return None
+    # 从 open_pos 向右配平
+    depth = 0
+    j = open_pos
+    while j < len(text):
+        if text[j] == "{":
+            depth += 1
+        elif text[j] == "}":
+            depth -= 1
+            if depth == 0:
+                if j >= hi:
+                    return (open_pos, j)
+                return None
+        j += 1
+    return None
+
+
+def _approx(ns: str, nq: str, idxmap, text: str, window: int):
+    """无精确命中时, 用最长公共子串给最接近的一段 (标 approx)。"""
+    from difflib import SequenceMatcher
+    if not nq:
+        return None
+    m = SequenceMatcher(None, ns, nq, autojunk=False).find_longest_match(0, len(ns), 0, len(nq))
+    if m.size == 0:
+        return None
+    lo_n, hi_n = m.a, m.a + m.size - 1
+    return _slice(idxmap, text, lo_n, hi_n, window, False)
+
+
+def _slice(idxmap, text: str, lo_n: int, hi_n: int, window: int, json_block: bool):
+    o_lo = idxmap[lo_n]
+    o_hi = idxmap[hi_n]
+    if json_block:
+        br = _enclosing_braces(text, o_lo, o_hi)
+        if br:
+            return text[br[0]: br[1] + 1], br[0], br[1]
+    lo = max(0, o_lo - window)
+    hi = min(len(text), o_hi + 1 + window)
+    return text[lo:hi], lo, hi
+
+
+def _range_between(text: str, frm: str, to: str):
+    """范围引用: 返回 frm 首次出现 → 其后首次 to 结束 之间(含两端)的原文逐字片段。
+
+    匹配空白无关; to 必须落在 frm 之后(取最近的一个), 给出最小包裹区间。找不到返回 None。
+    """
+    ns, idxmap = _build_norm(text)
+    nf, _ = _build_norm(frm)
+    nt, _ = _build_norm(to)
+    if not nf or not nt:
+        return None
+    p = ns.find(nf)
+    if p < 0:
+        return None
+    q = ns.find(nt, p + len(nf))      # to 必须在 from 之后
+    if q < 0:
+        return None
+    o_lo = idxmap[p]
+    o_hi = idxmap[q + len(nt) - 1]
+    return text[o_lo:o_hi + 1], o_lo, o_hi
+
+
+def main() -> int:
+    ap = argparse.ArgumentParser(description="从原文 case json 按字符匹配原样捞片段 (供填 value/directive)")
+    ap.add_argument("--source", required=True, help="原文 case json 路径")
+    ap.add_argument("--query", default=None, help="关键词模式: 要查找的文字 (空白无关匹配; 配 --window / --json-block)")
+    ap.add_argument("--from", dest="frm", default=None, help="范围模式: 起始锚点 (短串)")
+    ap.add_argument("--to", dest="to", default=None, help="范围模式: 结束锚点 (短串); 与 --from 同用, 用两个短参数引出之间(含)的整段长原文")
+    ap.add_argument("--ocr", default=None, help="配图 OCR 文本文件 (如 <case_dir>/_scratch/ocr.txt); 一并搜图片里的文字")
+    ap.add_argument("--window", type=int, default=300, help="命中点前后各保留多少字 (default 300)")
+    ap.add_argument("--max", type=int, default=3, help="每个语料最多返回几处命中 (default 3)")
+    ap.add_argument("--json-block", action="store_true", help="命中落在 {...} 内时返回整个 JSON 块")
+    args = ap.parse_args()
+
+    src = Path(args.source)
+    if not src.exists():
+        print(f"source not found: {src}", file=sys.stderr)
+        return 2
+    try:
+        corpora = [("原文", _source_text(src))]
+    except (json.JSONDecodeError, OSError) as e:
+        print(f"read source failed: {e}", file=sys.stderr)
+        return 2
+    # 第二语料: 配图 OCR 文本
+    if args.ocr:
+        ocr_p = Path(args.ocr)
+        if ocr_p.exists():
+            corpora.append(("配图OCR", ocr_p.read_text(encoding="utf-8")))
+        else:
+            print(f"# (--ocr {ocr_p} 不存在, 仅搜原文)", file=sys.stderr)
+
+    # ── 范围模式: --from / --to 两个短锚点 → 返回之间(含)的整段原文 ──
+    if args.frm is not None or args.to is not None:
+        if not (args.frm and args.to):
+            print("范围模式需同时给 --from 和 --to", file=sys.stderr)
+            return 2
+        out = []
+        for label, text in corpora:
+            rng = _range_between(text, args.frm, args.to)
+            if rng:
+                frag, lo, hi = rng
+                warn = "  ⚠ 跨度很大, 确认锚点是否选窄了" if (hi - lo) > 4000 else ""
+                out.append(f"# [{label}] 范围命中 (第 {lo}–{hi} 字, 共 {hi - lo + 1} 字{warn}; 下为两锚点间逐字原文)\n{frag}")
+        if out:
+            print("\n\n".join(out))
+            return 0
+        print(f"# 找不到从 {args.frm!r} 到 {args.to!r} 的范围 (检查: 两锚点是否各自存在、to 是否在 from 之后)", file=sys.stderr)
+        return 1
+
+    # ── 关键词模式: --query ──
+    if not args.query:
+        print("需要 --query, 或 (--from + --to) 范围模式", file=sys.stderr)
+        return 2
+    nq, _ = _build_norm(args.query)
+    if not nq:
+        print("query 去空白后为空", file=sys.stderr)
+        return 2
+
+    out, found = [], False
+    for label, text in corpora:
+        ns, idxmap = _build_norm(text)
+        hits = _find_all(ns, nq, args.max)
+        if hits:
+            found = True
+            out.append(f"# [{label}] {len(hits)} 处命中 (query={args.query!r}, 空白无关匹配; 下为逐字片段)")
+            for k, p in enumerate(hits, 1):
+                frag, lo, hi = _slice(idxmap, text, p, p + len(nq) - 1, args.window, args.json_block)
+                out.append(f"\n--- [{label}] 命中 {k} (第 {lo}–{hi} 字) ---\n{frag}")
+    if found:
+        print("\n".join(out))
+        return 0
+
+    # 无精确命中 → 各语料给最接近的一段
+    for label, text in corpora:
+        ns, idxmap = _build_norm(text)
+        ap_res = _approx(ns, nq, idxmap, text, args.window)
+        if ap_res:
+            frag, lo, hi = ap_res
+            out.append(f"# [{label}] 无精确命中, 最接近的一段 (~approx, 第 {lo}–{hi} 字; 请核对):\n\n{frag}")
+    if out:
+        print("\n".join(out))
+        return 0
+
+    print(f"# 原文/OCR 里都找不到与 {args.query!r} 相关的内容", file=sys.stderr)
+    return 1
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 373 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/render-case.py

@@ -0,0 +1,373 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+render-case.py — Procedure DSL · 阶段三 3.3 落盘&渲染脚本.
+
+把 case_data (符合 spec/format/case-data.schema.json) 通过 spec/tools/renderer.build_html
+渲染成单文件 HTML.
+
+用法:
+
+  渲染:
+       render-case.py --workflow outputs/case-N/workflow.json \
+                      --source-input input/case-N-raw.json \
+                      --page-title "Case N · 主题" --case-id N \
+                      --out outputs/case-N/case-N-<slug>.html
+
+  只校验, 不渲染:
+       render-case.py --workflow outputs/case-N/workflow.json --source-input input/case-N-raw.json --validate
+
+退出码:
+  0  成功 (渲染或校验通过)
+  1  IO / schema / 渲染异常
+  2  CLI 参数错误
+
+依赖:
+  必需: spec/tools/renderer.py (跟本脚本同目录, 自动加入 sys.path)
+  可选: jsonschema (装了就用 Draft 2020-12 校验; 没装则只做最小结构检查)
+"""
+from __future__ import annotations
+
+import argparse
+import importlib.util
+import json
+import re
+import sys
+from pathlib import Path
+
+# Windows cp1252 console 不能直接打中文/勾选号; 把 stdout/stderr 强转 UTF-8.
+for _stream in (sys.stdout, sys.stderr):
+    if hasattr(_stream, 'reconfigure'):
+        try:
+            _stream.reconfigure(encoding='utf-8', errors='replace')
+        except Exception:
+            pass
+
+# DSL_ROOT = procedure-dsl/  (本脚本位于 procedure-dsl/spec/tools/)
+DSL_ROOT = Path(__file__).resolve().parent.parent.parent
+SCHEMA_PATH = DSL_ROOT / 'spec' / 'format' / 'case-data.schema.json'
+# renderer.py 跟本脚本同目录 (spec/tools/), 直接用 parent 最 robust.
+TEMPLATE_DIR = Path(__file__).resolve().parent
+
+
+def _import_build_html():
+    """延迟 import build_html, 把 examples/_build 接到 sys.path. 失败时给出明确错误."""
+    sys.path.insert(0, str(TEMPLATE_DIR))
+    try:
+        from renderer import build_html  # type: ignore
+    except ImportError as e:
+        die(f'无法导入 renderer.build_html (期望路径: {TEMPLATE_DIR}/renderer.py): {e}')
+    return build_html
+
+
+def _load_lint():
+    """载入 lint-case.py (文件名带连字符, 按路径载) 复用其结构性 check, 保持单一真源."""
+    p = Path(__file__).resolve().parent / 'lint-case.py'
+    spec = importlib.util.spec_from_file_location('_lint_case_mod', p)
+    mod = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(mod)
+    return mod
+
+
+def die(msg: str, code: int = 1):
+    print(f'render-case: {msg}', file=sys.stderr)
+    sys.exit(code)
+
+
+def load_json(path: Path) -> dict:
+    if not path.exists():
+        die(f'文件不存在: {path}')
+    try:
+        return json.loads(path.read_text(encoding='utf-8'))
+    except json.JSONDecodeError as e:
+        die(f'{path} 不是合法 JSON: {e}')
+
+
+def die_short(msg: str):
+    die(msg)
+
+
+def merge_raw_source(case_data: dict, raw_path: Path) -> None:
+    """从 input/case-{N}-raw.json 抽 body_text + 封面 + 图集兜底, in-place 填到 case_data.source.
+
+    设计: raw 是事实源 (原帖正文 / 封面 / 标题 / URL), case_data.source.body_text 和 cover_image
+    被 raw 覆盖. 其他字段 (excerpt / author / date / platform) **保留 case_data 原值** ——
+    那些是 Agent 推断/总结的友好版本, 不应被 raw 覆盖.
+
+    图集兜底逻辑: 微信公众号正文里有 `[image:URL]` inline markup → renderer 自动渲染就好.
+    小红书等"短文 + 独立图集" 平台 body_text 不含 inline markup → 把 image_url_list 里
+    既没 inline 也不是封面的图, 以 `[image: URL]` 形式 append 到 body_text 末尾 (附 "附图" 分隔符).
+    这样 renderer.render_source_body 一视同仁地把它们也渲染成 <img>, 不重复封面.
+    """
+    import re
+
+    raw = load_json(raw_path)
+    src = case_data.setdefault('source', {})
+
+    body = raw.get('body_text', '') or ''
+
+    # cover_image: image_url_list 里 image_type=2 (封面) 的第一张; 没有就 fallback 整列第一张
+    images = raw.get('image_url_list') or []
+    covers = [it for it in images if isinstance(it, dict) and it.get('image_type') == 2]
+    pick = covers[0] if covers else (images[0] if images and isinstance(images[0], dict) else None)
+    cover_url = ''
+    if pick and pick.get('image_url'):
+        cover_url = pick['image_url']
+        src['cover_image'] = cover_url
+
+    # 图集兜底: 检查哪些图既没在 body inline, 也不是封面 → append 到 body 末尾
+    inlined_urls = set(re.findall(r'\[image:\s*(\S+?)\]', body))
+    missing = []
+    for it in images:
+        if not isinstance(it, dict):
+            continue
+        u = it.get('image_url', '') or ''
+        if not u:
+            continue
+        if u in inlined_urls:
+            continue   # 已 inline 不重复
+        if u == cover_url:
+            continue   # 封面已 src-cover 单独渲染
+        missing.append(u)
+
+    if missing:
+        suffix = '\n\n--- 附图 ---\n' + '\n'.join(f'[image: {u}]' for u in missing)
+        body = body + suffix
+
+    if body:
+        src['body_text'] = body
+
+    # title / url 兜底: case_data 漏填时从 raw 补 (Agent 一般会填)
+    if not src.get('title') and raw.get('title'):
+        src['title'] = raw['title']
+    if not src.get('url') and raw.get('content_link'):
+        src['url'] = raw['content_link']
+
+
+# =============================================================================
+# 校验
+# =============================================================================
+def validate(case_data: dict, strict: bool = True) -> list[str]:
+    """返回错误信息列表 (空 list = 通过).
+
+    优先使用 jsonschema (Draft 2020-12); 不可用时退化到最小结构检查 (必填 key 存在 + 类型对).
+    strict=True 时, 任何错误抛 SystemExit(1); strict=False 仅返回错误列表.
+    """
+    errors: list[str] = []
+
+    try:
+        from jsonschema import Draft202012Validator  # type: ignore
+        schema = load_json(SCHEMA_PATH)
+        validator = Draft202012Validator(schema)
+        for err in sorted(validator.iter_errors(case_data), key=lambda e: list(e.absolute_path)):
+            path = '$' + ''.join(f'.{p}' if isinstance(p, str) else f'[{p}]' for p in err.absolute_path)
+            errors.append(f'{path}: {err.message}')
+    except ImportError:
+        # 退化: 最小检查
+        errors.extend(_minimal_check(case_data))
+
+    if errors and strict:
+        for e in errors:
+            print(f'  ✗ {e}', file=sys.stderr)
+        print(f'  ↳ schema: {SCHEMA_PATH}  (要看字段约束直接 Read 这个文件, 不要猜路径)', file=sys.stderr)
+        die(f'schema 校验失败, 共 {len(errors)} 项 (装 `pip install jsonschema` 可看完整 Draft 2020-12 报告)')
+    return errors
+
+
+def _minimal_check(d: dict) -> list[str]:
+    """无 jsonschema 时的兜底: 仅检 顶层必填 + steps 元素必填 + IO 元素必填."""
+    errs: list[str] = []
+    top_required = ['page_title', 'procedure', 'declarations', 'source', 'steps']
+    for k in top_required:
+        if k not in d:
+            errs.append(f'$.{k}: 缺失必填字段')
+    if not isinstance(d.get('steps'), list):
+        errs.append('$.steps: 必须是 array')
+        return errs
+    # 所有 step 都要的基础字段; effect/action 仅非 block 步要 (block 是控制容器)
+    step_required = ['id', 'kind', 'via', 'inputs', 'outputs', 'intent']
+    exec_only = ['effect', 'action']               # kind != block 才要
+    io_required = ['type', 'value', 'anchor']
+    for i, step in enumerate(d['steps']):
+        if not isinstance(step, dict):
+            errs.append(f'$.steps[{i}]: 必须是 object'); continue
+        need = step_required + ([] if step.get('kind') == 'block' else exec_only)
+        for k in need:
+            if k not in step:
+                errs.append(f'$.steps[{i}].{k}: 缺失必填字段')
+        for io_kind in ('inputs', 'outputs'):
+            for j, item in enumerate(step.get(io_kind, []) or []):
+                if not isinstance(item, dict):
+                    errs.append(f'$.steps[{i}].{io_kind}[{j}]: 必须是 object'); continue
+                for k in io_required:
+                    if k not in item:
+                        errs.append(f'$.steps[{i}].{io_kind}[{j}].{k}: 缺失必填字段')
+    return errs
+
+
+# =============================================================================
+# 占位门禁: 文本类 value 是 <占位> → 拒绝渲染 (强制回填真实内容)
+# 模态判定与 lint-case.py Check 3 一致: 文本类必须真内容, 媒体类可 <描述>, inferred 放行.
+# =============================================================================
+_PH_RE = re.compile(r'^\s*<[^>]*>\s*$')
+# 显式「原文未提供」标记 → 放行 (LLM 判断原文确无该信息时的轻量逃生, 等同 inferred)。
+# 写法如: <占位>(原文未提供) / <某分析>(原文确无该信息)。与 lint-case.py 的 NOSRC_RE 保持一致。
+_NOSRC_RE = re.compile(r'原[文帖].{0,2}(未提供|未给出|未写|没有|没写|确无|无)')
+_TEXT_KW = ('提示词', '描述', '参数', '评', '大纲', '脚本', '文案', '歌词', '字幕',
+            '标题', '正文', '词', '知识', '工作流', '对标', '规格', '批处理', '模板', '版式',
+            '数据', '分析', '报告', '记录', '方案', '思路', '设定', '依据', '标准', '清单', '列表', '文本', '文字')
+_MEDIA_KW = ('图', '视频', '音频', '帧', '片段', '截图', '蒙版', '音效', '配音', 'BGM',
+             '数字人', '滤镜', '海报', '封面')
+
+
+def _modality(type_name: str, type_reg: dict) -> str:
+    base, seen = type_name, set()
+    while base in (type_reg or {}) and base not in seen:
+        seen.add(base)
+        ent = type_reg[base]
+        ext = ent.get('extends') if isinstance(ent, dict) else None
+        if not ext:
+            break
+        base = ext
+    nm = base or type_name or ''
+    if any(k in nm for k in _TEXT_KW):
+        return 'text'
+    if any(k in nm for k in _MEDIA_KW):
+        return 'media'
+    return 'unknown'
+
+
+def check_placeholder_values(case_data: dict) -> list[str]:
+    """揪出文本类(非媒体、非 inferred)IO value 仍是 <占位> 的——这些必须回填真内容才放行渲染."""
+    bad: list[str] = []
+    for p in case_data.get('procedures') or []:
+        pid = p.get('id') or '?'
+        type_reg = p.get('type_registry') or {}
+        for i, step in enumerate(p.get('steps') or []):
+            if not isinstance(step, dict):
+                continue
+            for kind in ('inputs', 'outputs'):
+                for j, io in enumerate(step.get(kind) or []):
+                    if not isinstance(io, dict) or io.get('inferred'):
+                        continue
+                    v = io.get('value')
+                    if not isinstance(v, str):
+                        continue
+                    if _NOSRC_RE.search(v):
+                        continue   # 显式标了「原文未提供」→ 放行 (LLM 确认原文确无)
+                    if not _PH_RE.match(v):
+                        continue
+                    if _modality(io.get('type', '') or '', type_reg) == 'media':
+                        continue   # 图/视频/音频 用 <描述> 合理
+                    bad.append(f"[{pid}] {step.get('id')}.{kind}[{j}] type={io.get('type','')!r} value={v.strip()!r}")
+    return bad
+
+
+# =============================================================================
+# main
+# =============================================================================
+def main() -> None:
+    ap = argparse.ArgumentParser(
+        prog='render-case.py',
+        description='Procedure DSL · case_data → HTML 渲染',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        epilog=__doc__.split('用法:')[1] if __doc__ else '',
+    )
+    ap.add_argument('--workflow', type=Path, required=True,
+                    help='workflow.json (含 procedures 数组). 内部组装 case_data = '
+                         'workflow + source-input merge + --page-title + --case-id, 不落盘 case_data.json. '
+                         '配合 --source-input / --page-title / --case-id 一起用.')
+    ap.add_argument('--page-title', type=str, default=None,
+                    help='页面标题, 仅与 --workflow 配对. e.g. "Case 5 · 产品宣传图 AI 工作流可视化"')
+    ap.add_argument('--case-id', type=str, default=None,
+                    help='case 编号, 仅与 --workflow 配对')
+    ap.add_argument('--source-input', type=Path, dest='source_input',
+                    help='可选: 原帖 raw json 路径 (e.g. input/case-N-raw.json). 给了的话, 自动把 '
+                         'raw.body_text + 封面图 / 标题 / URL 填到 case_data.source 对应字段 '
+                         '(body_text/cover_image 直接覆盖 case_data 同字段, title/url 仅在 case_data 缺时填), '
+                         '让 HTML 折叠原文区显示完整原帖正文 + 内嵌图. excerpt/author/date 等 Agent 推断字段不动.')
+    ap.add_argument('--out', type=Path,
+                    help='输出 HTML 路径. --validate 时可省略')
+    ap.add_argument('--validate', action='store_true',
+                    help='只做 schema 校验, 不渲染. 退出码 0=通过, 1=失败')
+    ap.add_argument('--no-validate', action='store_true',
+                    help='跳过校验直接渲染 (不推荐)')
+    ap.add_argument('--allow-placeholders', action='store_true',
+                    help='跳过「文本类 value 占位」门禁 (调试用; 默认: 有文本类 <占位> value 就拒绝出 HTML)')
+    args = ap.parse_args()
+
+    # workflow.json 装 procedures 主体 + cli 套 case-level meta
+    case_data = load_json(args.workflow)
+    if args.page_title:
+        case_data['page_title'] = args.page_title
+    if args.case_id is not None:
+        try:
+            case_data['case_id'] = int(args.case_id)
+        except ValueError:
+            case_data['case_id'] = args.case_id
+    # source 由 --source-input 提供 (workflow.json 不含 source); 没给就让 schema validate 报错
+
+    # raw 原帖 → case_data.source merge (在 validate 前, 让 schema 校验看到的就是完整版)
+    if args.source_input:
+        merge_raw_source(case_data, args.source_input)
+
+    def _count_steps(cd):
+        return sum(len(p.get('steps') or []) for p in cd.get('procedures', []))
+
+    if not args.no_validate:
+        validate(case_data, strict=not args.validate)
+
+    # 占位硬门禁: 文本类 value 仍是 <占位> → 拒绝出 HTML, 逼回填真内容 (媒体类/inferred/原文未提供 放行)。
+    # 放在这里 (validate 块外), 所以 --no-validate 也绕不过; --validate 模式也会查。
+    if not args.allow_placeholders:
+        ph = check_placeholder_values(case_data)
+        if ph:
+            print(f'render-case: ✗ {len(ph)} 处文本类 value 仍是 <占位>, 拒绝出 HTML —— 必须回填真实内容:', file=sys.stderr)
+            for h in ph:
+                print(f'    - {h}', file=sys.stderr)
+            print('  → 用 wf-patch 的 `@quote|<起锚>|<止锚>` + `--resolve-quotes --source <原文> --ocr <ocr.txt>` '
+                  '从原文/OCR 回填真内容;\n'
+                  '    原文确无该信息 → value 写成 `<占位>(原文未提供)`(或给该 IO 标 `inferred:true`+reason)即可放行;\n'
+                  '    媒体类(图/视频/音频)用 `<描述>` 本就不受此限。', file=sys.stderr)
+            print('  (确需带占位渲染才加 --allow-placeholders)', file=sys.stderr)
+            die(f'{len(ph)} 处文本类 value 占位未回填')
+
+    # 结构完整性硬门禁: ① 干骨架没填满(via 空 / 输入既无 value 又无 anchor) ② anchor 没闭合
+    # (透传没回填 / anchor 写成 JSON 路径) → 拒绝出 HTML, 逼回 workflow.json 修缮。
+    # 和占位门禁一样放在 validate 块外, --no-validate 也绕不过; 都是确定性判断, 不会困在不可满足的 loop。
+    _lint = _load_lint()
+    struct_issues = (_lint.check_skeleton_filled(case_data)
+                     + _lint.check_anchor_closure(case_data)
+                     + _lint.check_dataflow_connected(case_data)
+                     + _lint.check_unresolved_quotes(case_data))
+    if struct_issues:
+        print(f'render-case: ✗ {len(struct_issues)} 处结构未完成, 拒绝出 HTML —— workflow.json 还没填好:', file=sys.stderr)
+        for h in struct_issues:
+            print(f'    - {h}', file=sys.stderr)
+        print('  → Phase 2.0 把骨架填满: 每步补 via; 每个输入要么填 value(@quote 拽原文)要么连 anchor ← 上游编号;\n'
+              '    透传输入跑 `wf-patch.py --workflow <wf> --resolve-passthrough` 自动回填;\n'
+              '    anchor 用输出**编号** ← s1o1, 不要写 JSON 路径 ← p1.s1.outputs[0]。', file=sys.stderr)
+        die(f'{len(struct_issues)} 处结构未完成')
+
+    if not args.no_validate and args.validate:
+        n_procs = len(case_data.get('procedures', []))
+        print(f'render-case: ✓ {SCHEMA_PATH.name} 校验通过 '
+              f'({n_procs} procedure{"s" if n_procs > 1 else ""}, {_count_steps(case_data)} steps)')
+        if not args.out:
+            return
+
+    if not args.out:
+        ap.error('--out 必填 (除非用 --validate 只校验)')
+
+    build_html = _import_build_html()
+    html = build_html(case_data)
+    args.out.parent.mkdir(parents=True, exist_ok=True)
+    # newline='' 保留 build_html 返回串里的换行原貌, 防 Windows 把 \n 翻译成 \r\n
+    args.out.write_text(html, encoding='utf-8', newline='')
+    n_procs = len(case_data.get('procedures', []))
+    print(f'render-case: ✓ wrote {args.out} ({len(html):,} chars, '
+          f'{n_procs} procedure{"s" if n_procs > 1 else ""}, {_count_steps(case_data)} steps)')
+
+
+if __name__ == '__main__':
+    main()

+ 712 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/renderer.py

@@ -0,0 +1,712 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+renderer.py — Procedure DSL 可视化共享模板.
+
+每个 case 提供 case_data (一个 dict, 见 build_html 的 docstring),
+import 本模块并调用 build_html(case_data) → HTML 字符串.
+
+spec 引用: spec.md §12 (.html 可视化结构规范).
+"""
+import html
+import json
+import re
+from pathlib import Path
+
+
+# ── 数据 loaders (从 spec/taxonomy 单一来源加载) ────────────────────
+def _load_json(rel_path: str) -> dict:
+    """从 spec/ 子路径加载 JSON. rel_path 是相对 spec/ 的路径 (e.g. 'taxonomy/type.json')."""
+    return json.loads((Path(__file__).resolve().parent.parent / rel_path).read_text(encoding='utf-8'))
+
+
+def _load_stdlib_types() -> dict:
+    """type stdlib 渲染元信息. 新结构 type.json 无 type_metadata → 返回 {};
+    stdlib 叶子的 in_tree 标记在 build_html 里按 type.json 的 $leaves 补齐."""
+    return {}
+
+
+_DRAWER_TITLES = {
+    'effect': ('作用 (chip 上 data-prefix="作用")',
+               '这一步在 AIGC 生产工序链中的位置 + 作用; 从 §A.1 字典树取 L3 叶子'),
+    'action': ('动作 (chip 上 data-prefix="动作")',
+               '这一步的动作动词; 从 §A.2 字典树取路径'),
+    'type':   ('类型 (chip 上 data-type)',
+               '领域语义类型 (按功能角色分类: 程序控制/数据复用/内容/知识); 从 §A.3 字典树取叶子'),
+}
+
+
+def _add_label_suffix(node, depth=0):
+    """递归把 dict 的 key 加 (L1)/(L2) 显示后缀, 让 drawer UI 区分层级.
+    leaf string 保留原状; $* 元数据 key 跳过."""
+    if not isinstance(node, dict):
+        return node
+    result = {}
+    for k, v in node.items():
+        if k.startswith('$'):
+            continue
+        new_k = k
+        if isinstance(v, dict):
+            if depth == 0:
+                new_k = f'{k} (L1)'
+            elif depth == 1:
+                new_k = f'{k} (L2)'
+        result[new_k] = _add_label_suffix(v, depth + 1)
+    return result
+
+
+def _tree_to_drawer(nodes):
+    """新结构 最终分类树 (list of {分类名称, 分类说明, 子分类}) → drawer 嵌套 dict.
+    叶子 → {名称: 分类说明 字符串}; 非叶 → {名称: 子树 dict}. 层级即 根→叶 路径."""
+    out = {}
+    for n in nodes or []:
+        name = n.get('分类名称', '?')
+        kids = n.get('子分类') or []
+        out[name] = _tree_to_drawer(kids) if kids else (n.get('分类说明', '') or '')
+    return out
+
+
+def _load_drawer_tree(dim: str) -> dict:
+    """spec/taxonomy/{dim}.json → 重塑为 drawer UI 需要的 {title, desc, tree} 格式.
+    新结构读 最终分类树 (中文键); 自动加 (L1)/(L2) 层级标签. dim ∈ {'effect', 'action', 'type'}."""
+    raw = _load_json(f'taxonomy/{dim}.json')
+    title, desc = _DRAWER_TITLES[dim]
+    nested = _tree_to_drawer(raw.get('最终分类树', []))
+    return {
+        'title': title,
+        'desc': desc,
+        'tree': _add_label_suffix(nested, depth=0),
+    }
+
+
+# =============================================================================
+# STDLIB · type registry (字典树 §A.3 叶子的 in_tree 标记基础; 现为空, build_html 按 $leaves 补齐)
+# =============================================================================
+STDLIB_TYPE_REGISTRY = _load_stdlib_types()
+
+
+# =============================================================================
+# 字典树 (spec §A.1 作用 / §A.2 动作 / §A.3 类型)
+# =============================================================================
+EFFECT_TREE = _load_drawer_tree("effect")
+
+ACTION_TREE = _load_drawer_tree("action")
+
+TYPE_TREE = _load_drawer_tree("type")
+
+
+def _build_type_paths() -> dict:
+    """type.json 最终分类树 → {叶子名: '根/.../叶子' 路径}, 供 chip 显示完整路径."""
+    raw = _load_json('taxonomy/type.json')
+    out: dict = {}
+    def walk(nodes, prefix):
+        for n in nodes:
+            path = prefix + [n.get('分类名称', '')]
+            kids = n.get('子分类') or []
+            if kids:
+                walk(kids, path)
+            else:
+                out[n.get('分类名称', '')] = '/'.join(path)
+    walk(raw.get('最终分类树', []), [])
+    return out
+
+
+TYPE_PATHS = _build_type_paths()
+
+FEATURE_TAXONOMY = _load_json("taxonomy/feature.json")
+
+EXTERNAL_TAXONOMIES = {
+    '实质': {'title': '实质 (内容是什么)',  'desc': '理念 / 表象 — 911 路径',
+            'source': 'external', 'file': '分类库导出_实质_*.json'},
+    '形式': {'title': '形式 (内容怎么呈现)', 'desc': '呈现 / 架构 — 565 路径',
+            'source': 'external', 'file': '分类库导出_形式_*.json'},
+}
+
+
+# =============================================================================
+# Render helpers
+# =============================================================================
+def he(s):
+    """HTML escape, 默认 quote=True 把 `"` 转成 `&quot;`.
+    这点关键: title / data-* / class 等属性值如果含 `"` 会提前终止属性,
+    导致 tooltip 显示不完整 (典型 bug: '原文方法 3 只说"自己写动作"' 在 title 中只显示到 "只说" 就被截断).
+    """
+    if s is None:
+        return ''
+    return html.escape(str(s))
+
+
+def render_intent(text):
+    """目的列: 简短自然语言句, **尽量** 把其他列里的结构化值都做成 {kind:value} token.
+
+    每个 token 底色对应其引用的列, 让人一眼看出该值来自哪里. 合法 kind:
+      effect          → 作用列 (灰, 需求组)
+      via             → 外部工具列 (浅绿 + 等宽字体, 实现组)
+      act             → 动作列 (绿, 实现组)
+      control         → 逻辑控制列 (浅青, 实现组) — 并行/遍历/分支/请求/等待
+      in-type         → 输入·类型 (黄圆胶囊)         out-type → 输出·类型 (蓝圆胶囊)
+      in-sub          → 输入·实质 (黄矩形 tag)        out-sub  → 输出·实质 (蓝矩形 tag)
+      in-form         → 输入·形式 (黄矩形 tag 斜体)   out-form → 输出·形式 (蓝矩形 tag 斜体)
+
+    **特性列 (feature) 不允许在 intent 中引用** — feature 是内部执行特征 (随机/幂等/人工/读写外部),
+    不出现在面向使用者的描述. 写成 `ik-other` 灰色显示作为 lint 警告.
+
+    严禁变量名 token (no `{in:X}` / `{out:X}`); 严禁 dataflow 公式 / case-specific 简写.
+    """
+    def sub(m):
+        kind = m.group(1)
+        val = m.group(2)
+        kc = {
+            'effect': 'ik-effect',
+            'via': 'ik-via',
+            'act': 'ik-act',
+            'in-type': 'ik-in-type', 'out-type': 'ik-out-type',
+        }.get(kind, 'ik-other')
+        return f'<span class="intent-tok {kc}">{he(val)}</span>'
+    return re.sub(r'\{([\w-]+):([^}]+)\}', sub, text or '')
+
+
+def render_chip(type_name):
+    if not type_name:
+        return ''
+    if type_name == '-':
+        return he(type_name)
+    # 显示完整路径 (e.g. 程序控制类型/指令/提示词); data-type 仍存叶子名, drawer 查找不受影响.
+    # case-specific 类型 (不在字典树) 显示原名.
+    disp = TYPE_PATHS.get(type_name, type_name)
+    return f'<span class="chip" data-type="{he(type_name)}">{he(disp)}</span>'
+
+
+def render_path(prefix, value):
+    if not value:
+        return ''
+    if isinstance(value, list):
+        spans = []
+        for val in value:
+            if val:
+                spans.append(f'<span data-prefix="{prefix}" data-value="{he(val)}">{he(val)}</span>')
+        return '\n'.join(spans)
+    if isinstance(value, str):
+        if '+' in value:
+            parts = [p.strip() for p in value.split('+') if p.strip()]
+            spans = []
+            for val in parts:
+                spans.append(f'<span data-prefix="{prefix}" data-value="{he(val)}">{he(val)}</span>')
+            return '\n'.join(spans)
+        return f'<span data-prefix="{prefix}" data-value="{he(value)}">{he(value)}</span>'
+    return ''
+
+
+_VALUE_DESC_RE = re.compile(r'^<(.+)>$', re.DOTALL)
+
+
+def render_value(vl):
+    """值列渲染:
+      - 若整段以 `<...>` 括起 → 渲染为斜体浅灰背景, 表示"这是对内容的描述, 不是内容本身"
+        (适用于无法在 cell 中直接嵌入的非文本数据: 视频/图像/音频).
+      - 否则 → 渲染为普通文本 (适用于文本数据本身, 如 prompt 全文).
+    """
+    if vl is None:
+        return ''
+    s = str(vl).strip()
+    m = _VALUE_DESC_RE.match(s)
+    if m:
+        inner = m.group(1)
+        return f'<span class="value-desc">&lt;{he(inner)}&gt;</span>'
+    return f'<span class="natural">{he(s)}</span>'
+
+
+def render_focus_class(cell_key, focus_list):
+    return ' row-focus' if cell_key in (focus_list or []) else ''
+
+
+def cell_attrs(field_key, focus, io_reason=None, is_empty=False):
+    """组合 cell 的额外 class 和属性 (focus + 推断补全).
+
+    field_key 例: 'action', 'in-value-0', 'out-type-1', etc.
+    io_reason: 当前 cell 所属 IO item 整体被标 inferred 时, 传入 reason 字符串.
+    is_empty: 该 cell 内容是否为空 (留空的推断 cell 角标变 推?).
+    返回 (class_suffix_str, extra_attrs_str).
+    """
+    cls = render_focus_class(field_key, focus)
+    extra = ''
+    if io_reason:
+        cls += ' is-inferred'
+        if is_empty:
+            cls += ' is-low-confidence'
+        extra = f' title="推断补全: {he(io_reason)}"'
+    return cls, extra
+
+
+def render_io_value(item):
+    """IO 值列: output 的 id 作为小标签贴在值前 (供 anchor 1:1 引用对照); input 无 id."""
+    iid = item.get('id')
+    id_tag = f'<span class="io-id" data-io-id="{he(iid)}">{he(iid)}</span> ' if iid else ''
+    return id_tag + render_value(item.get('value'))
+
+
+_OUT_ID_RE = re.compile(r'^s\d+(?:\.\d+)?o\d+$')
+_OUT_PATH_RE = re.compile(r's(\d+(?:\.\d+)?)\.outputs\[(\d+)\]')
+
+
+def _ref_output_id(anchor):
+    """把一条输入 anchor (来源 ←) 归一到它引用的**输出编号**, 取不到返回 None.
+
+    认: ← s1o1 / ← s5o1[-1] (去索引) / ← p1.s1.outputs[0] (JSON 路径式也救, 归一成 s1o1)。
+    不认 (返回 None): ← 工序输入 / ← s1.名字 (按名引用) / 字面量。供"去处"自动反推用。
+    """
+    if not anchor:
+        return None
+    s = str(anchor).strip()
+    if s.startswith('←'):
+        s = s[1:].strip()
+    m = _OUT_PATH_RE.search(s)                       # JSON 路径式 → sNo(idx+1)
+    if m:
+        return f's{m.group(1)}o{int(m.group(2)) + 1}'
+    base = s.split('[')[0].strip()                   # 去掉 [i] / [-1] 索引
+    return base if _OUT_ID_RE.match(base) else None
+
+
+def build_output_consumers(proc):
+    """扫一个工序内所有输入的来源 ← anchor, 反推 {输出编号: [消费它的步骤 id]}。
+
+    "去处"(输出 →)其实是"来源"(输入 ←)的逆: 谁的输入引用了本输出, 谁就是去处。
+    模型没填 → 时, 渲染层据此自动补出去处, 不必逼模型冗余地正反都填。
+    """
+    consumers: dict = {}
+    for st in proc.get('steps', []) or []:
+        sid = st.get('id')
+        for io in st.get('inputs') or []:
+            oid = _ref_output_id(io.get('anchor'))
+            if oid:
+                lst = consumers.setdefault(oid, [])
+                if sid and sid not in lst:
+                    lst.append(sid)
+    return consumers
+
+
+def render_step_row(step, idx_label, type_reg=None, consumers=None):
+    """渲染一个 step (kind: step / block / nested) 为一组 tr 行 (14 列).
+
+    需求组 (rowspan): # / 目的 / 作用 / 实质 / 形式 (后两者 step 级).
+    输入/输出 (逐 IO): 类型 / 值 / 来源(去处). 实现组 (rowspan): 外部工具 / 动作 / 指令.
+    type_reg: 已合并 STDLIB + case-specific 的类型注册表 (用于 chip in_tree 标记).
+    consumers: {输出编号: [消费步骤 id]} 反向索引; 输出 → 没填时据此自动补"去处"。
+    """
+    inputs = step.get('inputs', [])
+    outputs = step.get('outputs', [])
+    N = max(len(inputs), len(outputs), 1)
+    focus = step.get('focus', [])
+
+    is_nested = step['kind'] == 'nested'
+    is_block = step['kind'] == 'block'
+
+    main_cls = 'step step-main'
+    if is_block:
+        main_cls = 'step block-header'
+    if is_nested:
+        main_cls = 'step step-main step-nested'
+    sub_cls = 'step step-sub'
+
+    data_step = step['id']
+    data_group = step.get('group', '')
+
+    rows = []
+    for k in range(N):
+        tr_cls = main_cls if k == 0 else sub_cls
+        attrs = f' data-step="{data_step}"'
+        if data_group:
+            attrs += f' data-group="{data_group}"'
+        attrs += f' data-focus="{",".join(focus)}"'
+        if k == 0:
+            attrs = f' id="{data_step}"' + attrs
+
+        cells = []
+        if k == 0:
+            rs = f' rowspan="{N}"' if N > 1 else ''
+            arrow = '<span class="arrow">▼</span> ' if is_block else ''
+            indent = '  └ ' if is_nested else ''
+            cells.append(f'<td class="idx{render_focus_class("idx", focus)}"{rs}>{arrow}{indent}{he(idx_label)}</td>')
+            intent_html = render_intent(step.get('intent', ''))
+            c, a = cell_attrs('intent', focus)
+            cells.append(f'<td class="intent{c}"{a}{rs}><div class="intent-text">{intent_html}</div></td>')
+            c, a = cell_attrs('effect', focus)
+            cells.append(f'<td class="effect{c}"{a}{rs}>{render_path("作用", step.get("effect", ""))}</td>')
+            c, a = cell_attrs('substance', focus)
+            cells.append(f'<td class="substance{c}"{a}{rs}>{render_path("实质", step.get("substance")) if step.get("substance") else ""}</td>')
+            c, a = cell_attrs('form', focus)
+            cells.append(f'<td class="form{c}"{a}{rs}>{render_path("形式", step.get("form")) if step.get("form") else ""}</td>')
+
+        in_item = inputs[k] if k < len(inputs) else None
+        if in_item:
+            tp = in_item.get('type'); vl = in_item.get('value'); ac = in_item.get('anchor')
+            io_inf = in_item.get('inferred_reason') if in_item.get('inferred') else None
+            c, a = cell_attrs(f'in-type-{k}', focus, io_inf, is_empty=not tp)
+            cells.append(f'<td class="in-type{c}"{a}>{render_chip(tp)}</td>')
+            c, a = cell_attrs(f'in-value-{k}', focus, io_inf, is_empty=not vl)
+            cells.append(f'<td class="in-value{c}"{a}>{render_io_value(in_item)}</td>')
+            c, a = cell_attrs(f'in-anchor-{k}', focus, io_inf, is_empty=not ac)
+            cells.append(f'<td class="in-anchor{c}"{a}><span class="flow">{he(ac)}</span></td>')
+        else:
+            cells += ['<td class="in-type"></td>', '<td class="in-value"></td>', '<td class="in-anchor"></td>']
+
+        if k == 0:
+            rs = f' rowspan="{N}"' if N > 1 else ''
+            c, a = cell_attrs('via', focus)
+            cells.append(f'<td class="via{c}"{a}{rs}>{he(step.get("via", ""))}</td>')
+            c, a = cell_attrs('action', focus)
+            cells.append(f'<td class="action{c}"{a}{rs}>{render_path("动作", step.get("action", ""))}</td>')
+            c, a = cell_attrs('directive', focus)
+            directive = step.get('directive', '') or ''
+            inner = f'<span class="natural">{he(directive)}</span>' if directive else ''
+            cells.append(f'<td class="directive{c}"{a}{rs}>{inner}</td>')
+
+        out_item = outputs[k] if k < len(outputs) else None
+        if out_item:
+            tp = out_item.get('type'); vl = out_item.get('value'); ac = (out_item.get('anchor') or '')
+            io_inf = out_item.get('inferred_reason') if out_item.get('inferred') else None
+            # 去处: 模型填了就用原值; 没填则从下游 ← 反推 (谁的输入引用了本输出)。
+            derived = ''
+            if not ac.strip() and consumers and out_item.get('id'):
+                cs = consumers.get(out_item['id'])
+                if cs:
+                    derived = '→ ' + ', '.join(cs)
+            flow_txt = ac if ac.strip() else derived
+            flow_cls = 'flow' if ac.strip() else ('flow derived' if derived else 'flow')
+            flow_attr = '' if ac.strip() else (' title="自动推导自下游来源 (模型未填 →)"' if derived else '')
+            c, a = cell_attrs(f'out-type-{k}', focus, io_inf, is_empty=not tp)
+            cells.append(f'<td class="out-type{c}"{a}>{render_chip(tp)}</td>')
+            c, a = cell_attrs(f'out-value-{k}', focus, io_inf, is_empty=not vl)
+            cells.append(f'<td class="out-value{c}"{a}>{render_io_value(out_item)}</td>')
+            c, a = cell_attrs(f'out-anchor-{k}', focus, io_inf, is_empty=not flow_txt)
+            cells.append(f'<td class="out-anchor{c}"{a}><span class="{flow_cls}"{flow_attr}>{he(flow_txt)}</span></td>')
+        else:
+            cells += ['<td class="out-type"></td>', '<td class="out-value"></td>', '<td class="out-anchor"></td>']
+
+        rows.append(f'<tr class="{tr_cls}"{attrs}>{"".join(cells)}</tr>')
+    return '\n      '.join(rows)
+
+
+def render_declarations(case_data, procedure=None):
+    """工序头部 + declare 块 (输入/资源/返回), 可折叠.
+
+    procedure: 该工序的 dict (新 schema 下 case_data.procedures[i]). 不传时退化到
+    老 case_data.procedure (兼容老 case 直到全部迁移完).
+    """
+    proc = procedure if procedure is not None else case_data.get('procedure', {})
+    decls = proc.get('declarations') if procedure is not None else case_data.get('declarations', {})
+    decls = decls or {}
+    parts = []
+    parts.append('<details class="declarations" open>')
+    parts.append('<summary class="decl-summary">')
+    parts.append(f'  <span class="kw">工序</span> <b class="proc-name">{he(proc.get("name", ""))}</b>')
+    if proc.get('purpose'):
+        parts.append(f'  <span class="decl-purpose">#目的: {he(proc["purpose"])}</span>')
+    if proc.get('category'):
+        parts.append(f'  <span class="tag-mini">类别: {he(proc["category"])}</span>')
+    meta_bits = []
+    for label, key in [('平台', 'platform'), ('作者', 'author')]:
+        if proc.get(key):
+            meta_bits.append(f'#{label}: {he(proc[key])}')
+    if case_data.get('case_id') is not None:
+        meta_bits.append(f'case: {he(case_data["case_id"])}')
+    if meta_bits:
+        parts.append(f'  <span class="decl-meta">{" · ".join(meta_bits)}</span>')
+    parts.append('</summary>')
+    parts.append('<div class="decl-body">')
+
+    def section(label, items, renderer):
+        out = [f'<div class="decl-section"><div class="decl-label">{label}</div>']
+        for it in items:
+            out.append(renderer(it))
+        out.append('</div>')
+        return '\n'.join(out)
+
+    def render_io(it):
+        chip = render_chip(it.get('type', ''))
+        name = he(it.get('name', ''))
+        default = it.get('default')
+        line = f'<div class="decl-row">{chip} <span class="name" data-var="{name}">{name}</span>'
+        if default:
+            line += f'  <span class="decl-default">= {he(default)}</span>'
+        if it.get('desc'):
+            line += f'  <span class="decl-desc">— {he(it["desc"])}</span>'
+        return line + '</div>'
+
+    if decls.get('inputs'):
+        parts.append(section('输入', decls['inputs'], render_io))
+    if decls.get('resources'):
+        parts.append(section('资源 (跨 case 长期资产)', decls['resources'], render_io))
+    if decls.get('returns'):
+        ret = decls['returns']
+        chip = render_chip(ret.get('type', ''))
+        line = f'<div class="decl-row">{chip}'
+        if ret.get('note'):
+            line += f'  <span class="decl-desc">— {he(ret["note"])}</span>'
+        line += '</div>'
+        parts.append(f'<div class="decl-section"><div class="decl-label">返回</div>{line}</div>')
+
+    parts.append('</div>')
+    parts.append('</details>')
+    return '\n'.join(parts)
+
+
+_INLINE_MEDIA_RE = re.compile(r'\[(image|video):\s*(https?://[^\s\]]+)\]')
+
+
+def render_source_body(body_text):
+    """把 body_text 渲染为 HTML: [image:URL] → <img>, [video:URL] → <a>, 其他按 \\n 分段."""
+    if not body_text:
+        return ''
+    pieces = []
+    last = 0
+    for m in _INLINE_MEDIA_RE.finditer(body_text):
+        seg = body_text[last:m.start()]
+        if seg.strip():
+            for para in seg.split('\n'):
+                p = para.strip()
+                if p:
+                    pieces.append(f'<p class="src-p">{he(p)}</p>')
+        kind, url = m.group(1), m.group(2)
+        if kind == 'image':
+            pieces.append(f'<div class="src-img-wrap"><img class="src-img" src="{he(url)}" loading="lazy" referrerpolicy="no-referrer" alt=""></div>')
+        else:
+            pieces.append(f'<div class="src-video"><a href="{he(url)}" target="_blank" rel="noopener">▶ 视频</a></div>')
+        last = m.end()
+    tail = body_text[last:]
+    if tail.strip():
+        for para in tail.split('\n'):
+            p = para.strip()
+            if p:
+                pieces.append(f'<p class="src-p">{he(p)}</p>')
+    return '\n'.join(pieces)
+
+
+def render_source(case_data):
+    """原文 折叠块: 元信息 + body_text 完整正文 (含内嵌图片/视频)."""
+    src = case_data.get('source')
+    if not src:
+        return ''
+    url = src.get('url', '')
+    title = src.get('title', '')
+    excerpt = src.get('excerpt', '')
+    body_text = src.get('body_text', '')
+    cover = src.get('cover_image', '')
+    meta_bits = [b for b in [src.get('platform'), src.get('author'), src.get('date')] if b]
+    parts = ['<details class="source-block">']
+    parts.append(f'<summary>原文: <b>{he(title or "(无标题)")}</b></summary>')
+    parts.append('<div class="source-body">')
+    if url:
+        parts.append(f'<div class="source-url"><a href="{he(url)}" target="_blank" rel="noopener">{he(url)}</a></div>')
+    if meta_bits:
+        parts.append(f'<div class="source-meta">{" · ".join(he(b) for b in meta_bits)}</div>')
+    if excerpt:
+        parts.append(f'<p class="source-excerpt"><b>摘要</b>: {he(excerpt)}</p>')
+    if cover:
+        parts.append(f'<div class="src-cover"><img class="src-img" src="{he(cover)}" loading="lazy" referrerpolicy="no-referrer" alt=""></div>')
+    if body_text:
+        parts.append('<hr class="src-divider">')
+        parts.append('<div class="source-full">')
+        parts.append(render_source_body(body_text))
+        parts.append('</div>')
+    parts.append('</div></details>')
+    return '\n'.join(parts)
+
+
+def render_thead():
+    return '''<thead>
+  <tr>
+    <th colspan="5" class="col-group-demand">需求</th>
+    <th colspan="3" class="col-group-input">输入</th>
+    <th colspan="3" class="col-group-impl">实现</th>
+    <th colspan="3" class="col-group-output">输出</th>
+  </tr>
+  <tr>
+    <th class="col-idx">#</th>
+    <th class="col-intent">目的</th>
+    <th class="col-effect">作用</th>
+    <th class="col-substance">实质</th>
+    <th class="col-form">形式</th>
+    <th class="col-in-type">类型</th>
+    <th class="col-in-value">值</th>
+    <th class="col-in-anchor">来源</th>
+    <th class="col-via">外部工具</th>
+    <th class="col-action">动作</th>
+    <th class="col-directive">指令</th>
+    <th class="col-out-type">类型</th>
+    <th class="col-out-value">值</th>
+    <th class="col-out-anchor">去处</th>
+  </tr>
+</thead>'''
+
+
+def render_legend():
+    return '''<div class="legend">
+    <div class="group gray">
+      <span class="gh">需求</span>
+      <span class="col-toggle" data-col="idx">#</span>
+      <span class="col-toggle" data-col="intent">目的</span>
+      <span class="col-toggle" data-col="effect">作用</span>
+      <span class="col-toggle" data-col="substance">实质</span>
+      <span class="col-toggle" data-col="form">形式</span>
+    </div>
+    <div class="group yellow">
+      <span class="gh">输入</span>
+      <span class="col-toggle" data-col="in-type">类型</span>
+      <span class="col-toggle" data-col="in-value">值</span>
+      <span class="col-toggle" data-col="in-anchor">来源</span>
+    </div>
+    <div class="group green">
+      <span class="gh">实现</span>
+      <span class="col-toggle" data-col="via">外部工具</span>
+      <span class="col-toggle" data-col="action">动作</span>
+      <span class="col-toggle" data-col="directive">指令</span>
+    </div>
+    <div class="group blue">
+      <span class="gh">输出</span>
+      <span class="col-toggle" data-col="out-type">类型</span>
+      <span class="col-toggle" data-col="out-value">值</span>
+      <span class="col-toggle" data-col="out-anchor">去处</span>
+    </div>
+    <span class="inferred-toggle" id="inferred-toggle" title="高亮所有标为推断补全的 cell">高亮推断</span>
+    <span class="legend-hint">点击列名 ↔ 显示/隐藏 · 点击组名 ↔ 整组切换 · 「推」角标 hover 看推断理由</span>
+  </div>'''
+
+
+# =============================================================================
+# CSS
+# =============================================================================
+CSS = (Path(__file__).resolve().parent / "styles.css").read_text(encoding="utf-8")
+
+# =============================================================================
+# JS
+# =============================================================================
+JS_TEMPLATE = (Path(__file__).resolve().parent / "script.js").read_text(encoding="utf-8")
+
+
+# =============================================================================
+# build_html — 主入口
+# =============================================================================
+def build_html(case_data: dict) -> str:
+    """从 case_data 构建完整 HTML.
+
+    case_data 结构 (新 schema):
+        page_title:    str
+        case_id:       int | str | None
+        source:        {platform, author, date, url, title, excerpt, body_text?, cover_image?}
+        procedures: [
+            {
+                id:            str (e.g. 'p1-simple' / 'p1')
+                name:          str
+                purpose:       str
+                category:      str
+                platform:      str
+                author:        str
+                declarations:  {inputs[], resources[], returns{}}
+                type_registry: dict (该工序的 case-specific 类型, 跟 STDLIB 合并)
+                steps:         [{id, kind, effect, via, action, ...}]
+                return_row:    {arrow, text}
+            },
+            ...
+        ]
+
+    """
+    # type_registry 合并: STDLIB + 所有 procedures.type_registry (跨工序合并)
+    type_reg = dict(STDLIB_TYPE_REGISTRY)
+    for proc in case_data.get('procedures', []):
+        type_reg.update(proc.get('type_registry') or {})
+
+    # 补齐 type.json $leaves: 两类问题都要修
+    #   (a) 缺 entry: STDLIB 跟 type.json 不同步, 21 个叶子在字典树但 STDLIB 没条目
+    #       → 补 stub {in_tree: True}
+    #   (b) 有 entry 但缺 in_tree 标记: e.g. type.json.type_metadata 里"提示词" 有 metadata 但没 in_tree,
+    #       同时它又是 $leaves 之一. STDLIB 直接复制 type_metadata 段就没带 in_tree.
+    #       → in-place 加 in_tree=True
+    # 这是 script.js isInTypeTree() 正确返 true 的硬要求.
+    try:
+        leaves_file = Path(__file__).resolve().parent.parent / 'taxonomy' / 'type.json'
+        if leaves_file.exists():
+            leaves_data = json.loads(leaves_file.read_text(encoding='utf-8'))
+            for leaf in leaves_data.get('$leaves', []):
+                if leaf not in type_reg:
+                    type_reg[leaf] = {'in_tree': True}
+                elif isinstance(type_reg[leaf], dict) and not type_reg[leaf].get('in_tree'):
+                    type_reg[leaf] = {**type_reg[leaf], 'in_tree': True}
+    except Exception:
+        pass    # 兜底失败不阻塞渲染
+
+    # build thead 一次 (24 列结构跨 procedures 共享)
+    thead = render_thead()
+
+    # 逐 procedure 渲染: 每个 procedure 出一段 (declarations 折叠 + 工序表)
+    procedure_blocks: list[str] = []
+    for proc in case_data.get('procedures', []):
+        proc_decl_html = render_declarations(case_data, procedure=proc)
+
+        consumers = build_output_consumers(proc)   # {输出编号: [消费步骤]} → 自动补"去处"
+        body_rows = []
+        for step in proc.get('steps', []):
+            body_rows.append(render_step_row(step, step['id'], type_reg, consumers))
+        rr = proc.get('return_row') or {}
+        if rr:
+            body_rows.append(f'<tr class="return-row"><td class="idx">{rr.get("arrow", "↩")}</td><td colspan="13">{rr.get("text", "")}</td></tr>')
+        proc_tbody = '<tbody>\n      ' + '\n      '.join(body_rows) + '\n    </tbody>'
+
+        proc_id_attr = he(proc.get('id', ''))
+        procedure_blocks.append(f'''<section class="procedure" id="proc-{proc_id_attr}">
+    {proc_decl_html}
+    <div class="table-wrap">
+      <table class="proc">
+        {thead}
+        {proc_tbody}
+      </table>
+    </div>
+  </section>''')
+
+    procedures_html = '\n  '.join(procedure_blocks)
+
+    # taxonomy for JS
+    taxonomy_js = {
+        '作用': EFFECT_TREE,
+        '动作': ACTION_TREE,
+        '类型': TYPE_TREE,
+        '实质': EXTERNAL_TAXONOMIES['实质'],
+        '形式': EXTERNAL_TAXONOMIES['形式'],
+    }
+
+    js = (JS_TEMPLATE
+          .replace('__TYPE_REGISTRY__', json.dumps(type_reg, ensure_ascii=False, indent=2))
+          .replace('__TAXONOMY__', json.dumps(taxonomy_js, ensure_ascii=False, indent=2)))
+
+    page_title = case_data.get('page_title', 'Procedure DSL 可视化')
+    source_html = render_source(case_data)
+    legend_html = render_legend()
+
+    return f'''<!doctype html>
+<html lang="zh">
+<head>
+  <meta charset="utf-8">
+  <title>{he(page_title)}</title>
+  <style>{CSS}</style>
+</head>
+<body>
+  <div class="scroll-area">
+    <header class="page-header">
+      <h1>{he(page_title)}</h1>
+    </header>
+    {source_html}
+    {legend_html}
+    {procedures_html}
+  </div>
+  <div class="drawer-overlay" id="drawer-overlay"></div>
+  <aside class="drawer" id="drawer" aria-hidden="true">
+    <header>
+      <h2>详情</h2>
+      <button class="close" aria-label="关闭">×</button>
+    </header>
+    <div class="content"></div>
+  </aside>
+  <script>{js}</script>
+</body>
+</html>
+'''

+ 194 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/script.js

@@ -0,0 +1,194 @@
+const typeRegistry = __TYPE_REGISTRY__;
+const taxonomy = __TAXONOMY__;
+
+function isInTypeTree(name) {
+  const t = typeRegistry[name];
+  if (!t) return false;
+  if (t.in_tree) return true;
+  if (t.extends) return isInTypeTree(t.extends);
+  return false;
+}
+
+const drawer = document.getElementById('drawer');
+const overlay = document.getElementById('drawer-overlay');
+const drawerTitle = drawer.querySelector('h2');
+const drawerContent = drawer.querySelector('.content');
+
+function openDrawer(title, htmlContent) {
+  drawerTitle.textContent = title;
+  drawerContent.innerHTML = htmlContent;
+  drawer.classList.add('open');
+  overlay.classList.add('open');
+}
+function closeDrawer() {
+  drawer.classList.remove('open');
+  overlay.classList.remove('open');
+}
+drawer.querySelector('.close').addEventListener('click', closeDrawer);
+overlay.addEventListener('click', closeDrawer);
+
+function escapeHtml(s) {
+  return String(s).replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]));
+}
+function renderTree(tree, highlight, depth = 0) {
+  if (typeof tree === 'string') {
+    return `<div class="node" style="margin-left:${depth*16}px; color:#6b7280;">${escapeHtml(tree)}</div>`;
+  }
+  let out = '';
+  for (const k of Object.keys(tree)) {
+    const v = tree[k];
+    const isHL = (highlight && (k === highlight || k.endsWith('/'+highlight)));
+    const cls = isHL ? 'node highlight' : 'node';
+    out += `<div class="${cls}" style="margin-left:${depth*16}px;">${escapeHtml(k)}${(typeof v === 'string') ? ' — ' + escapeHtml(v) : ''}</div>`;
+    if (typeof v === 'object') {
+      out += renderTree(v, highlight, depth + 1);
+    }
+  }
+  return out;
+}
+
+// type chip click
+document.querySelectorAll('.chip[data-type]').forEach(c => {
+  c.addEventListener('click', () => {
+    const tp = c.getAttribute('data-type');
+    const t = typeRegistry[tp] || {};
+    let parts = [];
+    parts.push(`<div class="row"><b>类型名</b>: ${escapeHtml(tp)}</div>`);
+    if (t.extends) parts.push(`<div class="row"><b>extends</b>: ${escapeHtml(t.extends)}</div>`);
+    if (t.desc) parts.push(`<div class="row"><b>描述</b>: ${escapeHtml(t.desc)}</div>`);
+    parts.push(`<h3>字典树 (§A.3 类型词表)</h3>`);
+    if (t && t.in_tree) {
+      parts.push(`<div class="row" style="color:#047857;">✓ <b>${escapeHtml(tp)}</b> 是字典树叶子</div>`);
+    } else if (t && t.extends && isInTypeTree(t.extends)) {
+      parts.push(`<div class="row" style="color:#0369a1;">✓ <b>${escapeHtml(tp)}</b> 是自定义拓展节点 (继承自: <b>${escapeHtml(t.extends)}</b>)</div>`);
+    } else {
+      parts.push(`<div class="warning">${escapeHtml(tp)} 不在字典树叶子, 也无合法的 extends 桥接.</div>`);
+    }
+    parts.push(`<div class="tree">${renderTree(taxonomy['类型'].tree, tp)}</div>`);
+    openDrawer(`类型 · ${tp}`, parts.join(''));
+  });
+});
+
+// 作用 / 动作 / 特性 / 实质 / 形式 click
+document.querySelectorAll('[data-prefix]').forEach(el => {
+  el.addEventListener('click', (e) => {
+    e.stopPropagation();
+    const prefix = el.getAttribute('data-prefix');
+    const value = el.getAttribute('data-value');
+    const tx = taxonomy[prefix];
+    if (!tx) {
+      openDrawer(`${prefix}`, `<div class="warning">无字典树定义</div>`);
+      return;
+    }
+    let body = '';
+    body += `<div class="row"><b>${escapeHtml(prefix)}</b>: ${escapeHtml(tx.title || '')}</div>`;
+    if (tx.desc) body += `<div class="row" style="color:#6b7280;">${escapeHtml(tx.desc)}</div>`;
+    if (tx.source === 'external') {
+      body += `<div class="warning"><b>${escapeHtml(prefix)}</b> 维度词表过大, 维护在外部 JSON: <code>${escapeHtml(tx.file || '')}</code>. 查询: <code>spec/tools/taxonomy-lookup.py --dim ${escapeHtml(prefix)} --subtree &lt;path&gt;</code>.</div>`;
+      body += `<h3>当前值</h3><div class="row" style="font-family:ui-monospace,monospace;">${escapeHtml(value)}</div>`;
+    } else if (tx.tree) {
+      body += `<h3>字典树 (当前值: <span class="highlight">${escapeHtml(value)}</span> 已高亮)</h3>`;
+      body += `<div class="tree">${renderTree(tx.tree, value)}</div>`;
+    }
+    openDrawer(`${prefix} · ${value}`, body);
+  });
+});
+
+// variable hover
+document.querySelectorAll('.name[data-var]').forEach(n => {
+  n.addEventListener('mouseenter', () => {
+    const v = n.getAttribute('data-var');
+    document.querySelectorAll(`.name[data-var="${v}"]`).forEach(x => x.classList.add('var-highlight'));
+  });
+  n.addEventListener('mouseleave', () => {
+    document.querySelectorAll('.name.var-highlight').forEach(x => x.classList.remove('var-highlight'));
+  });
+});
+
+// block toggle (含 nested step-sub: 用 data-group 选)
+document.querySelectorAll('tr.block-header').forEach(b => {
+  b.addEventListener('click', (e) => {
+    if (e.target.closest('.chip, [data-prefix], .name')) return;
+    const group = b.getAttribute('data-step');
+    const arrow = b.querySelector('.arrow');
+    const nested = document.querySelectorAll(`tr[data-group="${group}"]`);
+    const collapsed = arrow.textContent.trim() === '▶';
+    nested.forEach(n => n.style.display = collapsed ? '' : 'none');
+    arrow.textContent = collapsed ? '▼' : '▶';
+  });
+});
+
+// ───────── column visibility (legend toggle) ─────────
+const COL_GROUPS = {
+  'demand': { headerSel: 'th.col-group-demand', cols: ['idx','intent','effect','substance','form'] },
+  'input':  { headerSel: 'th.col-group-input',  cols: ['in-type','in-value','in-anchor'] },
+  'impl':   { headerSel: 'th.col-group-impl',   cols: ['via','action','directive'] },
+  'output': { headerSel: 'th.col-group-output', cols: ['out-type','out-value','out-anchor'] },
+};
+
+function setColVisible(col, visible) {
+  document.querySelectorAll(`th.col-${col}, td.${col}`).forEach(el => {
+    el.classList.toggle('col-hidden', !visible);
+  });
+  document.querySelectorAll(`.col-toggle[data-col="${col}"]`).forEach(b => {
+    b.classList.toggle('off', !visible);
+  });
+  recomputeGroupColspans();
+  if (typeof updateGroupHeadState === 'function') updateGroupHeadState();
+}
+
+function recomputeGroupColspans() {
+  for (const [, g] of Object.entries(COL_GROUPS)) {
+    const visibleCount = g.cols.filter(c => {
+      const th = document.querySelector(`th.col-${c}`);
+      return th && !th.classList.contains('col-hidden');
+    }).length;
+    const groupTh = document.querySelector(g.headerSel);
+    if (!groupTh) continue;
+    if (visibleCount === 0) {
+      groupTh.classList.add('col-hidden');
+    } else {
+      groupTh.classList.remove('col-hidden');
+      groupTh.setAttribute('colspan', String(visibleCount));
+    }
+  }
+}
+
+document.querySelectorAll('.col-toggle').forEach(btn => {
+  btn.addEventListener('click', () => {
+    const col = btn.getAttribute('data-col');
+    const isOff = btn.classList.contains('off');
+    setColVisible(col, isOff);
+  });
+});
+
+document.querySelectorAll('.legend .group .gh').forEach(gh => {
+  gh.addEventListener('click', () => {
+    const grpEl = gh.closest('.group');
+    const toggles = Array.from(grpEl.querySelectorAll('.col-toggle'));
+    const anyVisible = toggles.some(t => !t.classList.contains('off'));
+    toggles.forEach(t => setColVisible(t.getAttribute('data-col'), !anyVisible));
+    updateGroupHeadState();
+  });
+});
+
+function updateGroupHeadState() {
+  document.querySelectorAll('.legend .group').forEach(grpEl => {
+    const toggles = Array.from(grpEl.querySelectorAll('.col-toggle'));
+    const allOff = toggles.every(t => t.classList.contains('off'));
+    grpEl.querySelector('.gh').classList.toggle('all-off', allOff);
+  });
+}
+
+recomputeGroupColspans();
+updateGroupHeadState();
+
+// 推断补全 toggle (legend 上的"高亮推断")
+const infBtn = document.getElementById('inferred-toggle');
+if (infBtn) {
+  infBtn.addEventListener('click', () => {
+    document.body.classList.toggle('show-inferred');
+    infBtn.classList.toggle('on');
+  });
+}
+

+ 308 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/styles.css

@@ -0,0 +1,308 @@
+* { box-sizing: border-box; }
+html, body { margin: 0; padding: 0; font-family: -apple-system, "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif; font-size: 13px; color: #111827; background: #f5f5f7; }
+/* case 页布局: body 固定 viewport 高 + overflow hidden, 唯一的滚动容器是 .scroll-area; 页头 / declarations / source / legend / 表格全装在里面.
+   滚动时它们一起向上滚走, 只有 thead 因 position: sticky 留在顶 — 这是用户要求的"只冻结表头两行". */
+body { height: 100vh; overflow: hidden; }
+header.page-header { padding: 14px 20px 8px; background: #fff; border-bottom: 1px solid #e5e7eb; }
+header.page-header h1 { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
+header.page-header .meta { color: #6b7280; font-size: 12px; line-height: 1.5; }
+
+/* 工序头部 + declare 块 */
+details.declarations { margin: 12px 20px 0; background: #fff; border: 1px solid #e2e8f0; border-radius: 6px; }
+details.declarations[open] summary { border-bottom: 1px solid #e2e8f0; }
+details.declarations summary { padding: 10px 14px; cursor: pointer; font-size: 13px; line-height: 1.65; list-style: none; }
+details.declarations summary::-webkit-details-marker { display: none; }
+details.declarations summary::before { content: '▼ '; color: #94a3b8; font-size: 10px; margin-right: 4px; }
+details.declarations:not([open]) summary::before { content: '▶ '; }
+details.declarations .proc-name { color: #1f2937; font-size: 14px; }
+details.declarations .decl-purpose { color: #475569; margin-left: 12px; font-size: 12px; }
+details.declarations .decl-meta { color: #6b7280; font-size: 11.5px; margin-left: 16px; }
+details.declarations .tag-mini { display: inline-block; padding: 1px 7px; font-size: 11px; background: #fef3c7; border-radius: 3px; color: #92400e; margin-left: 8px; }
+.decl-body { padding: 12px 18px 14px; display: flex; flex-wrap: wrap; gap: 14px 32px; }
+.decl-section { min-width: 260px; flex: 1 1 280px; }
+.decl-label { color: #475569; font-size: 11.5px; font-weight: 600; margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px dashed #e2e8f0; }
+.decl-row { padding: 3px 0; font-size: 12.5px; line-height: 1.65; }
+.decl-row .name { font-weight: 500; color: #1f2937; margin-left: 4px; }
+.decl-row .decl-default { color: #6b7280; font-size: 11.5px; margin-left: 6px; }
+.decl-row .decl-desc { color: #6b7280; font-size: 11.5px; margin-left: 6px; }
+
+/* 原文 */
+details.source-block { margin: 8px 20px 12px; background: #fff; border: 1px solid #e2e8f0; border-radius: 6px; }
+details.source-block summary { padding: 8px 14px; cursor: pointer; font-size: 12px; color: #475569; list-style: none; }
+details.source-block summary::-webkit-details-marker { display: none; }
+details.source-block summary::before { content: '▶ '; color: #94a3b8; font-size: 10px; margin-right: 4px; }
+details.source-block[open] summary::before { content: '▼ '; }
+.source-body { padding: 6px 18px 12px; font-size: 12.5px; line-height: 1.65; }
+.source-body a { color: #2563eb; word-break: break-all; }
+.source-body .source-meta { color: #94a3b8; font-size: 11px; margin-top: 4px; }
+.source-body .source-excerpt { color: #1f2937; margin: 8px 0; padding: 8px 10px; background: #f8fafc; border-left: 3px solid #94a3b8; font-size: 12px; }
+.source-body hr.src-divider { border: 0; border-top: 1px dashed #cbd5e1; margin: 10px 0; }
+.source-body .src-p { margin: 6px 0; color: #1f2937; }
+.source-body .src-img-wrap, .source-body .src-cover { text-align: center; margin: 8px 0; }
+.source-body .src-img { max-width: 100%; max-height: 480px; border-radius: 4px; border: 1px solid #e2e8f0; }
+.source-body .src-video { margin: 8px 0; }
+.source-body .src-video a { display: inline-block; padding: 4px 10px; background: #fef3c7; color: #78350f; text-decoration: none; border-radius: 3px; font-size: 11.5px; }
+.source-body .source-full { max-height: 720px; overflow-y: auto; padding: 6px 12px; background: #fff; border: 1px solid #e2e8f0; border-radius: 4px; }
+
+/* Legend */
+.legend { padding: 10px 20px; background: #fff; border-bottom: 1px solid #e5e7eb; font-size: 11.5px; color: #6b7280; display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
+.legend .group { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
+.legend .group .gh { display: inline-block; padding: 2px 8px; border-radius: 3px; color: #1f2937; font-weight: 600; cursor: pointer; user-select: none; }
+.legend .group .gh:hover { filter: brightness(0.92); }
+.legend .group .gh.all-off { opacity: 0.45; text-decoration: line-through; }
+.legend .group.gray  .gh { background: #e2e8f0; }
+.legend .group.yellow .gh { background: #fde68a; }
+.legend .group.green .gh { background: #bbf7d0; }
+.legend .group.blue  .gh { background: #bfdbfe; }
+.legend .col-toggle { display: inline-block; padding: 2px 7px; border: 1px solid #cbd5e1; border-radius: 3px; background: #fff; cursor: pointer; font-size: 11.5px; color: #334155; user-select: none; }
+.legend .col-toggle:hover { background: #f1f5f9; }
+.legend .col-toggle.off { color: #94a3b8; background: #f1f5f9; text-decoration: line-through; border-color: #e2e8f0; }
+.legend .inferred-toggle { display: inline-block; padding: 2px 8px; border: 1px solid #d97706; border-radius: 3px;
+                           background: #fffbeb; color: #92400e; cursor: pointer; font-size: 11.5px;
+                           font-weight: 600; user-select: none; margin-left: 8px; }
+.legend .inferred-toggle.on { background: #fef3c7; box-shadow: inset 0 0 0 1px #d97706; }
+.legend .legend-hint { color: #94a3b8; font-size: 11px; margin-left: auto; }
+
+/* 表格容器 */
+.table-wrap { background: #fff; }
+/* case 页 .scroll-area: 占满 body, 自身承担两轴滚动. 内部不嵌套 overflow 容器, 否则 sticky 锚点会被抢走.
+   (browser 页不会走这条 — 它在 .browser-main 内, 不直接挂 body 下) */
+body > .scroll-area { height: 100%; overflow: auto; background: #f5f5f7; }
+table.proc { width: max-content; min-width: 100%; border-collapse: collapse; background: #fff; table-layout: auto; font-size: 12px; }
+table.proc th, table.proc td { border: 1px solid #e5e7eb; padding: 6px 8px; vertical-align: top; line-height: 1.5; }
+table.proc thead th { font-weight: 600; text-align: center; font-size: 12.5px; padding: 8px 6px; }
+table.proc tbody td { font-size: 12px; }
+
+/* 列宽 (需求 3 列固定 width, 其他 min-width) */
+table.proc th.col-idx,    table.proc td.idx    { width: 38px;  min-width: 38px;  max-width: 38px;  text-align: center; }
+table.proc th.col-intent, table.proc td.intent { width: 240px; min-width: 240px; max-width: 240px; }
+table.proc th.col-effect, table.proc td.effect { width: 80px;  min-width: 80px;  max-width: 80px; }
+table.proc th.col-via       { min-width: 110px; }
+table.proc th.col-action    { min-width: 130px; }
+table.proc th.col-directive { min-width: 200px; }
+table.proc th.col-config    { min-width: 150px; }
+table.proc th.col-decorator { min-width: 130px; }
+table.proc th.col-memo      { min-width: 220px; }
+table.proc th.col-control   { min-width: 80px; }
+table.proc th.col-feature   { min-width: 80px; }
+
+/* 值列整段 <...> — 表示该值是对内容的描述, 不是内容本身. 整段 inline italic gray bg. */
+.value-desc { display: inline; padding: 1px 4px; border-radius: 3px;
+              background: rgba(241, 245, 249, 0.7); color: #475569; font-style: italic; }
+
+/* 值列不允许截断 */
+table.proc td.in-value, table.proc td.out-value {
+  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
+  max-width: 320px;
+}
+table.proc td.directive, table.proc td.config,
+table.proc td.decorator, table.proc td.memo {
+  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
+  max-width: 280px;
+}
+/* 实质/形式 列 (step 级) — 内容是短路径, 收窄列宽强制换行 (避免空旷低信息密度) */
+table.proc th.col-substance, table.proc td.substance,
+table.proc th.col-form, table.proc td.form { width: 90px; min-width: 90px; max-width: 90px;
+  word-break: break-all; overflow-wrap: anywhere; }
+table.proc th.col-in-type, table.proc th.col-out-type           { min-width: 90px;  }
+table.proc th.col-in-name, table.proc th.col-out-name           { min-width: 110px; }
+table.proc th.col-in-value, table.proc th.col-out-value         { min-width: 180px; }
+table.proc th.col-in-anchor, table.proc th.col-out-anchor       { min-width: 110px; }
+
+/* 冻结 需求 组 (idx + 目的 + 作用) — left 累计 = 0 / 38 / 278 */
+table.proc th.col-idx,    table.proc td.idx    { position: sticky; left: 0;     z-index: 2; }
+table.proc th.col-intent, table.proc td.intent { position: sticky; left: 38px;  z-index: 2; }
+table.proc th.col-effect, table.proc td.effect { position: sticky; left: 278px; z-index: 2; }
+table.proc thead th.col-group-demand          { position: sticky; left: 0;     z-index: 3; }
+table.proc thead th.col-idx, table.proc thead th.col-intent, table.proc thead th.col-effect { z-index: 3; }
+table.proc td.effect, table.proc thead th.col-effect, table.proc thead th.col-group-demand {
+  box-shadow: 6px 0 8px -4px rgba(0,0,0,0.18);
+}
+
+/* 冻结 表头 — 滚动时组名/列名行 stick to top */
+table.proc thead th { position: sticky; top: 0; z-index: 3; }
+table.proc thead tr:nth-child(2) th { top: 33px; }
+/* 4 个 corner cell (sticky-left + sticky-top 同时生效) z-index 加高, 避免被 tbody sticky-left 列覆盖 */
+table.proc thead th.col-group-demand,
+table.proc thead th.col-idx,
+table.proc thead th.col-intent,
+table.proc thead th.col-effect { z-index: 5; }
+
+/* 颜色分组背景 */
+table.proc td.idx, table.proc td.intent, table.proc td.effect, table.proc td.substance, table.proc td.form { background: #f8fafc; }
+table.proc thead th.col-group-demand { background: #1e293b; color: #fff; }
+table.proc thead tr:nth-child(2) th.col-idx,
+table.proc thead tr:nth-child(2) th.col-intent,
+table.proc thead tr:nth-child(2) th.col-effect,
+table.proc thead tr:nth-child(2) th.col-substance,
+table.proc thead tr:nth-child(2) th.col-form { background: #475569; color: #fff; }
+table.proc td.in-substance, table.proc td.in-form, table.proc td.in-type, table.proc td.in-name, table.proc td.in-value, table.proc td.in-anchor { background: #fefce8; }
+table.proc thead th.col-group-input { background: #b45309; color: #fff; }
+table.proc thead tr:nth-child(2) th.col-in-substance,
+table.proc thead tr:nth-child(2) th.col-in-form,
+table.proc thead tr:nth-child(2) th.col-in-type,
+table.proc thead tr:nth-child(2) th.col-in-name,
+table.proc thead tr:nth-child(2) th.col-in-value,
+table.proc thead tr:nth-child(2) th.col-in-anchor { background: #d97706; color: #fff; }
+table.proc td.via, table.proc td.action, table.proc td.directive, table.proc td.config,
+table.proc td.decorator, table.proc td.memo, table.proc td.control, table.proc td.feature { background: #f0fdf4; }
+table.proc thead th.col-group-impl { background: #065f46; color: #fff; }
+table.proc thead tr:nth-child(2) th.col-via,
+table.proc thead tr:nth-child(2) th.col-action,
+table.proc thead tr:nth-child(2) th.col-directive,
+table.proc thead tr:nth-child(2) th.col-config,
+table.proc thead tr:nth-child(2) th.col-decorator,
+table.proc thead tr:nth-child(2) th.col-memo,
+table.proc thead tr:nth-child(2) th.col-control,
+table.proc thead tr:nth-child(2) th.col-feature { background: #047857; color: #fff; }
+table.proc td.out-substance, table.proc td.out-form, table.proc td.out-type, table.proc td.out-name, table.proc td.out-value, table.proc td.out-anchor { background: #eff6ff; }
+table.proc thead th.col-group-output { background: #1e40af; color: #fff; }
+table.proc thead tr:nth-child(2) th.col-out-substance,
+table.proc thead tr:nth-child(2) th.col-out-form,
+table.proc thead tr:nth-child(2) th.col-out-type,
+table.proc thead tr:nth-child(2) th.col-out-name,
+table.proc thead tr:nth-child(2) th.col-out-value,
+table.proc thead tr:nth-child(2) th.col-out-anchor { background: #2563eb; color: #fff; }
+
+/* 组间分隔粗线 (需求|输入 在 form 后; 输入|实现 在 来源后; 实现|输出 在 指令后) */
+table.proc th.col-form, table.proc td.form,
+table.proc th.col-in-anchor, table.proc td.in-anchor,
+table.proc th.col-directive, table.proc td.directive { border-right: 3px solid #94a3b8; }
+
+/* 行边框 / 块头 / nested */
+table.proc tr.step-main > td { border-top: 1.5px solid #94a3b8; }
+table.proc tr.step-sub > td { border-top: 1px dashed #cbd5e1; }
+table.proc tr.block-header { font-weight: 600; }
+table.proc tr.block-header > td.intent { background: #e2e8f0; }
+table.proc tr.step-nested > td.idx { color: #6b7280; }
+
+/* :target 高亮 — 从其他页跳转过来时让对应 step 行闪烁定位 */
+table.proc tr:target > td {
+  animation: rowTargetFlash 1.6s ease-out;
+  box-shadow: inset 4px 0 0 #6d28d9;
+}
+@keyframes rowTargetFlash {
+  0%   { background-color: #fef3c7 !important; }
+  100% { background-color: inherit; }
+}
+
+/* output 的 id 小标签 (贴在值前, 供 anchor 1:1 引用对照) */
+.io-id {
+  display: inline-block; margin-right: 4px; padding: 0 4px;
+  font-size: 10px; font-family: ui-monospace, "SF Mono", monospace;
+  color: #475569; background: #e2e8f0; border-radius: 3px; vertical-align: top;
+}
+
+/* 返回行 */
+tr.return-row > td { background: #fde68a !important; font-weight: 600; padding: 8px; }
+
+/* chip — 中性灰底 (供 declaration / drawer / 返回行); 表格内 type chip 由下方列色覆盖 */
+.chip { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 11.5px; color: #1f2937; background: #d1d5db; cursor: pointer; user-select: none; }
+.chip:hover { filter: brightness(0.95); box-shadow: 0 0 0 1px #1e293b; }
+
+/* 表格 in-type / out-type 列内 chip 统一列色 (黄/蓝区分输入输出) */
+table.proc td.in-type .chip  { background: #fde68a !important; color: #78350f; }
+table.proc td.out-type .chip { background: #bfdbfe !important; color: #1e3a8a; }
+
+/* keyword / name / flow */
+.kw { color: #6d28d9; font-weight: 600; }
+.name { color: #0f172a; }
+.name:hover, .name.var-highlight { background: #fef3c7; cursor: pointer; }
+.flow { color: #6b7280; font-size: 11.5px; font-style: italic; }
+/* 去处自动推导自下游来源 (模型未填 →): 虚下划线 + 更浅, 区别于模型手填 */
+.flow.derived { color: #9ca3af; border-bottom: 1px dashed #cbd5e1; cursor: help; }
+
+/* intent tokens */
+.intent-text { color: #1f2937; line-height: 1.55; }
+.intent-tok { display: inline-block; padding: 1px 5px; border-radius: 3px; margin: 0 1px; font-size: 11.5px; }
+/* intent token: 底色对应其引用的列. 输入列黄, 输出列蓝, 实现列绿, 需求列灰. */
+/* 需求 (灰) */
+.intent-tok.ik-effect    { background: #cbd5e1; color: #1f2937; }
+/* 实现 (绿系) — 3 个不同饱和度区分 */
+.intent-tok.ik-via       { background: #d1fae5; color: #064e3b; font-family: ui-monospace, "SF Mono", monospace; font-size: 11px; }
+.intent-tok.ik-act       { background: #86efac; color: #14532d; }
+.intent-tok.ik-control   { background: #99f6e4; color: #134e4a; }
+/* feature 禁止 intent 引用; 用 ik-other 警告色 */
+.intent-tok.ik-other     { background: #fee2e2; color: #991b1b; text-decoration: line-through; }
+/* 输入·类型 (黄圆胶囊) / 输出·类型 (蓝圆胶囊) */
+.intent-tok.ik-in-type   { background: #fde68a; color: #78350f; border-radius: 10px; padding: 1px 8px; font-weight: 500; }
+.intent-tok.ik-out-type  { background: #bfdbfe; color: #1e3a8a; border-radius: 10px; padding: 1px 8px; font-weight: 500; }
+/* 输入·实质 / 输出·实质 (矩形 tag) */
+.intent-tok.ik-in-sub    { background: #fef3c7; color: #92400e; }
+.intent-tok.ik-out-sub   { background: #dbeafe; color: #1e40af; }
+/* 输入·形式 / 输出·形式 (矩形 tag 斜体) */
+.intent-tok.ik-in-form   { background: #fef3c7; color: #92400e; font-style: italic; }
+.intent-tok.ik-out-form  { background: #dbeafe; color: #1e40af; font-style: italic; }
+
+/* substance/form 路径文本 */
+td.substance > span, td.form > span {
+  display: inline-block; padding: 1px 4px; border-radius: 2px; font-size: 11px;
+  color: #1f2937; background: rgba(255,255,255,0.6); border: 1px solid rgba(0,0,0,0.06);
+  word-break: break-all; line-height: 1.4; cursor: pointer;
+}
+td.effect > span, td.action > span {
+  display: inline-block; padding: 1px 5px; border-radius: 2px; font-size: 11.5px;
+  color: #0f172a; background: rgba(255,255,255,0.7); cursor: pointer; border: 1px solid rgba(0,0,0,0.06);
+}
+
+/* 指令/配置/运行/备注 列 — 多条目 vertical 堆叠 */
+td.directive .instr-item, td.config .instr-item, td.decorator .instr-item, td.memo .instr-item {
+  display: block; font-size: 11.5px; color: #1f2937; margin: 2px 0; line-height: 1.5;
+}
+
+/* row-focus 加深底色 */
+td.row-focus { font-weight: 600; color: #0f172a; }
+td.idx.row-focus, td.intent.row-focus, td.effect.row-focus, td.substance.row-focus, td.form.row-focus { background: #e2e8f0 !important; }
+td.in-substance.row-focus, td.in-form.row-focus, td.in-type.row-focus, td.in-name.row-focus, td.in-value.row-focus, td.in-anchor.row-focus { background: #fde68a !important; }
+td.via.row-focus, td.action.row-focus, td.directive.row-focus, td.config.row-focus,
+td.decorator.row-focus, td.memo.row-focus, td.control.row-focus, td.feature.row-focus { background: #bbf7d0 !important; }
+td.out-substance.row-focus, td.out-form.row-focus, td.out-type.row-focus, td.out-name.row-focus, td.out-value.row-focus, td.out-anchor.row-focus { background: #bfdbfe !important; }
+
+/* inferred 角标 */
+sup.inferred { color: #b45309; font-size: 10px; font-weight: bold; padding: 0 2px; cursor: help; }
+
+/* 任意 cell 推断补全标记 — 「推」角标 + hover 显示 reason (不再加虚线下划线, 由角标承担识别) */
+td.is-inferred {
+  cursor: help;
+}
+td.is-inferred::after {
+  content: '推';
+  display: inline-block;
+  font-size: 9px;
+  color: #92400e;
+  background: rgba(254, 243, 199, 0.9);
+  padding: 0 3px;
+  border-radius: 2px;
+  margin-left: 4px;
+  vertical-align: top;
+  font-weight: 600;
+  border: 1px solid #fbbf24;
+}
+/* 低置信留空变体: AI 想过但拿不准, 故意留空; 角标变 推? 与高置信 推 区分 (spec §推断补全标记 C) */
+td.is-inferred.is-low-confidence::after { content: '推?'; }
+/* 高亮模式: legend 点击"高亮推断" 时, body 加 show-inferred 类, 所有推断 cell 加重底色 */
+body.show-inferred td.is-inferred {
+  background: #fef3c7 !important;
+  box-shadow: inset 0 0 0 1px #d97706;
+}
+
+/* 列隐藏 */
+.col-hidden { display: none !important; }
+
+/* drawer */
+.drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.35); display: none; z-index: 100; }
+.drawer-overlay.open { display: block; }
+.drawer { position: fixed; right: 0; top: 0; bottom: 0; width: 520px; max-width: 90vw; background: #fff; box-shadow: -4px 0 16px rgba(0,0,0,0.15); z-index: 101; overflow-y: auto; transform: translateX(100%); transition: transform 0.2s ease-out; }
+.drawer.open { transform: translateX(0); }
+.drawer header { padding: 14px 18px; background: #1e293b; color: #fff; border-bottom: 0; position: sticky; top: 0; z-index: 2; }
+.drawer header h2 { margin: 0; font-size: 14px; }
+.drawer .close { position: absolute; right: 12px; top: 12px; background: transparent; color: #fff; border: 0; cursor: pointer; font-size: 18px; }
+.drawer .content { padding: 14px 18px; font-size: 12.5px; line-height: 1.6; color: #1f2937; }
+.drawer .content h3 { margin: 14px 0 6px; font-size: 12.5px; color: #047857; }
+.drawer .content pre { background: #f3f4f6; padding: 8px; border-radius: 3px; font-size: 11.5px; overflow-x: auto; line-height: 1.5; white-space: pre-wrap; }
+.drawer .content .row { margin: 4px 0; }
+.drawer .content .row b { color: #374151; }
+.drawer .tree { font-family: ui-monospace, "SF Mono", monospace; font-size: 11.5px; }
+.drawer .tree .node { padding: 1px 0; }
+.drawer .tree .highlight { background: #fde68a; padding: 1px 4px; border-radius: 2px; font-weight: 600; }
+.drawer .warning { background: #fef3c7; border-left: 3px solid #f59e0b; padding: 8px 10px; margin: 8px 0; font-size: 12px; }

+ 278 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/verify-io.py

@@ -0,0 +1,278 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""verify-io.py — Phase 1 收口的专用「IO 校验」步骤 (填完 value 后、进 Phase 2 前必跑)。
+
+专门校验四件事, 报问题就回去补 (修完重跑直到通过):
+  1. **文本 IO 逐字**: 每个**文本类** input/output 的 value 是不是在原文(正文+配图 OCR)里有
+     连续对应 —— 媒体类(图/视频/音频)IO **不要求**对应, 直接跳过。
+  2. **提示词提取**: 每个**工具生成步**(via 是具体生成工具)是不是把原文给这步的整段 prompt
+     提取进了 directive 或某个文本输入 —— 弱模型常把生成步建成「媒体输入→媒体输出」, 把原文
+     那段 prompt(最该提取的内容, 如「半剖面视图…」「视觉层:…技术层:…」)整段漏掉。
+  3. **declarations 收口**: 每个工序的 declarations.returns 补了没(必), inputs/resources 提醒。
+  4. **anchor 闭合**: 透传输入(有 ← anchor)是不是真把 value/type 回填了 —— 弱模型常**漏跑
+     `wf-patch --resolve-passthrough`** 或把 anchor 写成 JSON 路径(← p1.s1.outputs[0])而非
+     输出编号(← s1o1), 两种都会让透传 value 静默留空、一路漏到成品。
+
+退出码: 0 通过 / 1 有阻塞项要修 / 2 CLI/文件错。
+
+用法:
+    python spec/tools/verify-io.py --workflow outputs/case-{N}/workflow.json \
+        --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt
+"""
+import argparse
+import importlib.util
+import re
+import sys
+from pathlib import Path
+
+import json
+
+# 媒体类 value 应整体用 <…> 包成 <具体描述> (强模型参考一致): <极简写实背景图:深钢蓝-松绿-冷白渐层…>
+_MEDIA_BRACKET_OK = re.compile(r'^\s*<.+>\s*$', re.S)
+
+DSL_ROOT = Path(__file__).resolve().parent.parent.parent
+
+for _s in (sys.stdout, sys.stderr):
+    if hasattr(_s, 'reconfigure'):
+        try:
+            _s.reconfigure(encoding='utf-8', errors='replace')
+        except Exception:
+            pass
+
+
+def _load_lint():
+    """复用 lint-case.py 的 _norm / check_value_verbatim / _type_modality (文件名带连字符, 按路径载)."""
+    p = Path(__file__).resolve().parent / 'lint-case.py'
+    spec = importlib.util.spec_from_file_location('_lint_case_mod', p)
+    mod = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(mod)
+    return mod
+
+
+# 装配/排版/人工类工具不要求 prompt (它们不是"按提示词生成"). 用较长的判别词, 避免 'na' 误伤 nanobanana
+_NON_PROMPT_VIA = ('human', 'ppt', 'adobe', 'illustrat', 'inkscape', 'photoshop',
+                   '剪辑', '剪映', '拼接', '排版', '拼版', '合成', '后期', '裁剪', '修图',
+                   '人工', 'excel', 'word')
+
+
+def _is_generation_via(via: str) -> bool:
+    v = (via or '').strip().lower()
+    if not v or v in ('-', 'n/a', 'na', '人工', '人'):
+        return False
+    return not any(k in v for k in _NON_PROMPT_VIA)
+
+
+# 原文 prompt 的**独特**分层/要素标记: 命中后原文紧跟这些 = 只提了一部分 (截断)。
+# 只放区分度高的 (视觉层/技术层/核心要素…); 不放 产品/人物/环境 这种常见词 (满篇都是, 会误判)。
+_LAYER_MARKERS = ('视觉层', '技术层', '氛围层', '核心要素', '视觉风格', '输出要求', '技术规格')
+
+
+def _has_prompt_type(t: str) -> bool:
+    return '提示词' in (t or '') or 'prompt' in (t or '').lower()
+
+
+def check_prompt_extraction(data: dict, lint, source_norm: str) -> list:
+    """提示词建模 + 完整性 (对齐强模型参考: 提示词是**数据**, 建成 type=提示词 的 IO value, directive 不装它):
+      1. 生成步必须有 type=提示词 的输入 (原文整段 prompt 当数据流入), 没有=漏建;
+      2. directive 里疑似装了提示词原文 = 放错地方, 该挪到 IO;
+      3. type=提示词 的 value 逐字但截断 (原文后面还有分层/要素) = 只提了一部分。
+    (value 是否逐字由「文本 IO 逐字」那条统一管, 这里只管"建对地方"和"提全".)
+    """
+    issues = []
+    for p in data.get('procedures', []):
+        for s in p.get('steps', []) or []:
+            if not isinstance(s, dict) or s.get('kind') == 'block':
+                continue
+            sid = f"{p.get('id')}.{s.get('id')}"
+            via = (s.get('via') or '').strip()
+            directive = (s.get('directive') or '').strip()
+
+            # 2. directive 不该装提示词 (长且像在引原文) —— 不限生成步
+            if directive:
+                dn = lint._norm(directive)
+                if len(dn) >= 12 and lint._longest_run(dn, source_norm) >= 12:
+                    issues.append(
+                        f"[{sid}] directive 里疑似装了提示词原文 —— directive 只放「给工具的指示」"
+                        f"(如严格反推/比例 2:3); **提示词原文是数据, 挪到 type=提示词 的输入/输出 value**。")
+
+            # 1. 生成步必须有 type=提示词 的输入
+            if _is_generation_via(via):
+                has_prompt_in = any(_has_prompt_type(io.get('type', '')) for io in (s.get('inputs') or []))
+                if not has_prompt_in:
+                    issues.append(
+                        f"[{sid}] via={via!r} 是生成步但**没有 type=提示词 的输入** —— 原文的整段 prompt 是数据, "
+                        f"建成 type=提示词 的输入(value 逐字完整; 通常由一个 human「写提示词」步 OUT=提示词、本步 anchor 引入), "
+                        f"别塞 directive、也别只写「XX需求」标签。原文确实没给详细 prompt 才可省。")
+
+            # 3. type=提示词 的 value 逐字但截断 (原文紧跟还有分层/要素)
+            for kind in ('inputs', 'outputs'):
+                for io in (s.get(kind) or []):
+                    if not _has_prompt_type(io.get('type', '')):
+                        continue
+                    v = (io.get('value') or '').strip()
+                    if not v or v.startswith('<'):
+                        continue
+                    vn = lint._norm(v)
+                    if len(vn) < 8:
+                        continue
+                    pos = source_norm.find(vn)
+                    if pos >= 0:
+                        tail = source_norm[pos + len(vn): pos + len(vn) + 40]
+                        cont = [m for m in _LAYER_MARKERS if m in tail and m not in vn]
+                        if cont:
+                            issues.append(
+                                f"[{sid}].{kind[:3]} type=提示词 的 value 可能**只提了一部分** —— 原文后面紧跟 "
+                                f"{cont[:3]} 等, @quote 止锚要延到这段 prompt 真正结束(把所有分层/要素提全)。")
+    return issues
+
+
+def check_media_brackets(data: dict, lint) -> list:
+    """媒体类(图/视频/音频)IO 的 value 必须整体用 <…> 包成 <具体描述>, 别写裸标签."""
+    issues = []
+    for p in data.get('procedures', []):
+        reg = p.get('type_registry') or {}
+        for s in p.get('steps', []) or []:
+            if not isinstance(s, dict) or s.get('kind') == 'block':
+                continue
+            for kind in ('inputs', 'outputs'):
+                for io in (s.get(kind) or []):
+                    if io.get('inferred'):
+                        continue
+                    if lint._type_modality(io.get('type', ''), reg) != 'media':
+                        continue
+                    v = (io.get('value') or '').strip()
+                    if not v:
+                        continue
+                    if not _MEDIA_BRACKET_OK.match(v):
+                        issues.append(
+                            f"[{p.get('id')}.{s.get('id')}.{kind[:3]}] type={io.get('type', '')!r}(媒体) "
+                            f"value={v[:24]!r} 没用 <…> 包 —— 媒体类 value 写成 <具体描述>"
+                            f"(如 <一张冲锋衣登山者暴雨场景图,水珠滚落,冷色调>)。")
+    return issues
+
+
+def check_declarations(data: dict) -> tuple:
+    """returns 空 = 必补; inputs 空 = 提醒. 返回 (block_list, warn_list)."""
+    block, warn = [], []
+    for p in data.get('procedures', []):
+        decl = p.get('declarations') or {}
+        rets = decl.get('returns')
+        if not rets or (isinstance(rets, dict) and not any(rets.values())):
+            block.append(f"[{p.get('id')}] declarations.returns 空 — 补这个工序最终返回什么(type)")
+        if not decl.get('inputs'):
+            warn.append(f"[{p.get('id')}] declarations.inputs 空 — 确认外部输入(没有可不填)")
+    return block, warn
+
+
+def main() -> None:
+    ap = argparse.ArgumentParser(prog='verify-io.py', description='Phase 1 收口 IO 校验')
+    ap.add_argument('--workflow', type=Path, required=True)
+    ap.add_argument('--source', type=Path, required=True, help='原文 input/case-N.json (逐字比对用)')
+    ap.add_argument('--ocr', type=Path, default=None, help='配图 OCR 文本 (可选, 并入比对语料)')
+    args = ap.parse_args()
+
+    if not args.workflow.exists():
+        print(f'verify-io: workflow 不存在 {args.workflow}', file=sys.stderr)
+        sys.exit(2)
+    try:
+        data = json.loads(args.workflow.read_text(encoding='utf-8'))
+    except json.JSONDecodeError as e:
+        print(f'verify-io: workflow 不是合法 JSON: {e}', file=sys.stderr)
+        sys.exit(2)
+
+    lint = _load_lint()
+    _raw, source_norm = lint._load_source_corpus(args.source, args.ocr)
+    if not source_norm:
+        print(f'verify-io: 读不到原文 {args.source} (逐字校验需要它)', file=sys.stderr)
+        sys.exit(2)
+
+    case_id = data.get('case_id', '?')
+    print(f'[verify-io] case-{case_id} ({args.workflow.name})')
+
+    # 1. 文本 IO 逐字 (媒体跳过)
+    io_hints = lint.check_value_verbatim(data, source_norm)
+    if io_hints:
+        print(f'  · 文本 IO 逐字: {len(io_hints)} 处未对上原文 (媒体类已跳过)')
+        for h in io_hints:
+            print(f'      ✗ {h}')
+        print('     → 此时可重读原文; 用 @quote|起锚|止锚 + wf-patch --resolve-quotes 拽完整原文; '
+              '原文确无则标 inferred:true+reason 或 value 写「原文未提供」。')
+    else:
+        print('  · 文本 IO 逐字: OK (文本类 value 都对上原文; 媒体类不要求)')
+
+    # 2. 提示词提取
+    prompt_issues = check_prompt_extraction(data, lint, source_norm)
+    if prompt_issues:
+        print(f'  · 提示词提取: {len(prompt_issues)} 个生成步没提取到提示词')
+        for h in prompt_issues:
+            print(f'      ✗ {h}')
+    else:
+        print('  · 提示词提取: OK (生成步都有提示词)')
+
+    # 3. 媒体 value 的 <…> 包裹
+    media_issues = check_media_brackets(data, lint)
+    if media_issues:
+        print(f'  · 媒体 value <…>: {len(media_issues)} 处没包 (媒体类 value 要写 <具体描述>)')
+        for h in media_issues:
+            print(f'      ✗ {h}')
+    else:
+        print('  · 媒体 value <…>: OK')
+
+    # 4. declarations 收口
+    decl_block, decl_warn = check_declarations(data)
+    if decl_block or decl_warn:
+        print(f'  · declarations 收口: {len(decl_block)} 必补 / {len(decl_warn)} 待确认')
+        for d in decl_block:
+            print(f'      ✗ {d}')
+        for d in decl_warn:
+            print(f'      ⚠ {d}')
+        print('     → 用 wf-patch 补 declarations.inputs/resources/returns, '
+              '例: `--set p1.declarations.returns.type=产品概念图`。')
+    else:
+        print('  · declarations 收口: OK')
+
+    # 5. anchor 闭合 (透传输入回填了没 + anchor 格式)
+    anchor_issues = lint.check_anchor_closure(data)
+    if anchor_issues:
+        print(f'  · anchor 闭合: {len(anchor_issues)} 处透传没回填 / anchor 写成 JSON 路径')
+        for h in anchor_issues:
+            print(f'      ✗ {h}')
+        print('     → 透传输入(有 ← anchor)的 value/type 要回填: 跑 '
+              '`wf-patch.py --resolve-passthrough` 顺编号自动抄上游; anchor 用编号 ← s1o1, 别用 JSON 路径。')
+    else:
+        print('  · anchor 闭合: OK')
+
+    # 6. 干骨架填满 (via 非空 + 输入有 value 或 anchor)
+    skel_issues = lint.check_skeleton_filled(data)
+    if skel_issues:
+        print(f'  · 干骨架填满: {len(skel_issues)} 处 Phase 1 骨架没填(via 空 / 输入既无 value 又无 anchor)')
+        for h in skel_issues:
+            print(f'      ✗ {h}')
+        print('     → Phase 2.0 要把骨架填满: 每步补 via, 每个输入要么填 value 要么连 anchor。')
+    else:
+        print('  · 干骨架填满: OK')
+
+    # 7. 数据流连通 (多步工序至少连了 anchor, 不是把内容全当字面量)
+    flow_issues = lint.check_dataflow_connected(data)
+    if flow_issues:
+        print(f'  · 数据流连通: {len(flow_issues)} 个多步工序一个 anchor 都没连')
+        for h in flow_issues:
+            print(f'      ✗ {h}')
+        print('     → 2.0.2 连数据流: 下游输入用 `← 上游输出编号` 引数据, 别把同一内容当字面量逐 IO 重抄。')
+    else:
+        print('  · 数据流连通: OK')
+
+    n_block = (len(io_hints) + len(prompt_issues) + len(media_issues) + len(decl_block)
+               + len(anchor_issues) + len(skel_issues) + len(flow_issues))
+    if n_block:
+        print(f'\n有 {n_block} 个阻塞项要修 (文本IO {len(io_hints)} + 提示词 {len(prompt_issues)} '
+              f'+ 媒体<…> {len(media_issues)} + returns {len(decl_block)} + anchor {len(anchor_issues)} '
+              f'+ 骨架 {len(skel_issues)} + 数据流 {len(flow_issues)})。修完**重跑本脚本**确认通过, 才进 Phase 2。',
+              file=sys.stderr)
+        sys.exit(1)
+    print('\n✓ IO 校验通过, 可进 Phase 2 归类标注。')
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+    main()

+ 982 - 0
examples/process_pipeline/script/search_eval/mode_procedure/procedure-dsl/spec/tools/wf-patch.py

@@ -0,0 +1,982 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+wf-patch.py — workflow.json 的安全批量字段设置器.
+
+为什么有这个工具:
+  workflow.json 由各 phase **直接 Write 骨架 + 逐字段填充** 演化. 但「给几十个 IO
+  逐个加 anchor」「给每个 step 填 effect/action/type」这类批量字段赋值, 用 Edit
+  一处一处改太碎, 手写整段 JSON 又极易踩转义 / 控制字符坑 (把文件搞坏).
+  wf-patch 卡在中间: **你只负责语义决策 (path=value), 工具负责安全落盘 + 合法性校验**.
+
+  - 安全 IO: 工具自己 json.load -> 改 -> json.dump(ensure_ascii=False), 你永远不手写 JSON.
+  - 写入即校验 (fail-fast): 每条赋值立刻对照字典树 / type_registry / anchor 格式校验,
+    **任何一条非法 -> 报具体哪条错, 整批不写** (不产出悄悄错的文件). lint 仍做全局兜底.
+
+用法:
+    # 单条 / 多条 --set (path=value, 只在第一个 '=' 处切, value 可含 '=' 和空格)
+    python spec/tools/wf-patch.py --workflow outputs/case-N/workflow.json \
+        --set 'p1.s1.inputs[0].anchor=← s0.主角图' \
+        --set 'p1.s2.effect=主体生成' \
+        --set 'p1.s2.action=生成/图像生成/文生图'
+
+    # 或一次性喂一份 patch 清单 (适合 1.3 加 anchor / 2A 填字段这种几十处批量)
+    python spec/tools/wf-patch.py --workflow outputs/case-N/workflow.json --patch _scratch/anchors.json
+    # anchors.json = [{"path": "p1.s1.inputs[0].anchor", "value": "← s0.x"}, ...]
+
+    # 只校验不写
+    python spec/tools/wf-patch.py --workflow ... --set '...' --dry-run
+
+    # 删字段 (取代手 Edit 删; 字段不存在则幂等跳过)
+    python spec/tools/wf-patch.py --workflow ... --unset 'p1.declarations.inputs[0].inferred'
+
+    # 只校验不写
+    python spec/tools/wf-patch.py --workflow ... --set '...' --dry-run
+
+路径语法 (proc/step 主用 id (p1/s1), 下标 procedures[N].steps[M] 也接受; inputs/outputs 用 [i]; 嵌套步 id 带点 s2.1 也支持):
+    p1.s2.effect                      step 标量字段 (effect/substance/form/via/action/directive/kind/intent/group)
+    p1.s1.inputs[0].anchor            IO 字段 (anchor/type/value/id)
+    p1.s2.focus                       step 的 focus 数组 (逗号分隔: focus=via,action,out-type-0)
+    p1.purpose                        procedure 头部字段 (name/purpose/category/platform/author)
+    p1.declarations.inputs[0].desc    declarations 内任意字段 (通用下钻)
+    source.url                        case-level 原帖信息 (platform/author/date/url/title/excerpt)
+    p1.type_registry.场景图.extends    注册 case-specific 类型 (会自动建 type_registry 段)
+
+value 特殊取值:
+    __null__   -> JSON null (用于 substance/form/url 可空)
+
+仍用 Write / Edit 的只剩 (尽量别碰生 JSON):
+    - workflow.json 骨架的首次创建 (Phase 1.2 从 template Write)
+    - instruction (列表套列表, 手动 Edit; 透传 directive 用 --resolve-passthrough)
+    改字段/删字段/改 source 现在都走本工具, 不要再 Read→Edit 改 workflow.json (会反复重读、烧 token).
+
+自动修引号 (load 时兜底):
+    workflow.json 由模型直 Write, 偶尔把中文引号写成未转义的 ASCII " → JSON 崩.
+    本工具 load 失败时会自动把这类误引号修成「」再 parse; 修成功则继续 patch, 并把
+    修复随本次写回落盘 (--dry-run 不写). 修不回才按 exit 2 报错. 不用再手写 _scratch 修复脚本.
+
+退出码:
+    0  全部校验通过并写入 (--dry-run 时为校验通过)
+    1  有校验失败 (整批未写) / 路径解析失败
+    2  CLI 参数错误 / 文件不存在 / JSON 损坏 (且自动修引号也救不回)
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import re
+import sys
+from pathlib import Path
+
+# spec/tools/wf-patch.py -> procedure-dsl/
+DSL_ROOT = Path(__file__).resolve().parent.parent.parent
+TAX_DIR = DSL_ROOT / 'spec' / 'taxonomy'
+
+# Windows 控制台 UTF-8
+for _s in (sys.stdout, sys.stderr):
+    if hasattr(_s, 'reconfigure'):
+        try:
+            _s.reconfigure(encoding='utf-8', errors='replace')
+        except Exception:
+            pass
+
+KIND_VOCAB = {'step', 'block', 'nested'}
+
+# value/directive 里的「引用占位」文案 — 这些是 anchor 的活, value 应填数据本身.
+# 命中即视为「未真正回填」(--resolve-passthrough 会尝试填, lint 会报警).
+META_REF = re.compile(r'[((]?\s*同\s*s[\d]|见\s*s[\d]|←\s*s[\d]|同上')
+
+
+# ===========================================================================
+# 自动修引号: 模型直 Write workflow.json 时常把中文引号写成 ASCII " (未转义) → JSON 崩.
+# 仅在 json.loads 失败时兜底调用 (合法文件零开销). 判别: 串内一个 ASCII " 之后第一个
+# 非空白字符 ∈ {,:}]} 或 EOF → 真·字符串定界符 (保留); 否则是误写的内容引号 → 换直角
+# 引号「」(串内交替 开「/闭」). 逻辑独立内置于本文件 (不 import 任何外部模块);
+# scratch/repair_workflow_quotes.py 是同款独立实现, 二者无依赖关系. 改完必须能 parse 才用.
+# ===========================================================================
+
+_STRUCT_AFTER = set(',:}]')
+
+
+def repair_ascii_quotes(raw: str):
+    """→ (修后文本, 改动的内容引号数). 纯走字符, 不依赖能否 parse."""
+    out, i, n = [], 0, len(raw)
+    in_str = esc = False
+    open_q = True
+    changes = 0
+    while i < n:
+        c = raw[i]
+        if not in_str:
+            out.append(c)
+            if c == '"':
+                in_str, esc, open_q = True, False, True
+            i += 1
+            continue
+        if esc:
+            out.append(c); esc = False; i += 1; continue
+        if c == '\\':
+            out.append(c); esc = True; i += 1; continue
+        if c == '"':
+            j = i + 1
+            while j < n and raw[j] in ' \t\r\n':
+                j += 1
+            nxt = raw[j] if j < n else ''
+            if nxt == '' or nxt in _STRUCT_AFTER:
+                out.append(c); in_str = False          # 真·结束符
+            else:
+                out.append('「' if open_q else '」')     # 误写的内容引号
+                open_q = not open_q
+                changes += 1
+            i += 1
+            continue
+        out.append(c); i += 1
+    return ''.join(out), changes
+
+
+class PathError(Exception):
+    """路径无法解析到 workflow.json 里的目标位置."""
+
+
+# ===========================================================================
+# 字典树加载: leaf 集 + {leaf: 全路径} + 全叶路径集 (与 lint 同款叶子派生)
+# ===========================================================================
+
+def _load_tree(name: str):
+    """读 spec/taxonomy/{name}.json. 返回 (leaves:set, leaf2path:dict, control:list)."""
+    f = TAX_DIR / f'{name}.json'
+    if not f.exists():
+        return set(), {}, []
+    d = json.loads(f.read_text(encoding='utf-8'))
+    leaf2path: dict[str, str] = {}
+
+    def walk(node: dict, prefix: list[str]):
+        nm = node.get('分类名称')
+        if not nm:
+            return
+        p = prefix + [nm]
+        kids = node.get('子分类') or []
+        if not kids:                       # 无子分类 = 叶子
+            leaf2path[nm] = '/'.join(p)
+        for c in kids:
+            walk(c, p)
+
+    for top in d.get('最终分类树') or []:
+        walk(top, [])
+    leaves = set(d.get('$leaves') or leaf2path.keys())
+    return leaves, leaf2path, (d.get('$control') or [])
+
+
+EFFECT_LEAVES, EFFECT_PATHS, _ = _load_tree('effect')
+ACTION_LEAVES, ACTION_PATHS, ACTION_CONTROL = _load_tree('action')
+TYPE_LEAVES, TYPE_PATHS, _ = _load_tree('type')
+
+def _closest(name: str, leaves) -> str:
+    """给个最接近的叶子名做提示 (子串/前缀朴素匹配, 仅供报错文案)."""
+    cands = [lf for lf in leaves if name and (name in lf or lf in name)]
+    return (' 最接近: ' + '/'.join(cands[:3])) if cands else ''
+
+
+def _leaf_menu(field: str) -> str:
+    """校验失败时把该词表的**完整合法叶子**摆出来, 让模型直接照抄、别瞎猜反复试。
+
+    三张词表都很小 (effect 9 / action 30 / type 50), 整列得起。比"去读文件"更直接:
+    模型不用多花一次 read_file, 报错里就有菜单。每个失败字段类型只在末尾打一次。
+    """
+    if field == 'effect':
+        return ('合法 effect 叶子 (照抄其一): ' + ' / '.join(sorted(EFFECT_LEAVES))
+                + '  [全文 spec/taxonomy/effect.json]')
+    if field == 'action':
+        byb: dict = {}
+        for p in sorted(set(ACTION_PATHS.values())):
+            byb.setdefault(p.split('/')[0], []).append(p)
+        body = '; '.join(' | '.join(byb[b]) for b in sorted(byb))
+        return ('合法 action 叶路径 (照抄其一, 全集): ' + body
+                + '  [全文 spec/taxonomy/action.json]')
+    if field in ('type', 'extends'):
+        return ('合法 type 叶子 (extends 挂靠照抄其一): ' + ' / '.join(sorted(TYPE_LEAVES))
+                + '  [全文 spec/taxonomy/type.json]')
+    return ''
+
+
+# ===========================================================================
+# 字段校验 -> (ok, normalized_value, err_msg)
+# ===========================================================================
+
+def validate_field(field: str, value, proc: dict, pending_types: set[str] = None):
+    # null 哨兵 (substance/form/url 可空)
+    if value == '__null__':
+        if field in ('substance', 'form', 'url'):
+            return True, None, ''
+        return False, value, f'__null__ 只对 substance/form/url 有意义, {field} 不可为 null'
+
+    # focus 是数组: 逗号分隔 → list ('via,action,out-type-0'); 空串 → []
+    if field == 'focus':
+        items = [t.strip() for t in str(value).split(',') if t.strip()]
+        return True, items, ''
+
+    if field == 'effect':
+        if value in EFFECT_LEAVES:
+            return True, value, ''
+        # 给了全路径 -> 归一到叶名 (schema 存叶名)
+        for leaf, path in EFFECT_PATHS.items():
+            if value == path:
+                return True, leaf, ''
+        # 容错: 路径里有某段是合法叶名 → 取最末的那个
+        segs = [s.strip() for s in str(value).split('/') if s.strip()]
+        for seg in reversed(segs):
+            if seg in EFFECT_LEAVES:
+                return True, seg, ''
+        return False, value, f'effect={value!r} 不是 effect.json 叶子(存叶名).{_closest(segs[-1] if segs else str(value), EFFECT_LEAVES)}'
+
+    if field == 'action':
+        # action 存全路径; 给叶名自动展开, 给全叶路径原样接受
+        if value in ACTION_PATHS:                 # 是叶名
+            return True, ACTION_PATHS[value], ''
+        if value in ACTION_PATHS.values():        # 是合法叶路径
+            return True, value, ''
+        # 容错: 路径里有某段是合法叶名(多写了段 / 前缀错, 如 生成/元素生成/文生图)→ 取最末的合法叶, 纠正到其全路径
+        segs = [s.strip() for s in str(value).split('/') if s.strip()]
+        for seg in reversed(segs):
+            if seg in ACTION_PATHS:
+                return True, ACTION_PATHS[seg], ''
+        return False, value, (f'action={value!r} 不是合法动作叶子/叶路径 '
+                              f'(对到 action.json 的叶子, 如 元素生成、提取/化学提取/反推).{_closest(segs[-1] if segs else str(value), ACTION_LEAVES)}')
+
+    if field == 'type':
+        # type 是自由标签: Phase 1 随便起个描述性词即可, 不校验是否叶子/注册。
+        # 「对到 type.json 标准叶子 / 注册 type_registry 挂靠」是 Phase 2 归类的活;
+        # 最终是否合法由 lint-case (Check 1: 揪未注册的 case-specific type) + render schema 兜底。
+        if isinstance(value, str) and value.strip():
+            return True, value.strip(), ''
+        return False, value, 'type 不能为空'
+
+    if field == 'extends':                        # type_registry entry 的 extends 必须桥到 stdlib 叶子
+        if value in TYPE_LEAVES:
+            return True, value, ''
+        return False, value, f'type_registry extends={value!r} 必须是 type.json 叶子.{_closest(value, TYPE_LEAVES)}'
+
+    if field in ('substance', 'form'):
+        # 自由提炼的元素点 — 不查词表、不校验 (README「第二阶段 · 2.1 实质 / 形式」).
+        # 字符串原样存 (如 "人物、卧室场景"), 数组逐项 strip 后存. 旧的 taxonomy-lookup 校验已废弃.
+        if isinstance(value, str):
+            return True, value.strip(), ''
+        if isinstance(value, list):
+            return True, [str(p).strip() for p in value if str(p).strip()], ''
+        return False, value, f'{field} 必须是字符串或数组'
+
+    if field == 'anchor':
+        if re.match(r'^\s*(←|→)', str(value)):
+            return True, value, ''
+        return False, value, f'anchor={value!r} 须以 ← (输入引用) 或 → (输出去向) 开头'
+
+    if field == 'kind':
+        if value in KIND_VOCAB:
+            return True, value, ''
+        return False, value, f'kind={value!r} 不在 {sorted(KIND_VOCAB)}'
+
+    # 自由文本字段 (name/value/intent/via/purpose/category/platform/author/desc/group...)
+    return True, value, ''
+
+
+# ===========================================================================
+# 路径解析 -> (parent_container, key, proc, field_name)
+# ===========================================================================
+
+_SEG = re.compile(r'^([^\[]+)(?:\[(\d+)\])?$')
+
+
+def _split_seg(seg: str):
+    m = _SEG.match(seg)
+    if not m:
+        raise PathError(f'非法路径段 {seg!r}')
+    return m.group(1), (int(m.group(2)) if m.group(2) is not None else None)
+
+
+def _descend(container, segs, create=False):
+    """沿 segs 走进 container, 返回 (parent, last_key). create=True 时自动建中间节点.
+
+    segs 每段可带 [i] 下标. last_key 是 dict 键 (str) 或列表下标 (int);
+    设置即 parent[last_key]=value, 删除即 del parent[last_key].
+    用于 source.* / declarations.* 等通用路径 (proc/step 的 id 寻址不走这里).
+    """
+    cur = container
+    for i, seg in enumerate(segs):
+        name, idx = _split_seg(seg)
+        last = (i == len(segs) - 1)
+
+        if idx is None:
+            if last:
+                if not isinstance(cur, dict):
+                    raise PathError(f'{name!r} 的父级不是对象')
+                return cur, name
+            if not isinstance(cur, dict):
+                raise PathError(f'路径段 {name!r} 的父级不是对象')
+            if name not in cur:
+                if not create:
+                    raise PathError(f'路径段 {name!r} 不存在, 无法下钻')
+                cur[name] = {}
+            cur = cur[name]
+        else:
+            if not isinstance(cur, dict):
+                raise PathError(f'路径段 {name!r} 的父级不是对象')
+            if name not in cur:
+                if not create:
+                    raise PathError(f'路径段 {name!r} 不存在, 无法下钻')
+                cur[name] = []
+            lst = cur[name]
+            if not isinstance(lst, list):
+                raise PathError(f'{name} 不是列表')
+            if idx >= len(lst):
+                if not create:
+                    raise PathError(f'{name}[{idx}] 越界或非列表')
+                while idx >= len(lst):
+                    lst.append({})
+            if last:
+                return lst, idx
+            cur = lst[idx]
+    raise PathError('路径为空')
+
+
+# ── --create 自动建结构用的骨架 ─────────────────────────────────────────────
+_STEP_SCALARS = {'effect', 'substance', 'form', 'via', 'action', 'directive', 'kind', 'intent', 'group'}
+
+
+def _new_procedure(pid: str) -> dict:
+    return {
+        'id': pid, 'name': '', 'purpose': '', 'category': '', 'platform': '', 'author': '',
+        'declarations': {'inputs': [], 'resources': [], 'returns': {}},
+        'steps': [],
+    }
+
+
+def _new_step(sid: str) -> dict:
+    return {'id': sid, 'kind': 'step', 'via': '', 'inputs': [], 'outputs': []}
+
+
+def _new_io(is_output: bool, sid: str, idx: int) -> dict:
+    if is_output:
+        return {'id': f'{sid}o{idx + 1}', 'type': '', 'value': '', 'anchor': ''}
+    return {'type': '', 'value': '', 'anchor': ''}
+
+
+def _split_step_path(remainder: str):
+    """create 模式下 step 不存在、无法前缀匹配时, 从路径切出 (sid, fsegs).
+
+    规则: 出现 inputs[i]/outputs[i] 段 → 其前为 sid; 否则末段须是已知 step 标量字段, 其前为 sid.
+    sid 可含点 (嵌套步 s2.1)。切不出返回 (None, None) — 不创建, 避免误建。
+    """
+    segs = remainder.split('.')
+    for j, s in enumerate(segs):
+        nm, _ = _split_seg(s)
+        if nm in ('inputs', 'outputs'):
+            return ('.'.join(segs[:j]) or None), segs[j:]
+    if segs[-1] in _STEP_SCALARS:
+        return ('.'.join(segs[:-1]) or None), [segs[-1]]
+    return None, None
+
+
+def locate(data: dict, path: str, create: bool = False):
+    """把 path 解析到目标. 返回 (parent, key, proc, field_name).
+
+    设置即 parent[key] = value. proc 给校验提供 type_registry 上下文.
+    proc / step 主用 id 寻址 (p1/s1), 也接受下标 procedures[N]/steps[M]; inputs/outputs 用 [i] 下标.
+    step id 可能带点 (嵌套步 s2.1) — 用最长前缀匹配消歧 (s2.1 优先于 s2).
+    create=True (构建模式): 缺失的 procedure / step / IO 元素 / 中间结构自动创建, 新建打印到 stderr.
+    """
+    if '.' not in path:
+        raise PathError(f'路径太短 {path!r}, 至少 <proc>.<字段> 或 source.<字段>')
+
+    proc_id, remainder = path.split('.', 1)
+
+    # --- source.* 分支 (case-level 原帖信息, 无 proc 上下文) ---
+    if proc_id == 'source':
+        src = data.setdefault('source', {})
+        parent, key = _descend(src, remainder.split('.'), create=create)
+        return parent, key, None, (key if isinstance(key, str) else '')
+
+    procs = data.setdefault('procedures', [])
+    # 接受两种 proc 寻址: id (p1) 或下标别名 procedures[N] (映射到第 N 个工序; 弱模型爱用这种)
+    m_idx = re.match(r'^procedures\[(\d+)\]$', proc_id)
+    if m_idx:
+        idx = int(m_idx.group(1))
+        if idx < len(procs):
+            proc = procs[idx]
+        elif create:
+            proc = _new_procedure(f'p{idx + 1}')
+            procs.append(proc)
+            print(f'[wf-patch] + 新建 procedure p{idx + 1} (来自 procedures[{idx}])', file=sys.stderr)
+        else:
+            raise PathError(f'procedures[{idx}] 越界 (现有 {len(procs)} 个工序)')
+    else:
+        proc = next((p for p in procs if p.get('id') == proc_id), None)
+        if proc is None:
+            if not create:
+                ids = [p.get('id') for p in procs]
+                raise PathError(f'找不到 procedure id={proc_id!r} (现有: {ids})')
+            proc = _new_procedure(proc_id)
+            procs.append(proc)
+            print(f'[wf-patch] + 新建 procedure {proc_id}', file=sys.stderr)
+
+    # --- type_registry 分支 (允许自动建段/条目) ---
+    if remainder == 'type_registry' or remainder.startswith('type_registry.'):
+        parts = remainder.split('.')
+        if len(parts) == 3:
+            reg = proc.setdefault('type_registry', {})
+            entry = reg.setdefault(parts[1], {})
+            return entry, parts[2], proc, parts[2]
+        raise PathError('type_registry 路径形如 p1.type_registry.<类型名>.<extends|desc>')
+
+    # --- step 分支: 支持 id 寻址 (p1.s1.effect) 和下标寻址 (procedures[0].steps[0].effect) ---
+    matched, field_part = None, None
+    m_step = re.match(r'^steps\[(\d+)\]\.(.+)$', remainder)   # 下标寻址 steps[N].<字段>
+    if m_step:
+        sidx = int(m_step.group(1))
+        steps = proc.setdefault('steps', [])
+        if sidx < len(steps):
+            matched = steps[sidx]
+        elif create:
+            matched = _new_step(f's{sidx + 1}')
+            steps.append(matched)
+            print(f'[wf-patch] + 新建 step (procedures.steps[{sidx}] → id s{sidx + 1})', file=sys.stderr)
+        else:
+            raise PathError(f'steps[{sidx}] 越界 (该工序现有 {len(steps)} 步)')
+        field_part = m_step.group(2)
+    else:                                                     # id 寻址: 最长前缀匹配现有 step id
+        for s in (proc.get('steps') or []):
+            sid = s.get('id')
+            if not sid:
+                continue
+            if remainder == sid:
+                raise PathError(f'step 路径要带字段, 形如 {proc_id}.{sid}.effect')
+            if remainder.startswith(sid + '.') and (matched is None or len(sid) > len(matched['id'])):
+                matched = s
+        if matched is None and create:
+            sid_new, _ = _split_step_path(remainder)
+            if sid_new:
+                matched = _new_step(sid_new)
+                proc.setdefault('steps', []).append(matched)
+                print(f'[wf-patch] + 新建 step {proc_id}.{sid_new}', file=sys.stderr)
+        if matched is not None:
+            field_part = remainder[len(matched['id']) + 1:]   # 'sid.' 之后
+    if matched is not None:
+        sid = matched.get('id', '?')
+        fsegs = field_part.split('.')
+        name2, idx2 = _split_seg(fsegs[0])
+        if name2 in ('inputs', 'outputs'):
+            if idx2 is None:
+                raise PathError(f'{name2} 要带下标, 形如 {name2}[0]')
+            lst = matched.get(name2)
+            if not isinstance(lst, list):
+                if create:
+                    matched[name2] = lst = []
+                else:
+                    raise PathError(f'{proc_id}.{sid}.{name2}[{idx2}] 越界 (该 step 有 0 个 {name2})')
+            if idx2 >= len(lst):
+                if not create:
+                    raise PathError(f'{proc_id}.{sid}.{name2}[{idx2}] 越界 (该 step 有 {len(lst)} 个 {name2})')
+                while idx2 >= len(lst):
+                    lst.append(_new_io(name2 == 'outputs', sid, len(lst)))
+            if len(fsegs) != 2:
+                raise PathError(f'IO 路径形如 {proc_id}.{sid}.{name2}[{idx2}].anchor')
+            return lst[idx2], fsegs[1], proc, fsegs[1]
+        else:
+            if len(fsegs) != 1:
+                raise PathError(f'step 标量字段形如 {proc_id}.{sid}.{name2}')
+            return matched, name2, proc, name2
+
+    # --- proc 内其余路径: 头部字段 / declarations.* / return_row.* 等, 走通用下钻 ---
+    parent, key = _descend(proc, remainder.split('.'), create=create)
+    return parent, key, proc, (key if isinstance(key, str) else '')
+
+
+# ===========================================================================
+# 透传回填: anchor 为纯 ← sN.varname 的 IO, 从源 output 抄 value (逐字回填)
+# ===========================================================================
+
+def _is_fillable(value) -> bool:
+    """该 value 算「还没真正回填」吗 — 空 / 占位符 / 引用文案."""
+    if value in (None, '', '-'):
+        return True
+    return bool(META_REF.search(str(value)))
+
+
+def _passthrough_id(anchor):
+    """anchor 为 `← <output-id>` (可带 [i] 容器索引) → 返回 output id; 否则 None.
+
+    `← 工序输入` / `← s6 (链)` 等非纯 id 引用返回 None (无法确定唯一源 value).
+    """
+    m = re.match(r'^\s*←\s*([^\s\[((]+)', str(anchor or ''))
+    if not m:
+        return None
+    return m.group(1) or None
+
+
+def resolve_passthrough(data: dict):
+    """把 anchor 为纯透传 (← <output-id>)、value 仍空或占位的 input, 用源 output 的 value 逐字填上.
+
+    迭代到不动点 (处理链式透传). 返回 (filled_msgs, warn_msgs).
+    """
+    out_index = {}          # output id -> output item (读 value)
+    for p in data.get('procedures') or []:
+        for s in p.get('steps') or []:
+            for o in s.get('outputs') or []:
+                if isinstance(o, dict) and o.get('id'):
+                    out_index[o['id']] = o
+
+    def _src_value(rid):
+        src = out_index.get(rid)
+        if src is None or _is_fillable(src.get('value')):
+            return None
+        return src['value']
+
+    filled: list[str] = []
+    changed, rounds = True, 0
+    while changed and rounds < 20:
+        changed, rounds = False, rounds + 1
+        for p in data.get('procedures') or []:
+            for s in p.get('steps') or []:
+                for idx, io in enumerate(s.get('inputs') or []):
+                    if not isinstance(io, dict) or not _is_fillable(io.get('value')):
+                        continue
+                    rid = _passthrough_id(io.get('anchor'))
+                    val = _src_value(rid) if rid else None
+                    if val is None:
+                        continue
+                    io['value'] = val
+                    filled.append(
+                        f"{p.get('id')}.{s.get('id')}.inputs[{idx}].value "
+                        f"← 复制自 {rid} ({len(str(val))} 字)"
+                    )
+                    changed = True
+
+    # 仍填不动的透传 (源 id 找不到) → warn
+    warns: list[str] = []
+    for p in data.get('procedures') or []:
+        for s in p.get('steps') or []:
+            for idx, io in enumerate(s.get('inputs') or []):
+                if not isinstance(io, dict) or not _is_fillable(io.get('value')):
+                    continue
+                rid = _passthrough_id(io.get('anchor'))
+                if rid and out_index.get(rid) is None:
+                    warns.append(
+                        f"{p.get('id')}.{s.get('id')}.inputs[{idx}] anchor 指向 "
+                        f"{rid} 但找不到该 output id (检查 anchor / output id)"
+                    )
+    return filled, warns
+
+
+# ===========================================================================
+# 应用
+# ===========================================================================
+
+def load_patches(args) -> list[tuple[str, str]]:
+    """汇总 --set、--patch 与 --set-file 成 [(path, value), ...]."""
+    def _norm(v):
+        if isinstance(v, str):
+            # 将中文全角双角/单引号自动归一化为标准半角引号,更利于 AI 生图引擎和 Prompt 语法识别
+            v = v.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
+        return v
+
+    def _dq(x: str) -> str:
+        # 剥掉成对外层引号. cmd.exe 不剥单引号 → agent 写的 --set 'p.f=v' / p.f='v'
+        # 会把单引号原样传进来, 导致 path 变成 'p1 这种 (找不到 procedure). 这里兜底剥掉.
+        x = x.strip()
+        if len(x) >= 2 and x[0] == x[-1] and x[0] in ('"', "'"):
+            x = x[1:-1].strip()
+        return x
+
+    out: list[tuple[str, str]] = []
+    for s in args.set or []:
+        s = _dq(s)                           # 整体外层引号 (cmd 没剥的 'path=value')
+        if '=' not in s:
+            raise SystemExit(f'wf-patch: --set 缺 "=" : {s!r} (形如 path=value)')
+        path, value = s.split('=', 1)        # 只切第一个 '='
+        out.append((_dq(path), _norm(_dq(value))))
+
+    # 🟢 新增:从外部文件读取值注入
+    for sf in getattr(args, 'set_file', None) or []:
+        if '=' not in sf:
+            raise SystemExit(f'wf-patch: --set-file 缺 "=" : {sf!r} (形如 path=file_path)')
+        path, fpath_str = sf.split('=', 1)
+        fpath = Path(fpath_str.strip())
+        if not fpath.exists():
+            raise SystemExit(f'wf-patch: --set-file 指定的文件不存在: {fpath_str}')
+        try:
+            value = fpath.read_text(encoding='utf-8')
+        except Exception as e:
+            raise SystemExit(f'wf-patch: 无法读取 --set-file 指定的文件 {fpath_str}: {e}')
+        out.append((path.strip(), _norm(value)))
+
+    if args.patch:
+        if not args.patch.exists():
+            raise SystemExit(
+                f'wf-patch: --patch 文件不存在 {args.patch}\n'
+                f'  → --patch 的清单文件是**你要先写的输入**(扁平 `[{{"path":..,"value":..}}]` JSON)。\n'
+                f'    先 write_file 写出它, 再 `--patch` 跑它;\n'
+                f'    或字段不多时直接内联: `--set \'p1.s1.inputs[0].type=参考图\' --set ...`(不用文件)。')
+        try:
+            items = json.loads(args.patch.read_text(encoding='utf-8'))
+        except json.JSONDecodeError as e:
+            raise SystemExit(f'wf-patch: --patch 不是合法 JSON: {e}')
+        for it in items:
+            out.append((it['path'], _norm(it['value'])))
+    return out
+
+
+# ===========================================================================
+# @quote 标记回填: value/directive 写 `@quote|起锚|止锚` 或 `@quote|关键词`,
+# 由 --resolve-quotes 顺标记从原文/配图 OCR 匹配真实内容, 批量替换 (空白无关匹配)
+# ===========================================================================
+
+def _q_source_text(path: Path) -> str:
+    d = json.loads(path.read_text(encoding='utf-8'))
+    if not isinstance(d, dict):
+        return str(d)
+    return '\n'.join(str(d.get(k, '')) for k in ('title', 'body_text') if d.get(k))
+
+
+def _q_norm(text: str):
+    chars, idx = [], []
+    for i, ch in enumerate(text):
+        if ch.isspace():
+            continue
+        chars.append(ch)
+        idx.append(i)
+    return ''.join(chars), idx
+
+
+def _q_range_between(text: str, frm: str, to: str):
+    ns, idx = _q_norm(text)
+    nf, _ = _q_norm(frm)
+    nt, _ = _q_norm(to)
+    if not nf or not nt:
+        return None
+    p = ns.find(nf)
+    if p < 0:
+        return None
+    q = ns.find(nt, p + len(nf))
+    if q < 0:
+        return None
+    return text[idx[p]: idx[q + len(nt) - 1] + 1]
+
+
+def _q_braces(text: str, lo: int, hi: int):
+    depth, op, i = 0, None, lo
+    while i >= 0:
+        if text[i] == '}':
+            depth += 1
+        elif text[i] == '{':
+            if depth == 0:
+                op = i
+                break
+            depth -= 1
+        i -= 1
+    if op is None:
+        return None
+    depth, j = 0, op
+    while j < len(text):
+        if text[j] == '{':
+            depth += 1
+        elif text[j] == '}':
+            depth -= 1
+            if depth == 0:
+                return (op, j) if j >= hi else None
+        j += 1
+    return None
+
+
+def _q_query_block(text: str, query: str):
+    ns, idx = _q_norm(text)
+    nq, _ = _q_norm(query)
+    if not nq:
+        return None
+    p = ns.find(nq)
+    if p < 0:
+        return None
+    o_lo, o_hi = idx[p], idx[p + len(nq) - 1]
+    br = _q_braces(text, o_lo, o_hi)           # 命中落在 {...} 内 → 返回整块
+    if br:
+        return text[br[0]: br[1] + 1]
+    lo = text.rfind('\n', 0, o_lo) + 1          # 否则返回所在行/段
+    hi = text.find('\n', o_hi)
+    return text[lo: (hi if hi >= 0 else len(text))].strip()
+
+
+def resolve_quotes(data: dict, corpora: list):
+    """扫 value/directive 里的 `@quote|...` 标记, 顺标记从 corpora 匹配真实内容批量替换.
+
+    标记: `@quote|起锚|止锚` (范围, 推荐长段) 或 `@quote|关键词` (命中落 JSON 块返回整块, 否则所在行/段).
+    corpora: [(label, text), ...] 依次尝试 (原文优先, 再 OCR). 返回 (filled, warns).
+    """
+    filled, warns = [], []
+
+    def _resolve(v: str):
+        parts = v[len('@quote|'):].split('|')
+        for label, text in corpora:
+            r = _q_range_between(text, parts[0], parts[1]) if len(parts) >= 2 else _q_query_block(text, parts[0])
+            if r:
+                return r, label
+        return None, None
+
+    for p in data.get('procedures') or []:
+        pid = p.get('id')
+        for s in p.get('steps') or []:
+            sid = s.get('id')
+            d = s.get('directive')
+            if isinstance(d, str) and d.startswith('@quote|'):
+                r, label = _resolve(d)
+                if r:
+                    s['directive'] = r
+                    filled.append(f'{pid}.{sid}.directive ← [{label}] {len(r)} 字')
+                else:
+                    warns.append(f'{pid}.{sid}.directive: @quote 未匹配 {d[:40]!r}')
+            for kind in ('inputs', 'outputs'):
+                for k, item in enumerate(s.get(kind) or []):
+                    if not isinstance(item, dict):
+                        continue
+                    v = item.get('value')
+                    if isinstance(v, str) and v.startswith('@quote|'):
+                        r, label = _resolve(v)
+                        if r:
+                            item['value'] = r
+                            filled.append(f'{pid}.{sid}.{kind}[{k}].value ← [{label}] {len(r)} 字')
+                        else:
+                            warns.append(f'{pid}.{sid}.{kind}[{k}].value: @quote 未匹配 {v[:40]!r}')
+    return filled, warns
+
+
+def prune_patch_file(patch_path: Path, value_errors: list) -> int | None:
+    """把 --patch 文件裁成只剩**未成功 (value 校验失败)** 的条目, 成功的删掉。
+
+    成功项已落盘到 workflow.json, 留在 patch 里只会重复应用; 裁掉后 patch 文件就是
+    "剩余待修清单", 每条带 `_error` 失败原因 (再读时 path/value 之外的键被忽略, 无副作用)。
+    改完 value 重跑同一文件直到清空为 []。返回剩余条数; 文件读不动/不是数组返回 None。
+    """
+    try:
+        items = json.loads(patch_path.read_text(encoding='utf-8'))
+    except Exception:
+        return None
+    if not isinstance(items, list):
+        return None
+    err_by_path: dict = {}
+    for p, _field, msg in value_errors:
+        err_by_path.setdefault(p, msg)            # 同 path 多错只留第一条
+    remaining = []
+    for it in items:
+        if isinstance(it, dict) and it.get('path') in err_by_path:
+            it = {k: v for k, v in it.items() if k != '_error'}
+            it['_error'] = err_by_path[it['path']]
+            remaining.append(it)
+    patch_path.write_text(json.dumps(remaining, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
+    return len(remaining)
+
+
+def main() -> None:
+    ap = argparse.ArgumentParser(
+        prog='wf-patch.py',
+        description='workflow.json 安全批量字段设置器 (写入即校验, 任何一条非法整批不写)',
+    )
+    ap.add_argument('--workflow', type=Path, required=True, help='目标 workflow.json')
+    ap.add_argument('--set', action='append', metavar='PATH=VALUE',
+                    help='单条赋值, 可重复. 只在第一个 = 处切; value 可含 = 和空格 (记得整体加引号)')
+    ap.add_argument('--patch', type=Path, default=None,
+                    help='批量赋值清单 .json: [{"path":..,"value":..}, ...]')
+    ap.add_argument('--set-file', action='append', metavar='PATH=FILE_PATH', default=None,
+                    help='从外部文件读取内容注入指定字段. e.g. p1.s1.outputs[0].value=_scratch/prompt.txt')
+    ap.add_argument('--unset', action='append', metavar='PATH', default=None,
+                    help='删字段, 可重复. e.g. p1.declarations.inputs[0].inferred (字段不存在则跳过). 取代手 Edit 删字段')
+    ap.add_argument('--resolve-passthrough', action='store_true',
+                    help='把 anchor 为纯透传 (← sN.varname)、value 仍空/占位的 IO, 顺 anchor 从源 output 逐字抄 value. 可单独跑, 也可跟在 --set/--patch 后 (先赋值再解析). 迭代处理链式透传')
+    ap.add_argument('--dry-run', action='store_true', help='只校验/预演, 不写')
+    ap.add_argument('--create', action='store_true',
+                    help='(已默认开启, 保留兼容) 缺失的 procedure / step / IO 元素自动创建、文件不存在从空建')
+    ap.add_argument('--no-create', action='store_true',
+                    help='关闭自动建: 路径不存在就报错 (严格防 typo; 仅在「纯填充已存在结构、想抓打错的路径」时用)')
+    ap.add_argument('--resolve-quotes', action='store_true',
+                    help='把 value/directive 里的 @quote|起锚|止锚 (或 @quote|关键词) 标记, 顺标记从 --source 原文 / --ocr 配图文本匹配真实内容批量替换. 跟 anchor patch 一起跑')
+    ap.add_argument('--source', type=Path, default=None, help='--resolve-quotes 的原文 case json (匹配语料)')
+    ap.add_argument('--ocr', type=Path, default=None, help='--resolve-quotes 的配图 OCR 文本文件 (第二语料)')
+    ap.add_argument('--prune', action='store_true',
+                    help='跟 --patch 配合: 应用后把 patch 文件裁成只剩**未成功**的条目(成功的已落盘→删掉, '
+                         '失败的标 _error 原因保留)。patch 文件即变"剩余待修清单", 改完重跑同一文件直到清空。')
+    args = ap.parse_args()
+    # 默认 upsert (缺路径自动建); 弱模型增量 patch 总需要它, gated 反而一直撞「越界/不存在」死循环。
+    # --no-create 才关闭 (回到严格寻址、防 typo)。--create 保留为 no-op 兼容旧命令/文档。
+    args.create = not args.no_create
+
+    wf = args.workflow
+    repaired = 0
+    if args.create and not wf.exists():
+        data = {}
+        print(f'[wf-patch] + 新建 workflow 文件 {wf.name} (从空开始构建)', file=sys.stderr)
+    elif not wf.exists():
+        print(f'wf-patch: 文件不存在 {wf} (默认会从空新建; 你传了 --no-create 才不建)', file=sys.stderr)
+        sys.exit(2)
+    else:
+        raw = wf.read_text(encoding='utf-8')
+        try:
+            data = json.loads(raw)
+        except json.JSONDecodeError as e:
+            # 兜底: 试着把误写成 ASCII 的中文引号修成「」再 parse (模型直 Write 常见崩因)
+            fixed, repaired = repair_ascii_quotes(raw)
+            try:
+                data = json.loads(fixed)
+            except json.JSONDecodeError:
+                print(f'wf-patch: {wf} 不是合法 JSON, 无法处理: {e}\n'
+                      f'  → 去 workflow.json 第 {e.lineno} 行附近修语法 '
+                      f'(最常见: 数组 ] 或 对象 }} 结束后、下一个 "key" 前缺逗号), 修好再重跑。'
+                      f'别盲目重试本命令 (JSON 没修, 每次都同样报错)。', file=sys.stderr)
+                sys.exit(2)
+            print(f'[wf-patch] ⚠️ 原文件 JSON 非法 ({e.msg} @ line {e.lineno}); 已自动把 '
+                  f'{repaired} 处误写的 ASCII 引号修成「」→ 解析成功, 修复将随本次写回落盘',
+                  file=sys.stderr)
+
+    patches = load_patches(args)
+    unsets = args.unset or []
+    if not patches and not unsets and not args.resolve_passthrough and not args.resolve_quotes:
+        if args.patch:   # --patch 给了但解析为空 [] (多半是 --prune 收敛后): 算完成, 不是误用
+            print(f'wf-patch: {args.patch.name} 为空 [], 没有待应用项 (patch 已全部完成)。')
+            sys.exit(0)
+        print('wf-patch: 没有 --set / --patch / --unset / --resolve-passthrough / --resolve-quotes, 啥也没干', file=sys.stderr)
+        sys.exit(2)
+
+    # 解析 + 校验; 任何一条失败 -> 整批不写
+    pending_types = set()
+    for path, _ in patches:
+        m = re.match(r'^p\d+\.type_registry\.([^.]+)\.(extends|desc)$', path)
+        if m:
+            pending_types.add(m.group(1))
+
+    plan = []          # set: (parent, key, normalized_value, path, display)
+    del_plan = []      # unset: (parent, key, path)
+    skipped = []       # unset 跳过 (字段本就不在)
+    # 错误分两类, 决定原子 vs 部分应用:
+    #   fatal  = 路径/结构错 (locate 失败: 路径对不上、缺 --create 等) → 整批不写, 保护结构
+    #   value  = 字段值校验失败 (effect/action/type 等值非法) → **跳过这条、其余照写** (部分应用),
+    #            末尾以 exit 1 提示回去补。这样一批里几个值错不再连累其余正确字段一起丢。
+    fatal_errors = []  # (path, msg)
+    value_errors = []  # (path, msg)
+    for path, value in patches:
+        try:
+            parent, key, proc, field = locate(data, path, create=args.create)
+        except PathError as e:
+            fatal_errors.append((path, str(e)))
+            continue
+        ok, norm, msg = validate_field(field, value, proc, pending_types)
+        if not ok:
+            value_errors.append((path, field, msg))
+            continue
+        plan.append((parent, key, norm, path, norm if norm is not None else 'null'))
+    for path in unsets:
+        try:
+            parent, key, _proc, _field = locate(data, path)
+        except PathError as e:
+            fatal_errors.append((path, str(e)))
+            continue
+        present = (isinstance(parent, dict) and key in parent) or \
+                  (isinstance(parent, list) and isinstance(key, int) and key < len(parent))
+        (del_plan if present else skipped).append((parent, key, path) if present else path)
+
+    if patches or unsets:
+        n_fail = len(fatal_errors) + len(value_errors)
+        print(f'[wf-patch] {wf.name} — set {len(plan)}/{len(patches)} 通过, '
+              f'unset {len(del_plan)} 删/{len(skipped)} 跳过, {n_fail} 失败')
+        for _p, _k, _n, path, disp in plan:
+            print(f'  ✓ set   {path} = {disp}')
+        for _p, _k, path in del_plan:
+            print(f'  ✓ unset {path}')
+        for path in skipped:
+            print(f'  · skip  {path} (字段本就不存在)')
+        for path, _field, msg in value_errors:
+            print(f'  ✗ {path}  — {msg}')
+        for path, msg in fatal_errors:
+            print(f'  ✗✗ {path}  — {msg}  [路径/结构错]')
+        # 结构错 = patch 清单跟文件对不上 → 整批不写 (原子, 别半建坏骨架)
+        if fatal_errors:
+            print(f'\n有 {len(fatal_errors)} 条路径/结构错误, 整批未写入 (先修: 路径写对 / 该建的加 --create).',
+                  file=sys.stderr)
+            sys.exit(1)
+        # 只有字段值非法 → 跳过这几条、其余照常写, 进度不丢; 末尾 exit 1 提示去补
+        if value_errors:
+            # 把出错字段类型的**完整合法清单**打出来 (每类一次), 模型直接照抄、别再瞎猜反复试
+            shown = []
+            for _p, f, _m in value_errors:
+                key = 'type' if f == 'extends' else f
+                if key in ('effect', 'action', 'type') and key not in shown:
+                    shown.append(key)
+            for key in shown:
+                print(f'  ↳ {_leaf_menu(key)}', file=sys.stderr)
+            print(f'\n{len(value_errors)} 处字段值非法**已跳过未写**, 其余 {len(plan)} 处照常应用; '
+                  f'照上面清单选合法叶子, 修正这几条后重跑补上 (进度不丢, 别整批重来).', file=sys.stderr)
+
+    # 应用到内存 data (set 先 unset 后; resolve 要看到这些改动). 是否持久化由 dry-run 决定.
+    for parent, key, norm, _, _ in plan:
+        parent[key] = norm
+    for parent, key, _path in sorted(del_plan, key=lambda d: -d[1] if isinstance(d[1], int) else 0):
+        if isinstance(parent, list):
+            parent.pop(key)
+        else:
+            del parent[key]
+
+    # 透传回填
+    filled, warns = [], []
+    if args.resolve_passthrough:
+        filled, warns = resolve_passthrough(data)
+        print(f'[resolve-passthrough] 回填 {len(filled)} 处透传 value, {len(warns)} 处填不动')
+        for m in filled:
+            print(f'  ✓ {m}')
+        for w in warns:
+            print(f'  ⚠ {w}')
+
+    # @quote 标记回填 (顺 @quote|起锚|止锚 从原文/OCR 匹配真实内容批量替换)
+    quoted, qwarns = [], []
+    if args.resolve_quotes:
+        corpora = []
+        if args.source and args.source.exists():
+            corpora.append(('原文', _q_source_text(args.source)))
+        if args.ocr and args.ocr.exists():
+            corpora.append(('配图OCR', args.ocr.read_text(encoding='utf-8')))
+        if not corpora:
+            print('wf-patch: --resolve-quotes 需要 --source (或 --ocr) 指向匹配语料', file=sys.stderr)
+        else:
+            quoted, qwarns = resolve_quotes(data, corpora)
+            print(f'[resolve-quotes] 回填 {len(quoted)} 处 @quote 标记, {len(qwarns)} 处未匹配')
+            for m in quoted:
+                print(f'  ✓ {m}')
+            for w in qwarns:
+                print(f'  ⚠ {w}')
+
+    # 有字段值非法被跳过 → 退出码 1 (告诉 agent 还有几条要补), 但有效改动已照常落盘
+    final_exit = 1 if value_errors else 0
+
+    # --prune: 把 --patch 文件裁成只剩未成功项 (成功的已落盘→删, 失败的标 _error 留待修)。
+    # dry-run 不动文件 (预演不该有副作用); fatal 早已 exit, 到这里只剩 value 错或全成功。
+    if args.prune and args.patch and not args.dry_run:
+        nrem = prune_patch_file(args.patch, value_errors)
+        if nrem is not None:
+            if nrem:
+                print(f'\n[prune] 已把 {args.patch.name} 裁为剩余 {nrem} 条未成功项 '
+                      f'(成功的已删, 每条带 _error 原因); 修正 value 后重跑同一文件即可。', file=sys.stderr)
+            else:
+                print(f'\n[prune] {args.patch.name} 全部成功, 已清空为 []。', file=sys.stderr)
+
+    n_changes = len(plan) + len(del_plan) + len(filled) + len(quoted)
+    if args.dry_run:
+        extra = f' (+ 自动修复 {repaired} 处引号, dry-run 同样不写)' if repaired else ''
+        print(f'\n--dry-run: 预演 {n_changes} 处改动{extra}, 未写入.')
+        sys.exit(final_exit)
+
+    # repaired>0 时即便无字段改动也要落盘 (否则修好的引号没存下来, 文件还是坏的)
+    if n_changes == 0 and not repaired:
+        print('\n没有改动 (透传 value 都已填好 / 无可赋值), 未写文件.')
+        sys.exit(final_exit)
+
+    # 落盘 (安全序列化, 你从不手写 JSON)
+    wf.write_text(json.dumps(data, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
+    tail = f' (含自动修复 {repaired} 处引号→「」)' if repaired else ''
+    print(f'\n已写入 {n_changes} 处到 {wf.name}{tail}.')
+    sys.exit(final_exit)
+
+
+if __name__ == '__main__':
+    main()

+ 74 - 0
examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/claude_report_batch.py

@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+"""对指定 5 个 query 的「采纳/命中」帖子,用 claude 重跑大模型工序解构
+================================================================================
+
+- 只跑 decision=="report" 且 not anomaly 的帖(与 UI「采纳/命中」一致,复用 server.adapt)
+- 模型 anthropic/claude-sonnet-4-6(界面 fuzzy match 同名)
+- redo=True 覆盖:旧版本(gemini)自动进 history,新 claude 版成最新
+用法:
+  python claude_report_batch.py [model] [workers]
+"""
+import sys
+import json
+from pathlib import Path
+from concurrent.futures import ThreadPoolExecutor, as_completed
+
+HERE = Path(__file__).resolve().parent          # query_jobs/
+MP = HERE.parent                                # mode_procedure/
+sys.path.insert(0, str(MP))                     # server, db
+sys.path.insert(0, str(MP / "mode-dsl"))        # batch_model_extract
+
+# 导入 server 拿 adapt(中和 argparse,避免它把脚本参数当端口)
+_saved = sys.argv
+sys.argv = ["server.py"]
+import server
+sys.argv = _saved
+
+import batch_model_extract as bm
+
+QUERIES = [
+    "AI 知识科普 版面设计 图片 生成 怎么做",
+    "AI 知识科普 文本结构 图片 生成 怎么做",
+    "AI 知识科普 文字排版 图片 生成 怎么做",
+    "AI 知识科普 卡片 图片 生成 怎么做",
+    "AI 知识 文字排版 图片 生成 怎么做",
+]
+
+
+def _is_report(r, q):
+    a = server.adapt(r, q, "A")
+    return a.get("decision") == "report" and not a.get("anomaly")
+
+
+def report_results(q):
+    d = json.loads((server.RUNS_DIR / q / "form_A.json").read_text(encoding="utf-8"))
+    return [r for r in d.get("results", []) if _is_report(r, q)]
+
+
+def main():
+    model = sys.argv[1] if len(sys.argv) > 1 else "anthropic/claude-sonnet-4-6"
+    workers = int(sys.argv[2]) if len(sys.argv) > 2 else 3
+    redo = (sys.argv[3] if len(sys.argv) > 3 else "1") == "1"   # 0=跳过已完成(重试用)
+
+    tasks = []
+    for q in QUERIES:
+        reps = report_results(q)
+        print(f"📋 {q}: 采纳 {len(reps)} 帖")
+        tasks += [(q, r) for r in reps]
+    print(f"\n共 {len(tasks)} 帖采纳 · 模型 {model} · 并发 {workers} · {'redo覆盖' if redo else '跳过已完成(重试)'}\n")
+
+    ok = fail = skip = 0
+    with ThreadPoolExecutor(max_workers=workers) as ex:
+        futs = {ex.submit(bm._process_one, q, r, model, redo): r.get("case_id") for q, r in tasks}
+        for i, fut in enumerate(as_completed(futs), 1):
+            cid, msg = fut.result()
+            if (msg or "").startswith("skip"):
+                skip += 1; continue
+            mark = "✅" if (msg or "").startswith("ok") else "❌"
+            ok += mark == "✅"; fail += mark == "❌"
+            print(f"[{i}/{len(tasks)}] {mark} {cid} — {msg}")
+    print(f"\n🎉 完成:成功 {ok} · 失败 {fail} · 跳过 {skip} / {len(tasks)}")
+
+
+if __name__ == "__main__":
+    main()

+ 57 - 0
examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/export_claude.py

@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+"""导出 5 个 query 里「claude 解析成功」的采纳贴的 _model/ 到 output/
+================================================================================
+结构:output/{query}/procedures/A_{短码}/_model/{workflow.json, _meta.json,
+       _source.json, case-*.html, _extract.log}(不含 history/)
+只导 _extract.log 头里是 claude 的(report 采纳贴;非 report 的还是 gemini,不导)。
+"""
+import re
+import shutil
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent
+MP = HERE.parent
+RUNS = MP / "runs_new"
+OUT = MP / "output"
+
+QUERIES = [
+    "AI 知识科普 版面设计 图片 生成 怎么做",
+    "AI 知识科普 文本结构 图片 生成 怎么做",
+    "AI 知识科普 文字排版 图片 生成 怎么做",
+    "AI 知识科普 卡片 图片 生成 怎么做",
+    "AI 知识 文字排版 图片 生成 怎么做",
+]
+
+
+def _model_is_claude(model_dir):
+    log = model_dir / "_extract.log"
+    if not log.is_file():
+        return False
+    m = re.search(r"模型 (\S+)", log.read_text(errors="replace"))
+    return bool(m and ("claude" in m.group(1) or "sonnet" in m.group(1)))
+
+
+def main():
+    n = 0
+    for q in QUERIES:
+        proc = RUNS / q / "procedures"
+        if not proc.is_dir():
+            continue
+        for model_dir in sorted(proc.glob("*/_model")):
+            if not (model_dir / "workflow.json").is_file():
+                continue
+            if not _model_is_claude(model_dir):
+                continue   # 跳过非 claude(gemini 的非采纳贴)
+            folder = model_dir.parent.name           # A_xxx
+            dst = OUT / q / "procedures" / folder / "_model"
+            dst.mkdir(parents=True, exist_ok=True)
+            for f in model_dir.iterdir():
+                if f.is_file():                      # 只拷文件,跳过 history/ 子目录
+                    shutil.copy2(f, dst / f.name)
+            n += 1
+            print(f"  ✅ {q[:14]}.../{folder}")
+    print(f"\n🎉 导出 {n} 个帖子的 _model/ → {OUT}")
+
+
+if __name__ == "__main__":
+    main()

+ 215 - 0
examples/process_pipeline/script/search_eval/mode_procedure/query_jobs/info_graphic_job.py

@@ -0,0 +1,215 @@
+# -*- coding: utf-8 -*-
+"""信息图/版面设计 query 任务(20 条)
+================================================================================
+
+维度组合(实质 5 × 形式 4 = 20 条):
+  工具类型: AI(固定)
+  实质:     无 / 信息 / 内容呈现 / 知识 / 知识科普   ("无" 不显示)
+  形式:     版面设计 / 文本结构 / 文字排版 / 卡片
+  模态:     图片(固定)
+  动作:     生成(固定)
+  类型:     无(不显示)
+  后缀:     怎么做(固定)
+
+query 拼法(非空部分空格连):AI [实质] [形式] 图片 生成 怎么做
+
+两步:
+  python info_graphic_job.py create   → 给 20 条建占位 form_A.json(出现在「已检索 Query 列表」,0 帖)
+  python info_graphic_job.py search   → 批量搜索+评估这 20 条(渠道 xhs,gzh),覆盖占位
+"""
+import json
+import subprocess
+import sys
+import os
+from concurrent.futures import ThreadPoolExecutor, as_completed
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent       # query_jobs/
+MP = HERE.parent                             # mode_procedure/
+SE = MP.parent                               # search_eval/(search_and_evaluate.py 在这)
+RUNS_DIR = MP / "runs_new"
+SEARCH_EVAL = SE / "search_and_evaluate.py"
+
+PROJECT_ROOT = Path(__file__).resolve().parents[6]   # …/Agent(补评估要 import agent/examples)
+sys.path.insert(0, str(PROJECT_ROOT))
+from dotenv import load_dotenv
+load_dotenv()
+
+# ── 维度 ──────────────────────────────────────────────────────────────────────
+TOOL = "AI"
+SUBSTANCE = ["", "信息", "内容呈现", "知识", "知识科普"]   # "" = 无(不显示)
+FORM = ["版面设计", "文本结构", "文字排版", "卡片"]
+MODALITY = "图片"
+ACTION = "生成"
+SUFFIX = "怎么做"
+PLATFORMS = "xhs,gzh"   # 小红书, 公众号
+MAX_COUNT = 10          # 每个渠道搜 10 条
+
+
+def build_queries():
+    """实质 × 形式 → 20 条 query 字符串。"""
+    out = []
+    for sub in SUBSTANCE:
+        for form in FORM:
+            parts = [TOOL, sub, form, MODALITY, ACTION, SUFFIX]   # 类型=无 不入列
+            q = " ".join(p for p in parts if p)
+            out.append(q)
+    return out
+
+
+def cmd_create():
+    """给每条 query 建占位 form_A.json(0 帖),让它们出现在「已检索 Query 列表」。"""
+    qs = build_queries()
+    for q in qs:
+        d = RUNS_DIR / q
+        d.mkdir(parents=True, exist_ok=True)
+        fa = d / "form_A.json"
+        if fa.is_file():
+            try:
+                ex = json.loads(fa.read_text(encoding="utf-8"))
+                if ex.get("results"):
+                    print(f"  ⏭️  已有数据,跳过占位: {q}")
+                    continue
+            except Exception:
+                pass
+        fa.write_text(json.dumps({
+            "form": "A", "query": q, "original_q": q,
+            "platforms": [], "total": 0, "results": [], "_placeholder": True,
+        }, ensure_ascii=False, indent=2), encoding="utf-8")
+        print(f"  ✅ 占位: {q}")
+    print(f"\n共 {len(qs)} 条 query 占位完成 → 刷新「已检索 Query 列表」即可看到")
+
+
+def _search_one(q, keyword=None):
+    """对单条 query 跑 search_and_evaluate.py → 写 form_A.json(复刻 server run_search_eval_task)。
+    keyword 非空时用它当实际搜索词(词组太窄搜不到时换宽词),但 form_A.json 的 query 名仍是 q。"""
+    out_dir = RUNS_DIR / q
+    out_dir.mkdir(parents=True, exist_ok=True)
+    qf = out_dir / "temp_queries.json"
+    qf.write_text(json.dumps([keyword or q], ensure_ascii=False), encoding="utf-8")
+    log = out_dir / "_search_eval.log"
+    env = {**os.environ, "PYTHONIOENCODING": "utf-8", "PYTHONUTF8": "1"}
+    cmd = [sys.executable, "-u", str(SEARCH_EVAL), "--queries", str(qf),
+           "--platforms", PLATFORMS, "--output-dir", str(out_dir), "--max-count", str(MAX_COUNT)]
+    try:
+        with open(log, "w", encoding="utf-8") as lf:
+            r = subprocess.run(cmd, stdout=lf, stderr=subprocess.STDOUT, cwd=str(SE), env=env)
+        if r.returncode != 0:
+            return (q, f"search exit {r.returncode}")
+        ev = out_dir / "evaluated.json"
+        if not ev.is_file():
+            return (q, "no evaluated.json")
+        data = json.loads(ev.read_text(encoding="utf-8"))
+        data["form"] = "A"; data["query"] = q; data["original_q"] = q
+        (out_dir / "form_A.json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
+        return (q, f"ok · {data.get('total', '?')} 帖")
+    except Exception as ex:
+        return (q, f"error: {ex}")
+    finally:
+        try: qf.unlink()
+        except Exception: pass
+
+
+def _is_done(q):
+    """该 query 是否已有真实数据(非占位)。"""
+    fa = RUNS_DIR / q / "form_A.json"
+    try:
+        return not json.loads(fa.read_text(encoding="utf-8")).get("_placeholder")
+    except Exception:
+        return False
+
+
+def cmd_search(workers=2, force=False):
+    """默认跳过已完成的 query(断点续跑只补剩下的);--force 全部重跑。"""
+    qs = [q for q in build_queries() if force or not _is_done(q)]
+    skipped = 20 - len(qs)
+    if skipped:
+        print(f"⏭️  跳过 {skipped} 条已完成(--force 可强制重跑)")
+    if not qs:
+        print("✅ 全部已完成,无需搜索"); return
+    print(f"🔎 批量搜索+评估 {len(qs)} 条 · 渠道 {PLATFORMS} · 每渠道 {MAX_COUNT} 帖 · 并发 {workers}\n")
+    ok = fail = 0
+    with ThreadPoolExecutor(max_workers=workers) as ex:
+        futs = {ex.submit(_search_one, q): q for q in qs}
+        for i, fut in enumerate(as_completed(futs), 1):
+            q, msg = fut.result()
+            mark = "✅" if msg.startswith("ok") else "❌"
+            ok += mark == "✅"; fail += mark == "❌"
+            print(f"[{i}/{len(qs)}] {mark} {q} — {msg}")
+    print(f"\n🎉 完成:成功 {ok} · 失败 {fail} / {len(qs)}")
+
+
+async def _reeval_one(q):
+    """补评估:只重评该 query 里评估失败/未评的帖子,写回 form_A.json(不重搜)。"""
+    from examples.process_pipeline.script.search_eval.search_and_evaluate import evaluate_posts
+    from examples.process_pipeline.script.llm_evaluate_sources import build_eval_llm_call
+    fa = RUNS_DIR / q / "form_A.json"
+    try:
+        d = json.loads(fa.read_text(encoding="utf-8"))
+    except Exception:
+        return (q, "no form_A.json")
+    if d.get("_placeholder"):
+        return (q, "未搜索")
+    results = d.get("results", [])
+    failed = [r for r in results if (not r.get("llm_evaluation")) or (r.get("llm_evaluation") or {}).get("_error")]
+    if not failed:
+        return (q, "ok")
+    # 过滤视觉模型不支持的图(SVG 会让请求 400)。mmbiz 的格式在路径里(mmbiz_svg)
+    for r in failed:
+        post = r.get("post") or {}
+        imgs = post.get("images") or []
+        clean = [u for u in imgs if isinstance(u, str) and "_svg" not in u.lower() and not u.lower().endswith(".svg")]
+        if len(clean) != len(imgs):
+            post["images"] = clean
+    eval_llm, model = build_eval_llm_call("gemini-flash-lite")
+    await evaluate_posts(failed, requirement=q, llm_call=eval_llm, model=model,
+                         max_concurrent=4, include_images=True, max_images=4, image_mode="url", query=q)
+    for s in failed:
+        s.pop("_image_data_urls", None)   # 别把 base64 写进文件
+    fa.write_text(json.dumps(d, ensure_ascii=False, indent=2), encoding="utf-8")
+    still = sum(1 for r in failed if (r.get("llm_evaluation") or {}).get("_error"))
+    return (q, f"补评 {len(failed)} 帖,仍失败 {still}")
+
+
+def cmd_reeval():
+    """对所有已搜索 query 补评估失败/未评的帖子(不重搜)。"""
+    import asyncio
+    qs = [q for q in build_queries() if _is_done(q)]
+    print(f"🔁 补评估:检查 {len(qs)} 条已搜索 query")
+    fixed = 0
+    for q in qs:
+        _, msg = asyncio.run(_reeval_one(q))
+        if msg != "ok":
+            print(f"  🔧 {q} — {msg}"); fixed += 1
+    print(f"✅ 补评估完成(处理 {fixed} 条有失败帖的 query)")
+
+
+def cmd_run(workers=2):
+    """完整执行:搜剩余未搜的 query(10/渠道)+ 补所有失败的评估。"""
+    cmd_search(workers)
+    print()
+    cmd_reeval()
+
+
+if __name__ == "__main__":
+    cmd = sys.argv[1] if len(sys.argv) > 1 else "list"
+    if cmd == "create":
+        cmd_create()
+    elif cmd == "search":
+        force = "--force" in sys.argv
+        nums = [a for a in sys.argv[2:] if a.isdigit()]
+        w = int(nums[0]) if nums else 2
+        cmd_search(w, force=force)
+    elif cmd == "search-one":
+        # python info_graphic_job.py search-one "<query 显示名>" "<实际搜索关键词>"
+        qname, kw = sys.argv[2], sys.argv[3]
+        print(f"🔎 用关键词「{kw}」搜,存到 query「{qname}」")
+        print("  ", _search_one(qname, keyword=kw))
+    elif cmd == "reeval":
+        cmd_reeval()
+    elif cmd == "run":
+        nums = [a for a in sys.argv[2:] if a.isdigit()]
+        cmd_run(int(nums[0]) if nums else 2)
+    else:
+        for i, q in enumerate(build_queries(), 1):
+            print(f"{i:2d}. {q}")

+ 1447 - 0
examples/process_pipeline/script/search_eval/mode_procedure/server.py

@@ -0,0 +1,1447 @@
+# -*- coding: utf-8 -*-
+"""搜索评估案例查看 server。
+沿用 图文排版搜索评估.html 的版式(卡片 + dialog 详情 + rubric 评分条),
+数据实时扫描 runs_full/*/form_*.json —— runs_full 下每新增一个 q 文件夹,刷新即出现。
+分页:query → 三种形式(A/B/C) → 三个渠道 三行从上到下。
+
+用法:python server.py [port]   默认 8770,浏览器开 http://0.0.0.0:8770
+"""
+import json, re, glob, sys, pathlib, subprocess, threading
+from datetime import datetime
+from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
+from urllib.parse import urlparse, parse_qs
+
+try:  # Windows 控制台默认 cp1252,中文 print 会崩,统一切 utf-8
+    sys.stdout.reconfigure(encoding="utf-8")
+except Exception:
+    pass
+
+HERE = pathlib.Path(__file__).parent
+SE = HERE.parent                       # search_eval:引擎脚本/procedure-dsl/evaluation 都在父目录
+sys.path.insert(0, str(HERE))
+sys.path.insert(0, str(SE))            # 复用兄弟模块 batch_extract_procedures / build_workflows
+
+import argparse
+_parser = argparse.ArgumentParser(description="工序解构 server (mode_procedure:写死 new 模式 + procedure 直写版)")
+_parser.add_argument("port", type=int, nargs="?", default=8771, help="运行端口(默认 8771)")
+_parser.add_argument("--mode", choices=["legacy", "new"], default="new", help="(mode_procedure 固定 new)")
+_args, _ = _parser.parse_known_args()
+
+PORT = _args.port
+MODE = "new"                           # mode_procedure 写死 new 模式
+RUNS_DIR_NAME = "runs_new"
+RUNS_DIR = HERE / RUNS_DIR_NAME        # 产出目录在本文件夹 mode_procedure/runs_new
+
+PLAT = {"xhs": "小红书", "gzh": "公众号", "zhihu": "知乎", "x": "X", "bili": "B站", "douyin": "抖音",
+        "sph": "视频号", "youtube": "YouTube", "github": "GitHub", "toutiao": "头条", "weibo": "微博"}
+KT = {"procedure": "工序", "step": "步骤", "tool": "工具"}
+
+# 从 taxonomy 取动作叶子/类型名,用于把 original_q 解析回原始维度(动作×类型 正交)
+# 路径优先级:search_eval/evaluation/(主源,IDE 编辑那份就是 runtime 实际读的)
+# → test_script/evaluation/(历史副本兜底)→ script/evaluation/(更老兜底)
+# 谁也找不到时整目录扫空,server 仍能起。
+EVALDIR = HERE / "evaluation"
+if not EVALDIR.exists():
+    EVALDIR = HERE.parent.parent / "test_script" / "evaluation"
+if not EVALDIR.exists():
+    EVALDIR = HERE.parent / "evaluation"
+try:
+    _jm = json.load(open(EVALDIR / "judged_matrix.json", encoding="utf-8"))
+    ACT_L1 = {a["name"]: a["l1"] for a in _jm["actions"]}
+    ACTION_SET = set(ACT_L1)
+    TYPE_SET = {t["name"] for t in _jm["types"]}
+    ACTIONS_TAX = [{"name": a["name"], "l1": a["l1"], "l2": a.get("l2", "")} for a in _jm["actions"]]
+    TYPES_TAX = [{"name": t["name"], "l1": t["l1"]} for t in _jm["types"]]
+    # taxonomy 顺序沿用 judged_matrix(严格版);矩阵分值改用 type_action_scores(宽松版) —
+    # 两份是同一组 27×50 cell 的独立 gemini judging,前者只 53 格到 tier3,后者 156 格到 score3
+    _tas = json.load(open(EVALDIR / "type_action_scores.json", encoding="utf-8"))["scores"]
+    _MATRIX = []
+    for a in _jm["actions"]:
+        row = []
+        for t in _jm["types"]:
+            rec = _tas.get(t["name"], {}).get(a["name"])
+            row.append({"tier": rec["score"], "r": rec.get("reason", "")} if rec else {})
+        _MATRIX.append(row)
+except Exception:
+    ACT_L1, ACTION_SET, TYPE_SET, ACTIONS_TAX, TYPES_TAX, _MATRIX = {}, set(), set(), [], [], []
+
+ACTIVE_TASKS = {}
+ACTIVE_REEVALS = {}
+ACTIVE_SEARCH_EVALS = {}
+ACTIVE_BATCH_TASKS = {}
+
+def _gen_version() -> str:
+    """生成版本号 v_月日时分。"""
+    return "v_" + datetime.now().strftime("%m%d%H%M")
+
+
+def _read_meta_version(out_dir: pathlib.Path):
+    """读 out_dir/_meta.json 里的版本号(用于把旧产物归档到 history/{旧版本}/)。"""
+    try:
+        meta = json.loads((out_dir / "_meta.json").read_text(encoding="utf-8"))
+        return meta.get("version")
+    except Exception:
+        return None
+
+
+def _stamp_version(out_dir: pathlib.Path, version: str):
+    """把版本号写进 out_dir/_meta.json(_write_meta 之后调用)。"""
+    meta_path = out_dir / "_meta.json"
+    try:
+        meta = json.loads(meta_path.read_text(encoding="utf-8")) if meta_path.is_file() else {}
+    except Exception:
+        meta = {}
+    meta["version"] = version
+    try:
+        meta_path.write_text(json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8")
+    except Exception:
+        pass
+
+
+def _store_dsl(table: str, q: str, case_id: str, version: str, model: str, out_dir: pathlib.Path):
+    """把刚生成的 workflow.json 写入数据库(agent_dsl / mode_dsl)。失败不阻断。"""
+    try:
+        import db
+        wf = json.loads((out_dir / "workflow.json").read_text(encoding="utf-8"))
+        src = None
+        sp = out_dir / "_source.json"
+        if sp.is_file():
+            try:
+                src = json.loads(sp.read_text(encoding="utf-8"))
+            except Exception:
+                src = None
+        platform = case_id.split("_")[0] if "_" in case_id else None
+        db.upsert_dsl(table, q, case_id, version, model, wf, source=src,
+                      platform=platform,
+                      post_title=(src or {}).get("title"),
+                      source_link=(src or {}).get("link"))
+    except Exception as ex:
+        print(f"[db] _store_dsl({table}) 失败(不阻断):{ex}")
+
+
+def backup_procedure_history(out_dir: pathlib.Path):
+    if not out_dir.is_dir():
+        return
+    files_to_backup = [f for f in out_dir.iterdir() if f.is_file()]
+    if not files_to_backup:
+        return
+    history_dir = out_dir / "history"
+    # 按旧产物的版本号归档(v_MMDDHHMM);无版本号(历史遗留)回退时间戳
+    label = _read_meta_version(out_dir) or datetime.now().strftime("%Y%m%d_%H%M%S")
+    version_dir = history_dir / label
+    version_dir.mkdir(parents=True, exist_ok=True)
+    import shutil
+    for f in files_to_backup:
+        try:
+            shutil.move(str(f), str(version_dir / f.name))
+        except Exception as e:
+            print(f"[backup] failed to move procedure file {f.name}: {e}")
+
+def backup_reeval_history(q_dir: pathlib.Path):
+    if not q_dir.is_dir():
+        return
+    files_to_backup = list(q_dir.glob("form_*.json"))
+    if not files_to_backup:
+        return
+    history_dir = q_dir / "history"
+    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+    version_dir = history_dir / timestamp
+    version_dir.mkdir(parents=True, exist_ok=True)
+    import shutil
+    for f in files_to_backup:
+        try:
+            shutil.copy(str(f), str(version_dir / f.name))
+        except Exception as e:
+            print(f"[backup] failed to copy reeval file {f.name}: {e}")
+
+from batch_extract_procedures import _short_case, _source_to_dsl_input, _write_meta, _composite_score
+
+
+def _backend_note(model, engine="cyber_runner"):
+    """根据引擎/模型判断计费后端,明确扣 OpenRouter 余额还是 Claude 订阅。"""
+    if engine and engine != "cyber_runner":
+        return "Claude SDK / OAuth(扣 Claude 订阅额度)"
+    if "qwen" in (model or "").lower():
+        return "Qwen 原生(阿里云,不走 OpenRouter)"
+    return "OpenRouter(扣 OpenRouter 余额,非 Claude 订阅)"
+
+def _log_header(log_fh, title, model, engine="cyber_runner"):
+    """在子进程日志开头写一行:本次用什么模型、走什么后端。"""
+    line = f"[server] {title} · 模型 {model} · 后端 {_backend_note(model, engine)}\n"
+    log_fh.write(line); log_fh.write("-" * 60 + "\n"); log_fh.flush()
+
+
+def run_model_extraction_task(q, folder_name, case_id, src_path, out_dir, model, version):
+    """模型提取:跑 procedure_model_extract.py(单次大模型直出 workflow.json + 渲染)。
+    产物写 procedures/{folder}/_model/ 子目录,task_key 带 /_model 后缀,与 Agent 工序分开。"""
+    task_key = f"{q}/{folder_name}/_model"
+    log_path = out_dir / "_extract.log"
+    try:
+        out_dir.mkdir(parents=True, exist_ok=True)
+        cmd = [sys.executable, "-u", str(HERE / "mode-dsl" / "procedure_model_extract.py"),
+               str(src_path), "--out-dir", str(out_dir), "--model", model, "--case-id", folder_name]
+        flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
+        with open(log_path, "w", encoding="utf-8", buffering=1) as log_fh:
+            _log_header(log_fh, "🤖 工序提取(模型直出,无 agent/validate 循环)", model, "cyber_runner")
+            proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
+                                    cwd=str(HERE), creationflags=flags)
+            ACTIVE_TASKS[task_key]["pid"] = proc.pid
+            proc.wait()
+            if proc.returncode == 0:
+                # 模型工序独立展示在「大模型工序」子 tab(按 _model/*.html 检测),不进 gallery 合并
+                _stamp_version(out_dir, version)
+                _store_dsl("mode_dsl", q, case_id, version, model, out_dir)   # 写库
+                ACTIVE_TASKS[task_key]["status"] = "success"
+            else:
+                ACTIVE_TASKS[task_key]["status"] = "failed"
+                ACTIVE_TASKS[task_key]["error"] = f"model extract exit code {proc.returncode}"
+    except Exception as e:
+        ACTIVE_TASKS[task_key]["status"] = "failed"
+        ACTIVE_TASKS[task_key]["error"] = str(e)
+        try:
+            with open(log_path, "a", encoding="utf-8") as f_err:
+                f_err.write(f"\n[server error] model extract failed: {e}\n")
+        except Exception:
+            pass
+
+
+def run_extraction_task(q, folder_name, case_id, src_path, out_dir, engine, model, version):
+    task_key = f"{q}/{folder_name}"
+    log_path = out_dir / "_extract.log"
+    try:
+        out_dir.mkdir(parents=True, exist_ok=True)
+        if engine == "cyber_runner":
+            script_path = HERE / "procedure-dsl" / "run_cyber.py"
+        else:
+            script_path = HERE / "procedure-dsl" / "run_procedure_dsl.py"
+            
+        cmd = [
+            sys.executable, "-u", str(script_path),
+            str(src_path),
+            "--out-dir", str(out_dir),
+            "--model", model,
+            "--max-turns", "300"
+        ]
+        if engine != "cyber_runner":
+            cmd.extend(["--max-retries", "3"])
+        else:
+            cmd.extend(["--skill", "procedure"])   # mode_procedure:run_cyber 用直写版 skill
+
+        flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
+        with open(log_path, "w", encoding="utf-8", buffering=1) as log_fh:
+            _log_header(log_fh, "🔧 工序提取(单帖)", model, engine)
+            proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
+                                    cwd=str(HERE / "procedure-dsl"), creationflags=flags)   # cwd=本地 procedure-dsl(run_cyber 假设的工作目录,agent 相对路径才对)
+            ACTIVE_TASKS[task_key]["pid"] = proc.pid
+            proc.wait()
+            
+            if proc.returncode == 0:
+                try:
+                    import build_workflows
+                    build_workflows.write_one(q, folder_name, runs_dir=RUNS_DIR)
+                    _stamp_version(out_dir, version)
+                    _store_dsl("agent_dsl", q, case_id, version, model, out_dir)   # 写库
+                    ACTIVE_TASKS[task_key]["status"] = "success"
+                except Exception as ex:
+                    ACTIVE_TASKS[task_key]["status"] = "failed"
+                    ACTIVE_TASKS[task_key]["error"] = f"Workflow compilation failed: {ex}"
+                    with open(log_path, "a", encoding="utf-8") as f_err:
+                        f_err.write(f"\n[server error] Workflow compilation failed: {ex}\n")
+            else:
+                ACTIVE_TASKS[task_key]["status"] = "failed"
+                ACTIVE_TASKS[task_key]["error"] = f"Runner failed with exit code {proc.returncode}"
+    except Exception as e:
+        ACTIVE_TASKS[task_key]["status"] = "failed"
+        ACTIVE_TASKS[task_key]["error"] = str(e)
+        try:
+            with open(log_path, "a", encoding="utf-8") as f_err:
+                f_err.write(f"\n[server error] Extraction failed: {e}\n")
+        except Exception:
+            pass
+
+MODSET = {"文", "图", "视频", "音频"}
+TOOLQUAL = {"AI": "AI 模型", "软件": "桌面 APP", "电脑端": "桌面 APP", "在线": "云端 Web",
+            "网页版": "云端 Web", "代码": "API·CLI", "命令行": "API·CLI", "插件": "插件扩展"}
+
+def parse_dims(oq):
+    """把组合 query(如 '文 元素生成 提示词 教程')解析回 {动作, 类型, 动作L1, 约束}。"""
+    toks = (oq or "").split()
+    action = next((t for t in toks if t in ACTION_SET), None)
+    type_ = next((t for t in toks if t in TYPE_SET), None)
+    cons = None
+    if toks:
+        t0 = toks[0]
+        if t0 in MODSET:
+            cons = {"kind": "模态", "value": t0}
+        elif t0 in TOOLQUAL:
+            cons = {"kind": "工具类型", "value": TOOLQUAL[t0]}
+    return {"action": action, "type": type_, "action_l1": ACT_L1.get(action, ""), "constraint": cons}
+
+def flat_scores(sc):
+    f = {}
+    for k, v in (sc or {}).items():
+        if isinstance(v, dict):
+            for kk, vv in v.items():
+                try: f[kk] = int(vv)
+                except Exception: pass
+        else:
+            try: f[k] = int(v)
+            except Exception: pass
+    return f
+
+def _recency_hard(date_str):
+    """按 publish_timestamp 头 10 字符(YYYY-MM-DD)算硬时效:半年内=3 / 两年内=2 / 更早=1。
+
+    取代原 LLM 评的 recency 维度——脚本算更稳,发布时间在帖子抓取时就有,无需 LLM token。
+    """
+    try:
+        d = datetime.strptime((date_str or "")[:10], "%Y-%m-%d")
+    except (ValueError, TypeError):
+        return None
+    days = (datetime.now() - d).days
+    if days <= 180: return 3
+    if days <= 730: return 2
+    return 1
+
+
+def adapt(r, run, form_name=None):
+    p = r.get("post", {}); e = r.get("llm_evaluation", {})
+    
+    # 1. 解析 知识类型 (knowledge_type)
+    kt = []
+    kt_raw = e.get("知识类型") or e.get("knowledge_type") or []
+    for k in kt_raw:
+        if k in ("工序", "procedure"): kt.append("procedure")
+        elif k in ("能力", "步骤", "step"): kt.append("step")
+        elif k in ("工具", "tool"): kt.append("tool")
+
+    fs = {}
+    score_reasons = {}
+
+    # 检测是否为 eval_prompt_sample-mod 里的新版 0-10 分数 schema
+    is_mod_schema = "相关性" in e and isinstance(e["相关性"], dict) and ("和内容制作知识相关" in e["相关性"] or "和 query 相关" in e["相关性"])
+
+    if is_mod_schema:
+        # 新版 0-10 分数格式解析
+        # 1. 相关性
+        rel = e.get("相关性") or {}
+        for subkey, item in rel.items():
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                code_key = None
+                if "内容制作" in subkey or "知识" in subkey:
+                    code_key = "relevance_production"
+                elif "query" in subkey or "检索" in subkey:
+                    code_key = "relevance_query"
+                if code_key and score_val is not None:
+                    try:
+                        fs[code_key] = float(score_val)
+                        if reason_val:
+                            score_reasons[code_key] = reason_val
+                    except Exception:
+                        pass
+
+        # 2. 质量
+        q_block = e.get("质量") or {}
+        fixed = q_block.get("固定维度") or {}
+        
+        # 固定维度
+        fixed_keys = {
+            "时效性": "recency",
+            "热度性": "popularity",
+            "评论反馈": "feedback"
+        }
+        for cn, code in fixed_keys.items():
+            item = fixed.get(cn)
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                if score_val is not None:
+                    try:
+                        fs[code] = float(score_val)
+                        if reason_val:
+                            score_reasons[code] = reason_val
+                    except Exception:
+                        pass
+                        
+        # 用例 (真实感, 表现力)
+        usecase = fixed.get("用例") or {}
+        usecase_keys = {
+            "真实感": "realism",
+            "表现力": "expressiveness"
+        }
+        for cn, code in usecase_keys.items():
+            item = usecase.get(cn)
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                if score_val is not None:
+                    try:
+                        fs[code] = float(score_val)
+                        if reason_val:
+                            score_reasons[code] = reason_val
+                    except Exception:
+                        pass
+
+        # 动态维度
+        dynamic = q_block.get("动态维度") or {}
+        
+        # 工序
+        proc = dynamic.get("工序") or {}
+        if proc:
+            item = proc.get("流程完整性")
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                if score_val is not None:
+                    try:
+                        fs["procedure_completeness"] = float(score_val)
+                        if reason_val:
+                            score_reasons["procedure_completeness"] = reason_val
+                    except Exception:
+                        pass
+            field = proc.get("字段完整性") or {}
+            field_keys = {
+                "输入完整性": "procedure_input",
+                "实现完整性": "procedure_implementation",
+                "输出完整性": "procedure_output"
+            }
+            for cn, code in field_keys.items():
+                item = field.get(cn)
+                if isinstance(item, dict):
+                    score_val = item.get("得分")
+                    reason_val = item.get("理由")
+                    if score_val is not None:
+                        try:
+                            fs[code] = float(score_val)
+                            if reason_val:
+                                score_reasons[code] = reason_val
+                        except Exception:
+                            pass
+            item = proc.get("泛化性")
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                if score_val is not None:
+                    try:
+                        fs["procedure_generality"] = float(score_val)
+                        if reason_val:
+                            score_reasons["procedure_generality"] = reason_val
+                    except Exception:
+                        pass
+
+        # 能力
+        cap = dynamic.get("能力") or dynamic.get("步骤") or {}
+        if cap:
+            field = cap.get("字段完整性") or {}
+            field_keys = {
+                "输入完整性": "step_input",
+                "实现完整性": "step_implementation",
+                "输出完整性": "step_output"
+            }
+            for cn, code in field_keys.items():
+                item = field.get(cn)
+                if isinstance(item, dict):
+                    score_val = item.get("得分")
+                    reason_val = item.get("理由")
+                    if score_val is not None:
+                        try:
+                            fs[code] = float(score_val)
+                            if reason_val:
+                                score_reasons[code] = reason_val
+                        except Exception:
+                            pass
+            item = cap.get("泛化性")
+            if isinstance(item, dict):
+                score_val = item.get("得分")
+                reason_val = item.get("理由")
+                if score_val is not None:
+                    try:
+                        fs["step_generality"] = float(score_val)
+                        if reason_val:
+                            score_reasons["step_generality"] = reason_val
+                    except Exception:
+                        pass
+
+        # 工具
+        tool = dynamic.get("工具") or {}
+        if tool:
+            tool_keys = {
+                "能力边界覆盖": "tool_boundary",
+                "有效比较": "tool_comparison",
+                "参数/接口具体性": "tool_specificity",
+                "实操示例": "tool_example",
+                "版本&限制": "tool_limits"
+            }
+            for cn, code in tool_keys.items():
+                item = tool.get(cn)
+                if isinstance(item, dict):
+                    score_val = item.get("得分")
+                    reason_val = item.get("理由")
+                    if score_val is not None:
+                        try:
+                            fs[code] = float(score_val)
+                            if reason_val:
+                                score_reasons[code] = reason_val
+                        except Exception:
+                            pass
+
+    else:
+        # 兼容老版 1-5 分数 schema (带 "评分" 或 old-style flatness)
+        is_new_schema = "评分" in e or "知识类型" in e or "制作相关性" in e
+        CN_TO_EN = {
+            "相关性": "relevance",
+            "成品质量": "result_quality",
+            "可信度": "credibility",
+            "具体用例": "concrete_use_case",
+            "完整性": "completeness",
+            "步骤结构": "step_structure",
+            "步骤可复现": "step_reproducibility",
+            "步骤可复现性": "step_reproducibility",
+            "能力定义": "capability_definition",
+            "实现深度": "implementation_depth",
+            "边界失败": "boundary_failure_eval",
+            "通用性": "generality",
+            "能力覆盖": "capability_coverage",
+            "有效对比": "effective_comparison",
+            "参数具体": "param_specificity",
+            "实操示例": "worked_example",
+            "实操用例": "worked_example",
+            "示例完整": "worked_example",
+            "版本限制": "version_limits",
+            "版本说明": "version_limits",
+            "限制说明": "version_limits",
+        }
+        
+        if is_new_schema:
+            pf = e.get("评分") or {}
+            for cat, metrics in pf.items():
+                if isinstance(metrics, dict):
+                    for metric, val in metrics.items():
+                        en_key = CN_TO_EN.get(metric, metric)
+                        if isinstance(val, dict) and "得分" in val:
+                            try: fs[en_key] = int(val["得分"])
+                            except Exception: pass
+                        elif isinstance(val, (int, float)):
+                            fs[en_key] = int(val)
+                        
+                        if isinstance(val, dict) and "理由" in val:
+                            score_reasons[en_key] = val["理由"]
+        else:
+            fs = flat_scores(e.get("scores", {}))
+        
+    # 计算均分 (overall)
+    if is_mod_schema:
+        rel_keys = {"relevance_production", "relevance_query"}
+        rel_vals = [v for k, v in fs.items() if k in rel_keys]
+        qual_vals = [v for k, v in fs.items() if k not in rel_keys]
+        
+        rel_avg = sum(rel_vals) / len(rel_vals) if rel_vals else None
+        qual_avg = sum(qual_vals) / len(qual_vals) if qual_vals else None
+        
+        if rel_avg is not None and qual_avg is not None:
+            overall = round((rel_avg + qual_avg) / 2, 1)
+        elif rel_avg is not None:
+            overall = round(rel_avg, 1)
+        elif qual_avg is not None:
+            overall = round(qual_avg, 1)
+        else:
+            overall = 0.0
+    else:
+        overall = round(sum(fs.values()) / len(fs), 1) if fs else 0
+    anomaly = bool(e.get("error")) or not fs
+    grade = p.get("_quality_grade", "")
+    fb = r.get("found_by_queries", [])
+    
+    # 4. 解析 制作相关性 (production_relevance)
+    if is_mod_schema:
+        # 新版使用 "相关性" 中的 "和内容制作知识相关" 代表制作相关性
+        production_relevance = fs.get("relevance_production")
+    else:
+        if is_new_schema:
+            pr_block = e.get("制作相关性") or {}
+            pr_raw = pr_block.get("得分") if isinstance(pr_block, dict) else pr_block
+            if isinstance(pr_block, dict) and "理由" in pr_block:
+                score_reasons["production_relevance"] = pr_block["理由"]
+        else:
+            pr_raw = e.get("production_relevance")
+            
+        try: production_relevance = int(float(pr_raw)) if pr_raw is not None else None
+        except (TypeError, ValueError): production_relevance = None
+    
+    recency_hard = _recency_hard(p.get("publish_timestamp", ""))
+    
+    # 5. 解析 判定决策 (decision) 和 理由 (reason)
+    reason = e.get("判定理由") or e.get("reason") or ""
+    
+    # 根据过滤指标决定是否保留 (过滤指标判定逻辑优先,不依赖文字匹配)
+    is_discard = False
+    
+    # 制作相关性低于阈值则丢弃 (新版 0-10 满分,因此低于 4 丢弃;老版低于 2 丢弃)
+    if production_relevance is not None:
+        threshold = 4 if is_mod_schema else 2
+        if production_relevance < threshold:
+            is_discard = True
+            
+    # 时效性低于 2 被丢弃(发布时间超两年的老帖)
+    if recency_hard is not None and recency_hard < 2:
+        is_discard = True
+        
+    # 综合均分低于阈值被丢弃 (新版低于 6 丢弃;老版低于 3 丢弃)
+    if overall is not None:
+        threshold_ov = 6 if is_mod_schema else 3
+        if overall < threshold_ov:
+            is_discard = True
+        
+    decision = "discard" if is_discard else "report"
+
+    # Find matching procedure html
+    procedure_html = None
+    case_id = r.get("case_id", "")
+    title = p.get("title", "")
+    run_dir = RUNS_DIR / run
+
+    if run_dir.is_dir():
+        # 1. 优先扫描该帖子对应的文件夹下的任何 HTML 文件 (不限名称)
+        # 文件夹名格式: {form}_{platform}_{channel_content_id[:8]}
+        content_id = r.get("channel_content_id") or ""
+        if not content_id and case_id and "_" in case_id:
+            content_id = case_id.split("_", 1)[1]
+        plat_key = r.get("platform") or ""
+        
+        if form_name and plat_key and content_id:
+            folder_name = f"{form_name}_{plat_key}_{content_id[:8]}"
+            case_dir = run_dir / "procedures" / folder_name
+            if case_dir.is_dir():
+                html_files = list(case_dir.glob("*.html"))
+                if html_files:
+                    procedure_html = f"runs_full/{run}/procedures/{folder_name}/{html_files[0].name}"
+
+        # 1b. 兼容 fallback: 批量提取模式下直接以 case_id 命名的文件夹
+        if not procedure_html and case_id:
+            case_dir = run_dir / "procedures" / case_id
+            if case_dir.is_dir():
+                html_files = list(case_dir.glob("*.html"))
+                if html_files:
+                    procedure_html = f"runs_full/{run}/procedures/{case_id}/{html_files[0].name}"
+
+        # 2. 其次匹配标准文件名: case-{case_id}.html 或 {case_id}.html
+        candidate_dirs = [run_dir, run_dir / "procedures"]
+        if not procedure_html and case_id:
+            named_files = [f"case-{case_id}.html", f"{case_id}.html"]
+            for d_dir in candidate_dirs:
+                if d_dir.is_dir():
+                    for name in named_files:
+                        if (d_dir / name).is_file():
+                            procedure_html = f"runs_full/{run}/procedures/{name}" if d_dir.name == "procedures" else f"runs_full/{run}/{name}"
+                            break
+                if procedure_html:
+                    break
+
+        # 3. 再次匹配 HTML 内部的标准声明 (meta 标签或 HTML 注释)
+        if not procedure_html and case_id:
+            for d_dir in candidate_dirs:
+                if d_dir.is_dir():
+                    for html_path in d_dir.glob("*.html"):
+                        try:
+                            content = html_path.read_text(encoding="utf-8")
+                            if f'name="case-id" content="{case_id}"' in content or \
+                               f'name="case_id" content="{case_id}"' in content or \
+                               f'<!-- case_id: {case_id} -->' in content or \
+                               f'<!-- case-id: {case_id} -->' in content:
+                                procedure_html = f"runs_full/{run}/procedures/{html_path.name}" if d_dir.name == "procedures" else f"runs_full/{run}/{html_path.name}"
+                                break
+                        except Exception:
+                            continue
+                if procedure_html:
+                    break
+
+        # 4. 最后使用标题作为兜底模糊匹配
+        if not procedure_html and title:
+            for d_dir in candidate_dirs:
+                if d_dir.is_dir():
+                    for html_path in d_dir.glob("*.html"):
+                        try:
+                            content = html_path.read_text(encoding="utf-8")
+                            if title in content:
+                                procedure_html = f"runs_full/{run}/procedures/{html_path.name}" if d_dir.name == "procedures" else f"runs_full/{run}/{html_path.name}"
+                                break
+                        except Exception:
+                            continue
+                if procedure_html:
+                    break
+
+    if procedure_html:
+        procedure_html = procedure_html.replace("runs_full/", f"{RUNS_DIR_NAME}/")
+
+    return {
+        "case_id": r.get("case_id", ""),
+        "platform": PLAT.get(r.get("platform"), r.get("platform")), "platformKey": r.get("platform"),
+        "title": p.get("title", "") or "(无标题)", "date": (p.get("publish_timestamp", "") or "")[:10],
+        "url": r.get("source_url", ""), "engagement": f'{p.get("like_count", 0)} 赞',
+        "knowledge_type": kt, "decision": decision,
+        "tools": [KT.get(k, k) for k in kt] + ([f"质量 {grade}"] if grade else []), "found_by": fb,
+        "images": (p.get("images") or [])[:6], "text": p.get("body_text", "") or "",
+        "scores": fs, "overall": overall, "reason": reason, "score_reasons": score_reasons,
+        "grade": grade, "qscore": p.get("_quality_score", 0), "anomaly": anomaly,
+        "production_relevance": production_relevance, "recency_hard": recency_hard,
+        "run": run, "procedure_html": procedure_html,
+    }
+
+def scan_runs():
+    runs = {}
+    for f in sorted(glob.glob(str(RUNS_DIR / "*" / "form_*.json"))):
+        try:
+            d = json.load(open(f, encoding="utf-8"))
+        except Exception:
+            continue
+        run = pathlib.Path(f).parent.name
+        form_name = d.get("form") or ""
+        results = [adapt(r, run, form_name) for r in d.get("results", [])]
+        report_val = sum(1 for r in results if r.get("decision") == "report" and not r.get("anomaly"))
+        discard_val = sum(1 for r in results if r.get("decision") == "discard" and not r.get("anomaly"))
+        
+        runs.setdefault(run, []).append({
+            "form": d.get("form"), "query": d.get("query"), "original_q": d.get("original_q", ""),
+            "requirement": d.get("requirement", ""),
+            "platforms": d.get("platforms", []), "total": d.get("total"),
+            "report": report_val, "discard": discard_val,
+            "results": results,
+        })
+    for v in runs.values():
+        v.sort(key=lambda x: x.get("form") or "")
+
+    if MODE == "new":
+        def _mtime(name):
+            try:
+                return (RUNS_DIR / name).stat().st_mtime
+            except Exception:
+                return 0
+        sorted_keys = sorted(runs.keys(), key=_mtime, reverse=True)
+    else:
+        def _qnum(name):
+            m = re.search(r"\d+", name)
+            return (int(m.group()) if m else 0, name)
+        sorted_keys = [kv[0] for kv in sorted(runs.items(), key=lambda kv: _qnum(kv[0]))]
+
+    out = []
+    for k in sorted_keys:
+        v = runs[k]
+        oq = v[0].get("original_q") or v[0].get("query") or ""
+        seen, hits = set(), 0   # 知识命中数 = 各形式采纳(report)且非异常、按 url 去重后的帖子数
+        for f in v:
+            for r in f.get("results", []):
+                if r.get("decision") == "report" and not r.get("anomaly") and r.get("url") not in seen:
+                    seen.add(r.get("url")); hits += 1
+        out.append({"key": k, "forms": v, "dims": parse_dims(oq), "original_q": oq,
+                    "hits": hits, "tot": sum((f.get("total") or 0) for f in v)})
+    active_reevals = {k: v["status"] for k, v in ACTIVE_REEVALS.items()}
+    active_batch_tasks = {k: v["status"] for k, v in ACTIVE_BATCH_TASKS.items()}
+    return {"queries": out, "actions": ACTIONS_TAX, "types": TYPES_TAX, "matrix": _MATRIX, "active_reevals": active_reevals, "active_batch_tasks": active_batch_tasks}
+
+class H(BaseHTTPRequestHandler):
+    def _send(self, code, body, ctype):
+        b = body.encode("utf-8") if isinstance(body, str) else body
+        self.send_response(code)
+        if ctype.startswith("text/") or ctype == "application/json" or ctype == "application/javascript":
+            self.send_header("Content-Type", ctype + "; charset=utf-8")
+        else:
+            self.send_header("Content-Type", ctype)
+        self.send_header("Content-Length", str(len(b))); self.end_headers(); self.wfile.write(b)
+    def do_GET(self):
+        parsed = urlparse(self.path)
+        path = parsed.path
+        params = parse_qs(parsed.query)
+
+        if path in ("/", "/index.html"):
+            try:
+                html_file = "new_query.html" if MODE == "new" else "index.html"
+                page = (HERE / html_file).read_text(encoding="utf-8")
+                self._send(200, page, "text/html")
+            except Exception as e:
+                self._send(500, f"Error reading page: {e}", "text/plain")
+        elif path == "/api/data":
+            self._send(200, json.dumps(scan_runs(), ensure_ascii=False), "application/json")
+        elif path == "/api/procedure_status":
+            q = (params.get("q") or [""])[0].strip()
+            form = (params.get("form") or [""])[0].strip()
+            case_id = (params.get("case_id") or [""])[0].strip()
+            
+            if not q or not form or not case_id:
+                self._send(400, "missing q, form, or case_id", "text/plain")
+                return
+                
+            variant = (params.get("variant") or ["agent"])[0].strip()
+            req_version = (params.get("version") or [""])[0].strip()
+            folder_name = f"{form}_{_short_case(case_id)}"
+            out_dir = RUNS_DIR / q / "procedures" / folder_name
+            rel_base = f"{RUNS_DIR_NAME}/{q}/procedures/{folder_name}"
+            task_key = f"{q}/{folder_name}"
+            if variant == "model":                       # 大模型工序在 _model/ 子目录
+                out_dir = out_dir / "_model"
+                rel_base = rel_base + "/_model"
+                task_key = task_key + "/_model"
+
+            # 指定了非当前版本 → 直接从 history/{version}/ 取该版本的 html
+            if req_version and req_version != _read_meta_version(out_dir):
+                hist = out_dir / "history" / req_version
+                hf = list(hist.glob("*.html")) if hist.is_dir() else []
+                if hf:
+                    self._send(200, json.dumps({"status": "success",
+                        "procedure_html": f"{rel_base}/history/{req_version}/{hf[0].name}"},
+                        ensure_ascii=False), "application/json")
+                else:
+                    self._send(200, json.dumps({"status": "not_started",
+                        "error": f"版本 {req_version} 的页面文件已不存在"}, ensure_ascii=False), "application/json")
+                return
+
+            if task_key in ACTIVE_TASKS:
+                task = ACTIVE_TASKS[task_key]
+                res = {"status": task["status"], "error": task["error"]}
+                if task["status"] == "success":
+                    html_files = list(out_dir.glob("*.html")) if out_dir.is_dir() else []
+                    if html_files:
+                        res["procedure_html"] = f"{rel_base}/{html_files[0].name}"
+                self._send(200, json.dumps(res, ensure_ascii=False), "application/json")
+                return
+
+            html_files = list(out_dir.glob("*.html")) if out_dir.is_dir() else []
+            if html_files:
+                self._send(200, json.dumps({
+                    "status": "success",
+                    "procedure_html": f"{rel_base}/{html_files[0].name}"
+                }, ensure_ascii=False), "application/json")
+                return
+            # 仅 agent 变体兼容旧的 case_id 命名目录
+            if variant != "model" and case_id:
+                fallback_dir = RUNS_DIR / q / "procedures" / case_id
+                fb_html = list(fallback_dir.glob("*.html")) if fallback_dir.is_dir() else []
+                if fb_html:
+                    self._send(200, json.dumps({
+                        "status": "success",
+                        "procedure_html": f"{RUNS_DIR_NAME}/{q}/procedures/{case_id}/{fb_html[0].name}"
+                    }, ensure_ascii=False), "application/json")
+                    return
+
+            log_path = out_dir / "_extract.log"
+            if not log_path.is_file() and variant != "model" and case_id:
+                log_path = RUNS_DIR / q / "procedures" / case_id / "_extract.log"
+            if log_path.is_file():
+                self._send(200, json.dumps({"status": "failed", "error": "Not running, but no HTML output found (possibly crashed)."}, ensure_ascii=False), "application/json")
+                return
+
+            self._send(200, json.dumps({"status": "not_started"}, ensure_ascii=False), "application/json")
+        elif path == "/api/procedure_versions":
+            # 列某帖某变体的所有版本(DB 为主,文件系统兜底)。latest = 当前 _meta 版本。
+            q = (params.get("q") or [""])[0].strip()
+            form = (params.get("form") or [""])[0].strip()
+            case_id = (params.get("case_id") or [""])[0].strip()
+            variant = (params.get("variant") or ["agent"])[0].strip()
+            folder_name = f"{form}_{_short_case(case_id)}"
+            out_dir = RUNS_DIR / q / "procedures" / folder_name
+            if variant == "model":
+                out_dir = out_dir / "_model"
+            latest = _read_meta_version(out_dir)
+            by_ver = {}
+            # DB(带 model / 工序数 / 时间)
+            try:
+                import db
+                for r in db.fetch_versions("mode_dsl" if variant == "model" else "agent_dsl", q, case_id):
+                    if r.get("version"):
+                        by_ver[r["version"]] = {"version": r["version"], "model": r.get("model"),
+                                                "procedure_count": r.get("procedure_count"),
+                                                "created_time": str(r.get("created_time") or "")}
+            except Exception:
+                pass
+            # 文件系统兜底(当前 + history/v_*)
+            for v in ([latest] if latest else []) + (
+                    [d.name for d in (out_dir / "history").iterdir()
+                     if d.is_dir() and d.name.startswith("v_")] if (out_dir / "history").is_dir() else []):
+                by_ver.setdefault(v, {"version": v, "model": None, "procedure_count": None, "created_time": ""})
+            versions = sorted(by_ver.values(), key=lambda x: x["version"], reverse=True)
+            for v in versions:
+                v["is_latest"] = (v["version"] == latest)
+            self._send(200, json.dumps({"versions": versions, "latest": latest}, ensure_ascii=False), "application/json")
+        elif path == "/api/procedure_log":
+            q = (params.get("q") or [""])[0].strip()
+            form = (params.get("form") or [""])[0].strip()
+            case_id = (params.get("case_id") or [""])[0].strip()
+            
+            if not q or not form or not case_id:
+                self._send(400, "missing q, form, or case_id", "text/plain")
+                return
+                
+            variant = (params.get("variant") or ["agent"])[0].strip()
+            folder_name = f"{form}_{_short_case(case_id)}"
+            if variant == "model":
+                log_path = RUNS_DIR / q / "procedures" / folder_name / "_model" / "_extract.log"
+            else:
+                log_path = RUNS_DIR / q / "procedures" / folder_name / "_extract.log"
+                if not log_path.is_file() and case_id:
+                    log_path = RUNS_DIR / q / "procedures" / case_id / "_extract.log"
+            
+            if not log_path.is_file():
+                self._send(200, json.dumps({"log": ""}, ensure_ascii=False), "application/json")
+                return
+                
+            try:
+                content = log_path.read_text(encoding="utf-8", errors="replace")
+                self._send(200, json.dumps({"log": content}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        elif path == "/api/spec_content":
+            file_name = (params.get("file") or [""])[0].strip()
+            allowed = [
+                "README.md",
+                "tools.md",
+                "extraction/phase1-skeleton.md",
+                "extraction/phase2-normalize.md",
+                "extraction/phase3-finalize.md",
+                "taxonomy/type_suggestions.md"
+            ]
+            if file_name not in allowed:
+                self._send(400, "invalid file parameter", "text/plain")
+                return
+            target_path = HERE / "procedure-dsl" / "spec" / file_name
+            if not target_path.is_file():
+                self._send(404, "spec file not found", "text/plain")
+                return
+            try:
+                content = target_path.read_text(encoding="utf-8", errors="replace")
+                self._send(200, json.dumps({"content": content}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        elif path == "/api/reeval_status":
+            q = (params.get("q") or [""])[0].strip()
+            if not q:
+                self._send(400, "missing q", "text/plain")
+                return
+            if q in ACTIVE_REEVALS:
+                self._send(200, json.dumps({
+                    "status": ACTIVE_REEVALS[q]["status"],
+                    "error": ACTIVE_REEVALS[q].get("error")
+                }, ensure_ascii=False), "application/json")
+            else:
+                self._send(200, json.dumps({"status": "not_started"}, ensure_ascii=False), "application/json")
+        elif path == "/api/search_eval_status":
+            q = (params.get("q") or [""])[0].strip()
+            if not q:
+                self._send(400, "missing q", "text/plain")
+                return
+            if q in ACTIVE_SEARCH_EVALS:
+                self._send(200, json.dumps({
+                    "status": ACTIVE_SEARCH_EVALS[q]["status"],
+                    "error": ACTIVE_SEARCH_EVALS[q].get("error")
+                }, ensure_ascii=False), "application/json")
+            else:
+                self._send(200, json.dumps({"status": "not_started"}, ensure_ascii=False), "application/json")
+        elif path == "/api/batch_generate_status":
+            q = (params.get("q") or [""])[0].strip()
+            if not q:
+                self._send(400, "missing q", "text/plain")
+                return
+            if q in ACTIVE_BATCH_TASKS:
+                self._send(200, json.dumps({
+                    "status": ACTIVE_BATCH_TASKS[q]["status"],
+                    "error": ACTIVE_BATCH_TASKS[q].get("error")
+                }, ensure_ascii=False), "application/json")
+            else:
+                self._send(200, json.dumps({"status": "not_started"}, ensure_ascii=False), "application/json")
+        elif path == "/api/batch_generate_log":
+            q = (params.get("q") or [""])[0].strip()
+            if not q:
+                self._send(400, "missing q", "text/plain")
+                return
+            safe_q = re.sub(r'[\x00-\x1f\\/*?:"<>|]', '', q).strip()
+            log_path = RUNS_DIR / safe_q / "procedures" / "_batch_extract.log"
+            if not log_path.is_file():
+                self._send(200, json.dumps({"log": ""}, ensure_ascii=False), "application/json")
+                return
+            try:
+                content = log_path.read_text(encoding="utf-8", errors="replace")
+                self._send(200, json.dumps({"log": content}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        elif path == "/api/search_eval_log":
+            q = (params.get("q") or [""])[0].strip()
+            if not q:
+                self._send(400, "missing q", "text/plain")
+                return
+            safe_q = re.sub(r'[\x00-\x1f\\/*?:"<>|]', '', q).strip()
+            log_path = RUNS_DIR / safe_q / "_search_eval.log"
+            if not log_path.is_file():
+                self._send(200, json.dumps({"log": ""}, ensure_ascii=False), "application/json")
+                return
+            try:
+                content = log_path.read_text(encoding="utf-8", errors="replace")
+                self._send(200, json.dumps({"log": content}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        elif self.path.startswith("/runs_full/") or self.path.startswith("/runs_new/"):
+            try:
+                import urllib.parse
+                clean_path = urllib.parse.unquote(self.path.split("?")[0])
+                parts = clean_path.strip("/").split("/")
+                target_file = HERE
+                for part in parts:
+                    target_file = target_file / part
+                runs_dir = HERE / parts[0]
+                if runs_dir.resolve() in target_file.resolve().parents and target_file.is_file():
+                    content = target_file.read_bytes()
+                    ext = target_file.suffix.lower()
+                    ctype = "text/html"
+                    if ext in (".png", ".webp"):
+                        ctype = f"image/{ext[1:]}"
+                    elif ext in (".jpg", ".jpeg"):
+                        ctype = "image/jpeg"
+                    elif ext == ".json":
+                        ctype = "application/json"
+                    elif ext == ".js":
+                        ctype = "application/javascript"
+                    elif ext == ".css":
+                        ctype = "text/css"
+                    self._send(200, content, ctype)
+                else:
+                    self._send(404, "not found", "text/plain")
+            except Exception as e:
+                self._send(500, f"Error: {e}", "text/plain")
+        else:
+            self._send(404, "not found", "text/plain")
+    def do_POST(self):
+        if self.path == "/api/run_search_eval":
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+                
+            q = (payload.get("query") or "").strip()
+            platforms = (payload.get("platforms") or "xhs,zhihu").strip()
+            
+            if not q:
+                self._send(400, json.dumps({"error": "missing query"}, ensure_ascii=False), "application/json"); return
+                
+            safe_q = re.sub(r'[\x00-\x1f\\/*?:"<>|]', '', q).strip()
+            if not safe_q:
+                self._send(400, json.dumps({"error": "invalid query name"}, ensure_ascii=False), "application/json"); return
+                
+            q_dir = RUNS_DIR / safe_q
+            q_dir.mkdir(parents=True, exist_ok=True)
+            
+            temp_queries_file = q_dir / "temp_queries.json"
+            try:
+                with open(temp_queries_file, "w", encoding="utf-8") as f:
+                    json.dump([q], f, ensure_ascii=False)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to write temp query: {e}"}), "application/json"); return
+                
+            log_path = q_dir / "_search_eval.log"
+            
+            ACTIVE_SEARCH_EVALS[q] = {
+                "status": "running",
+                "pid": None,
+                "error": None
+            }
+            
+            def run_search_eval_task(query_text, safe_query_name, queries_file, out_dir, target_platforms, log_file):
+                try:
+                    cmd = [
+                        sys.executable, "-u", str(SE / "search_and_evaluate.py"),
+                        "--queries", str(queries_file),
+                        "--platforms", target_platforms,
+                        "--output-dir", str(out_dir),
+                        "--max-count", "20"
+                    ]
+                    import os
+                    env = os.environ.copy()
+                    env["PYTHONIOENCODING"] = "utf-8"
+                    env["PYTHONUTF8"] = "1"
+                    # 搜索评估未传 --eval-model → 用 search_and_evaluate 默认 gemini-flash-lite(OpenRouter)
+                    _se_model = cmd[cmd.index("--eval-model") + 1] if "--eval-model" in cmd else "google/gemini-3.1-flash-lite (默认)"
+                    flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
+                    with open(log_file, "w", encoding="utf-8", buffering=1) as log_fh:
+                        _log_header(log_fh, "🔎 搜索评估", _se_model)
+                        proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
+                                                cwd=str(SE), env=env, creationflags=flags)
+                        ACTIVE_SEARCH_EVALS[query_text]["pid"] = proc.pid
+                        proc.wait()
+                        
+                        if proc.returncode == 0:
+                            evaluated_file = out_dir / "evaluated.json"
+                            if evaluated_file.is_file():
+                                with open(evaluated_file, "r", encoding="utf-8") as rf:
+                                    eval_data = json.load(rf)
+                                eval_data["form"] = "A"
+                                eval_data["query"] = query_text
+                                eval_data["original_q"] = query_text
+                                
+                                with open(out_dir / "form_A.json", "w", encoding="utf-8") as wf:
+                                    json.dump(eval_data, wf, ensure_ascii=False, indent=2)
+                                ACTIVE_SEARCH_EVALS[query_text]["status"] = "success"
+                            else:
+                                ACTIVE_SEARCH_EVALS[query_text]["status"] = "failed"
+                                ACTIVE_SEARCH_EVALS[query_text]["error"] = "evaluated.json not found after execution"
+                                with open(log_file, "a", encoding="utf-8") as f_err:
+                                    f_err.write("\n[server error] evaluated.json not found after execution\n")
+                        else:
+                            ACTIVE_SEARCH_EVALS[query_text]["status"] = "failed"
+                            ACTIVE_SEARCH_EVALS[query_text]["error"] = f"search_and_evaluate.py exited with code {proc.returncode}"
+                except Exception as ex:
+                    ACTIVE_SEARCH_EVALS[query_text]["status"] = "failed"
+                    ACTIVE_SEARCH_EVALS[query_text]["error"] = str(ex)
+                    try:
+                        with open(log_file, "a", encoding="utf-8") as f_err:
+                            f_err.write(f"\n[server error] Exception: {ex}\n")
+                    except Exception:
+                        pass
+                finally:
+                    try:
+                        if queries_file.is_file():
+                            queries_file.unlink()
+                    except Exception:
+                        pass
+                        
+            t = threading.Thread(target=run_search_eval_task, args=(q, safe_q, temp_queries_file, q_dir, platforms, log_path))
+            t.daemon = True
+            t.start()
+            
+            self._send(200, json.dumps({
+                "status": "started",
+                "query": q,
+                "log": f"{RUNS_DIR_NAME}/{safe_q}/_search_eval.log"
+            }, ensure_ascii=False), "application/json")
+        elif self.path == "/api/generate_procedure":
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+                
+            q = (payload.get("q") or "").strip()
+            form = (payload.get("form") or "").strip()
+            case_id = (payload.get("case_id") or "").strip()
+            engine = (payload.get("engine") or "cyber_runner").strip()
+            model = (payload.get("model") or "google/gemini-3.1-flash-lite").strip()
+            
+            if MODE != "new" and not re.match(r"^q\d+$", q):
+                self._send(400, json.dumps({"error": f"bad q (expect 'qNN'): {q!r}"}, ensure_ascii=False), "application/json"); return
+            if form not in ("A", "B", "C"):
+                self._send(400, json.dumps({"error": f"bad form: {form!r}"}, ensure_ascii=False), "application/json"); return
+            if not case_id:
+                self._send(400, json.dumps({"error": "missing case_id"}, ensure_ascii=False), "application/json"); return
+                
+            q_dir = RUNS_DIR / q
+            form_file = q_dir / f"form_{form}.json"
+            if not form_file.is_file():
+                self._send(404, json.dumps({"error": f"form file not found: {form_file.name}"}, ensure_ascii=False), "application/json"); return
+                
+            try:
+                with open(form_file, encoding="utf-8") as f:
+                    form_data = json.load(f)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to read form: {e}"}, ensure_ascii=False), "application/json"); return
+                
+            matching_result = None
+            for r in form_data.get("results", []):
+                if r.get("case_id") == case_id:
+                    matching_result = r
+                    break
+                    
+            if not matching_result:
+                self._send(404, json.dumps({"error": f"case_id {case_id} not found in form {form}"}, ensure_ascii=False), "application/json"); return
+                
+            folder_name = f"{form}_{_short_case(case_id)}"
+            out_dir = q_dir / "procedures" / folder_name
+            backup_procedure_history(out_dir)
+            out_dir.mkdir(parents=True, exist_ok=True)
+            
+            src_path = out_dir / "_source.json"
+            try:
+                with open(src_path, "w", encoding="utf-8") as f:
+                    json.dump(_source_to_dsl_input(matching_result), f, ensure_ascii=False, indent=2)
+                    
+                score = _composite_score(matching_result.get("llm_evaluation") or {})
+                _write_meta(out_dir, case_id=case_id, from_q=q, form=form, score=score)
+                version = _gen_version()
+                _stamp_version(out_dir, version)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to write inputs: {e}"}, ensure_ascii=False), "application/json"); return
+
+            task_key = f"{q}/{folder_name}"
+            ACTIVE_TASKS[task_key] = {
+                "status": "running",
+                "start_time": datetime.now().isoformat(),
+                "pid": None,
+                "error": None
+            }
+
+            t = threading.Thread(target=run_extraction_task, args=(q, folder_name, case_id, src_path, out_dir, engine, model, version))
+            t.daemon = True
+            t.start()
+            
+            self._send(200, json.dumps({
+                "status": "started",
+                "task_key": task_key,
+                "log": f"{RUNS_DIR_NAME}/{q}/procedures/{folder_name}/_extract.log"
+            }, ensure_ascii=False), "application/json")
+        elif self.path == "/api/extract_procedure_model":
+            # 模型提取:单次大模型直出 workflow.json(无 agent / 无 validate 循环)。
+            # 写同一个 procedures/{form}_{short_case}/,复用 procedure_status/log/展示。
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+            q = (payload.get("q") or "").strip()
+            form = (payload.get("form") or "").strip()
+            case_id = (payload.get("case_id") or "").strip()
+            model = (payload.get("model") or "anthropic/claude-sonnet-4-6").strip()   # 大模型工序默认 claude
+            if form not in ("A", "B", "C"):
+                self._send(400, json.dumps({"error": f"bad form: {form!r}"}, ensure_ascii=False), "application/json"); return
+            if not case_id:
+                self._send(400, json.dumps({"error": "missing case_id"}, ensure_ascii=False), "application/json"); return
+            q_dir = RUNS_DIR / q
+            form_file = q_dir / f"form_{form}.json"
+            if not form_file.is_file():
+                self._send(404, json.dumps({"error": f"form file not found: {form_file.name}"}, ensure_ascii=False), "application/json"); return
+            try:
+                with open(form_file, encoding="utf-8") as f:
+                    form_data = json.load(f)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to read form: {e}"}, ensure_ascii=False), "application/json"); return
+            matching_result = next((r for r in form_data.get("results", []) if r.get("case_id") == case_id), None)
+            if not matching_result:
+                self._send(404, json.dumps({"error": f"case_id {case_id} not found in form {form}"}, ensure_ascii=False), "application/json"); return
+            folder_name = f"{form}_{_short_case(case_id)}"
+            out_dir = q_dir / "procedures" / folder_name / "_model"   # 大模型工序独立子目录,不覆盖 Agent 工序
+            backup_procedure_history(out_dir)
+            out_dir.mkdir(parents=True, exist_ok=True)
+            src_path = out_dir / "_source.json"
+            try:
+                with open(src_path, "w", encoding="utf-8") as f:
+                    json.dump(_source_to_dsl_input(matching_result), f, ensure_ascii=False, indent=2)
+                _write_meta(out_dir, case_id=case_id, from_q=q, form=form,
+                            score=_composite_score(matching_result.get("llm_evaluation") or {}))
+                version = _gen_version()
+                _stamp_version(out_dir, version)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to write inputs: {e}"}, ensure_ascii=False), "application/json"); return
+            task_key = f"{q}/{folder_name}/_model"
+            ACTIVE_TASKS[task_key] = {"status": "running", "start_time": datetime.now().isoformat(), "pid": None, "error": None}
+            t = threading.Thread(target=run_model_extraction_task, args=(q, folder_name, case_id, src_path, out_dir, model, version))
+            t.daemon = True
+            t.start()
+            self._send(200, json.dumps({
+                "status": "started", "task_key": task_key,
+                "log": f"{RUNS_DIR_NAME}/{q}/procedures/{folder_name}/_model/_extract.log"
+            }, ensure_ascii=False), "application/json")
+        elif self.path == "/api/reeval":
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+            q = (payload.get("q") or "").strip()
+            if MODE != "new" and not re.match(r"^q\d+$", q):
+                self._send(400, json.dumps({"error": f"bad q (expect 'qNN'): {q!r}"},
+                                           ensure_ascii=False), "application/json"); return
+            q_dir = RUNS_DIR / q
+            if not q_dir.is_dir():
+                self._send(404, json.dumps({"error": f"{RUNS_DIR_NAME}/{q} not found"}, ensure_ascii=False),
+                           "application/json"); return
+            backup_reeval_history(q_dir)
+            log_path = q_dir / "_reeval.log"
+            try:
+                log_fh = open(log_path, "w", encoding="utf-8", buffering=1)
+                cmd = [sys.executable, "-u", str(SE / "batch_3forms.py"),
+                       "--reeval", "--reeval-q", q, "--output-dir", str(RUNS_DIR)]
+                flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
+                proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
+                                        cwd=str(SE), creationflags=flags)
+                
+                ACTIVE_REEVALS[q] = {
+                    "status": "running",
+                    "pid": proc.pid,
+                    "error": None
+                }
+                
+                def wait_reeval(q_key, p_obj, fh):
+                    try:
+                        p_obj.wait()
+                        if p_obj.returncode == 0:
+                            ACTIVE_REEVALS[q_key]["status"] = "success"
+                        else:
+                            ACTIVE_REEVALS[q_key]["status"] = "failed"
+                            ACTIVE_REEVALS[q_key]["error"] = f"Subprocess exited with code {p_obj.returncode}"
+                    except Exception as ex:
+                        ACTIVE_REEVALS[q_key]["status"] = "failed"
+                        ACTIVE_REEVALS[q_key]["error"] = str(ex)
+                    finally:
+                        try:
+                            fh.close()
+                        except Exception:
+                            pass
+                
+                t = threading.Thread(target=wait_reeval, args=(q, proc, log_fh))
+                t.daemon = True
+                t.start()
+                
+                self._send(200, json.dumps(
+                    {"status": "started", "pid": proc.pid, "q": q,
+                     "log": str(log_path.relative_to(HERE))},
+                    ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to start: {e}"},
+                                           ensure_ascii=False), "application/json")
+        elif self.path == "/api/batch_generate_procedure":
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+                
+            q = (payload.get("q") or "").strip()
+            form = (payload.get("form") or "A").strip()
+            engine = (payload.get("engine") or "cyber_runner").strip()
+            model = (payload.get("model") or "google/gemini-3.1-flash-lite").strip()
+            try:
+                concurrency = int(payload.get("concurrency", 4))
+            except Exception:
+                concurrency = 4
+            concurrency = max(1, min(16, concurrency))
+            
+            if not q:
+                self._send(400, json.dumps({"error": "missing q"}, ensure_ascii=False), "application/json"); return
+                
+            q_dir = RUNS_DIR / q
+            form_file = q_dir / f"form_{form}.json"
+            if not form_file.is_file():
+                self._send(404, json.dumps({"error": f"form file not found: {form_file.name}"}, ensure_ascii=False), "application/json"); return
+                
+            try:
+                with open(form_file, encoding="utf-8") as f:
+                    form_data = json.load(f)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to read form: {e}"}, ensure_ascii=False), "application/json"); return
+            
+            valid_results = []
+            import copy
+            for r in form_data.get("results", []):
+                adapted = adapt(r, q, form)
+                if adapted.get("decision") == "report" and not adapted.get("anomaly"):
+                    r_copy = copy.deepcopy(r)
+                    original_case_id = r.get("case_id", "")
+                    r_copy["case_id"] = f"{form}_{_short_case(original_case_id)}"
+                    valid_results.append(r_copy)
+                    
+            if not valid_results:
+                self._send(400, json.dumps({"error": "没有可提取工序的帖子(所有帖子都已被过滤,或都存在解析异常)"}, ensure_ascii=False), "application/json"); return
+                
+            procedures_dir = q_dir / "procedures"
+            procedures_dir.mkdir(parents=True, exist_ok=True)
+            batch_posts_path = procedures_dir / "temp_batch.json"
+            try:
+                with open(batch_posts_path, "w", encoding="utf-8") as f:
+                    json.dump({"results": valid_results}, f, ensure_ascii=False, indent=2)
+            except Exception as e:
+                self._send(500, json.dumps({"error": f"failed to write temp_batch.json: {e}"}, ensure_ascii=False), "application/json"); return
+                
+            ACTIVE_BATCH_TASKS[q] = {
+                "status": "running",
+                "start_time": datetime.now().isoformat(),
+                "pid": None,
+                "error": None
+            }
+            
+            def run_batch_extraction():
+                try:
+                    log_path = procedures_dir / "_batch_extract.log"
+                    cmd = [
+                        sys.executable, "-u", str(HERE / "procedure-dsl" / "run_cyber.py"),
+                        str(batch_posts_path),
+                        "--out-dir", str(procedures_dir),
+                        "--batch",
+                        "--batch-workers", str(concurrency),
+                        "--model", model,
+                        "--skill", "procedure",   # mode_procedure:用直写版 skill
+                        "--max-turns", "300"
+                    ]
+                    
+                    flags = subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0
+                    with open(log_path, "w", encoding="utf-8", buffering=1) as log_fh:
+                        _log_header(log_fh, "🔧 工序提取(批量 --skill procedure)", model, engine)
+                        proc = subprocess.Popen(cmd, stdout=log_fh, stderr=subprocess.STDOUT,
+                                                cwd=str(HERE / "procedure-dsl"), creationflags=flags)   # cwd=本地 procedure-dsl(run_cyber 假设的工作目录,agent 相对路径才对)
+                        ACTIVE_BATCH_TASKS[q]["pid"] = proc.pid
+                        proc.wait()
+                        
+                        if proc.returncode == 0:
+                            try:
+                                import build_workflows
+                                build_workflows.write_run(q, runs_dir=RUNS_DIR)
+                                ACTIVE_BATCH_TASKS[q]["status"] = "success"
+                            except Exception as ex:
+                                ACTIVE_BATCH_TASKS[q]["status"] = "failed"
+                                ACTIVE_BATCH_TASKS[q]["error"] = f"Workflows compilation failed: {ex}"
+                        else:
+                            ACTIVE_BATCH_TASKS[q]["status"] = "failed"
+                            ACTIVE_BATCH_TASKS[q]["error"] = f"Batch runner exited with code {proc.returncode}"
+                except Exception as ex:
+                    ACTIVE_BATCH_TASKS[q]["status"] = "failed"
+                    ACTIVE_BATCH_TASKS[q]["error"] = str(ex)
+                finally:
+                    try:
+                        if batch_posts_path.is_file():
+                            batch_posts_path.unlink()
+                    except Exception:
+                        pass
+                        
+            t = threading.Thread(target=run_batch_extraction)
+            t.daemon = True
+            t.start()
+            
+            self._send(200, json.dumps({
+                "status": "started",
+                "q": q,
+                "log": f"{RUNS_DIR_NAME}/{q}/procedures/_batch_extract.log"
+            }, ensure_ascii=False), "application/json")
+        elif self.path == "/api/save_spec":
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode("utf-8") if length > 0 else "{}"
+            try:
+                payload = json.loads(raw)
+            except Exception as e:
+                self._send(400, json.dumps({"error": f"bad json: {e}"}), "application/json"); return
+            file_name = (payload.get("file") or "").strip()
+            content = payload.get("content") or ""
+            allowed = [
+                "README.md",
+                "tools.md",
+                "extraction/phase1-skeleton.md",
+                "extraction/phase2-normalize.md",
+                "extraction/phase3-finalize.md",
+                "taxonomy/type_suggestions.md"
+            ]
+            if file_name not in allowed:
+                self._send(400, json.dumps({"error": "invalid file parameter"}), "application/json"); return
+            target_path = HERE / "procedure-dsl" / "spec" / file_name
+            try:
+                target_path.parent.mkdir(parents=True, exist_ok=True)
+                target_path.write_text(content, encoding="utf-8")
+                self._send(200, json.dumps({"status": "ok"}, ensure_ascii=False), "application/json")
+            except Exception as e:
+                self._send(500, json.dumps({"error": str(e)}, ensure_ascii=False), "application/json")
+        else:
+            self._send(404, json.dumps({"error": "not found"}), "application/json")
+    def log_message(self, *a): pass
+
+if __name__ == "__main__":
+    n = len(scan_runs()["queries"])
+    print(f"搜索评估查看 server ({MODE} 模式):http://0.0.0.0:{PORT}   ({RUNS_DIR_NAME}/ 下 {n} 个 query,实时扫描)")
+    ThreadingHTTPServer(("0.0.0.0", PORT), H).serve_forever()

+ 113 - 0
examples/process_pipeline/script/search_eval/mode_procedure/shell/README.md

@@ -0,0 +1,113 @@
+# mode_procedure 查看服务 + 公网分享 使用说明
+
+把本地的程序控制类型评估查看服务(`server.py`,默认 `:8771`)一键起好,并通过 Cloudflare 隧道生成一个**公网链接**,发给任何人就能看 —— 无需对方在同一局域网、无需对方改代理设置。
+
+脚本:`share.sh`(本目录)
+
+---
+
+## 快速开始
+
+```bash
+cd /Users/max_liu/max_liu/company/Agent/examples/process_pipeline/script/search_eval/mode_procedure/shell
+
+./share.sh start      # 起服务 + 隧道,打印公网链接
+```
+
+执行后会输出类似:
+
+```
+🌐 公网链接(发给同事即可,无需局域网/改代理):
+    https://advanced-how-leasing-brief.trycloudflare.com
+```
+
+把这个链接发到群里即可。**进程一直保留**(已脱离终端),关掉终端窗口也不会断。
+
+---
+
+## 全部命令
+
+| 命令 | 作用 |
+|------|------|
+| `./share.sh start`   | 起 `server.py`(后台)+ cloudflared 隧道(后台,http2),打印公网链接 |
+| `./share.sh stop`    | 停掉服务和隧道 |
+| `./share.sh restart` | 重启两者(**会换一个新链接**,记得重新发) |
+| `./share.sh status`  | 查看运行状态 + 当前链接 + 本地自检(HTTP 状态码) |
+| `./share.sh url`     | 只打印当前公网链接(方便复制) |
+
+`start` 是幂等的:服务已在跑就跳过,不会重复起进程,可放心反复执行当作"确保它在跑"。
+
+---
+
+## 典型场景
+
+**第一次分享 / 重新分享:**
+```bash
+./share.sh start          # 拿到链接,发群
+```
+
+**链接突然打不开了(先别慌,一条命令查):**
+```bash
+./share.sh status
+```
+- `server.py ❌` → 后端挂了,执行 `./share.sh start` 拉起来。
+- `cloudflared ❌` 或链接变了 → 隧道断了,执行 `./share.sh restart`(换新链接)。
+- 两个都 ✅ 但对方打不开 → 多半是对方浏览器/系统代理拦截,见下方"常见问题"。
+
+**忘了链接是多少:**
+```bash
+./share.sh url
+```
+
+**用完关闭分享:**
+```bash
+./share.sh stop
+```
+
+---
+
+## 它替你规避的坑(为什么不直接用局域网 IP / 不直接 `python server.py`)
+
+| 坑 | 现象 | 脚本的处理 |
+|----|------|-----------|
+| 前台运行,关终端被 SIGHUP 杀掉 | 关窗口/休眠后链接 502 | 用 `setsid`/`nohup` 脱离终端守护 |
+| QUIC/UDP 被公司网或 VPN 封 | 隧道死循环重连,公网打不开 | 固定 `--protocol http2`,走 TCP 443 |
+| 局域网共享要求同网段 | WiFi 客户端隔离 → ping 不通 | 走公网隧道,完全绕开局域网 |
+| 访客本地代理拦截内网 IP | 同事打不开 `192.168.x.x` | 公网 HTTPS,访客代理正常放行 |
+| 重复启动起一堆进程 | 端口冲突/混乱 | `start` 先检测端口,幂等 |
+
+---
+
+## 常见问题
+
+**Q:链接打开是 502 / Bad Gateway?**
+后端 `server.py` 没在跑(隧道只是转发器)。`./share.sh status` 确认,再 `./share.sh start`。
+
+**Q:对方打不开,但我本地和 `status` 都正常?**
+对方浏览器或系统开了代理(Clash/V2Ray 等),把公网域名也拦了。让对方临时关代理,或把 `trycloudflare.com` 加进代理白名单/直连规则。
+
+**Q:链接每次重启都变,能不能固定?**
+`trycloudflare` 是临时地址,绑定在 cloudflared 进程生命周期上,进程停就失效、重启换新。要**永久固定地址**需要 Cloudflare 账号 + 自有域名做 named tunnel —— 需要时再单独配置。
+
+**Q:日志在哪?**
+- 服务日志:`../.server.log`
+- 隧道日志:`../.cloudflared.log`
+(都在 `mode_procedure/` 目录下,以 `.` 开头隐藏。)
+
+**Q:换个端口?**
+```bash
+PORT=9000 ./share.sh start
+```
+
+**Q:用指定的 python 解释器?**
+```bash
+PYTHON=/path/to/python ./share.sh start
+```
+
+---
+
+## 依赖
+
+- `cloudflared`(已安装;如缺失:`brew install cloudflared`)
+- `python`(项目当前用 conda `base` 环境的 `python`)
+- `lsof` / `curl`(macOS 自带)

+ 131 - 0
examples/process_pipeline/script/search_eval/mode_procedure/shell/share.sh

@@ -0,0 +1,131 @@
+#!/usr/bin/env bash
+# ──────────────────────────────────────────────────────────────────────────
+# mode_procedure 查看服务 + Cloudflare 隧道 一键管理脚本
+#
+#   ./share.sh start     启动 server.py(后台) + cloudflared 隧道(后台,http2),打印公网链接
+#   ./share.sh stop      停掉两者
+#   ./share.sh restart   重启两者(换新链接)
+#   ./share.sh status     查看运行状态 + 当前链接
+#   ./share.sh url        只打印当前公网链接
+#
+# 设计要点:
+#   - 两个进程都用 nohup/setsid 脱离终端,关掉终端窗口也不会被 SIGHUP 杀掉。
+#   - cloudflared 强制 --protocol http2,绕开公司网/VPN 常封的 UDP(QUIC)。
+#   - 幂等:重复 start 会先清掉旧进程,不会起一堆。
+# ──────────────────────────────────────────────────────────────────────────
+set -euo pipefail
+
+# 项目目录 = 本脚本所在目录(shell/)的上一级
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJ_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+PORT="${PORT:-8771}"
+
+SERVER_LOG="$PROJ_DIR/.server.log"
+CF_LOG="$PROJ_DIR/.cloudflared.log"
+SERVER_PIDF="$PROJ_DIR/.server.pid"
+CF_PIDF="$PROJ_DIR/.cloudflared.pid"
+
+PY="${PYTHON:-python}"
+
+# 选一个能后台脱离的方式:优先 setsid,macOS 没有就用 nohup
+_spawn() {  # _spawn <logfile> <cmd...>
+  local log="$1"; shift
+  if command -v setsid >/dev/null 2>&1; then
+    setsid "$@" >"$log" 2>&1 < /dev/null &
+  else
+    nohup "$@" >"$log" 2>&1 < /dev/null &
+  fi
+  echo $!
+}
+
+_alive() { [ -n "${1:-}" ] && kill -0 "$1" 2>/dev/null; }
+
+_server_running() { lsof -nP -iTCP:"$PORT" -sTCP:LISTEN >/dev/null 2>&1; }
+
+_extract_url() {
+  # 优先看脚本自己的日志,兼容回退到手动启动时的 /tmp 日志;没找到不报错
+  { grep -hEo "https://[a-z0-9-]+\.trycloudflare\.com" "$CF_LOG" /tmp/cf_tunnel.log 2>/dev/null || true; } | tail -1
+}
+
+start_server() {
+  if _server_running; then
+    echo "✅ server.py 已在跑 (:$PORT)"
+    return
+  fi
+  echo "▶️  启动 server.py …"
+  ( cd "$PROJ_DIR" && _spawn "$SERVER_LOG" "$PY" server.py "$PORT" ) > "$SERVER_PIDF"
+  # 等监听端口起来
+  for _ in $(seq 1 20); do
+    _server_running && break
+    sleep 0.5
+  done
+  if _server_running; then
+    echo "✅ server.py 已启动 (:$PORT)  日志: $SERVER_LOG"
+  else
+    echo "❌ server.py 启动失败,看日志: $SERVER_LOG"; tail -15 "$SERVER_LOG" || true; exit 1
+  fi
+}
+
+start_tunnel() {
+  echo "▶️  启动 cloudflared 隧道 (http2) …"
+  : > "$CF_LOG"
+  _spawn "$CF_LOG" cloudflared tunnel --protocol http2 --url "http://localhost:$PORT" > "$CF_PIDF"
+  # 等 URL 出现
+  local url=""
+  for _ in $(seq 1 40); do
+    url="$(_extract_url)"
+    [ -n "$url" ] && break
+    sleep 0.5
+  done
+  if [ -n "$url" ]; then
+    # 再等连接注册成功
+    for _ in $(seq 1 20); do
+      grep -q "Registered tunnel connection" "$CF_LOG" && break
+      sleep 0.5
+    done
+    echo
+    echo "🌐 公网链接(发给同事即可,无需局域网/改代理):"
+    echo "    $url"
+    echo
+  else
+    echo "❌ 隧道未拿到地址,看日志: $CF_LOG"; tail -15 "$CF_LOG" || true; exit 1
+  fi
+}
+
+stop_all() {
+  echo "⏹  停止隧道与服务 …"
+  pkill -f "cloudflared tunnel --protocol http2 --url http://localhost:$PORT" 2>/dev/null && echo "  - cloudflared 已停" || echo "  - 无 cloudflared"
+  # 杀掉占用端口的 server.py
+  local pids; pids="$(lsof -nP -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true)"
+  if [ -n "$pids" ]; then
+    echo "$pids" | xargs kill 2>/dev/null && echo "  - server.py (:$PORT) 已停"
+  else
+    echo "  - 无 server.py 监听 :$PORT"
+  fi
+  rm -f "$SERVER_PIDF" "$CF_PIDF"
+}
+
+status() {
+  echo "── 状态 ──────────────────────────────"
+  if _server_running; then echo "server.py : ✅ 运行中 (:$PORT)"; else echo "server.py : ❌ 未运行"; fi
+  if pgrep -f "cloudflared tunnel .*localhost:$PORT" >/dev/null 2>&1; then
+    echo "cloudflared: ✅ 运行中"
+  else
+    echo "cloudflared: ❌ 未运行"
+  fi
+  local url; url="$(_extract_url)"
+  [ -n "$url" ] && echo "公网链接   : $url" || echo "公网链接   : (无)"
+  # 本地健康检查(绕代理)
+  local code; code="$(curl -s -m3 --noproxy '*' -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT/" 2>/dev/null || echo 000)"
+  echo "本地自检   : HTTP $code"
+  echo "─────────────────────────────────────"
+}
+
+case "${1:-start}" in
+  start)   start_server; start_tunnel ;;
+  stop)    stop_all ;;
+  restart) stop_all; sleep 1; start_server; start_tunnel ;;
+  status)  status ;;
+  url)     u="$(_extract_url)"; [ -n "$u" ] && echo "$u" || { echo "(隧道未运行)"; exit 1; } ;;
+  *) echo "用法: $0 {start|stop|restart|status|url}"; exit 1 ;;
+esac

+ 182 - 0
examples/process_pipeline/script/search_eval/workflows/AI 人像 图片 生成 怎么做_A_xhs_684a5748.json

@@ -0,0 +1,182 @@
+{
+  "query_id": "AI 人像 图片 生成 怎么做",
+  "query": "AI 人像 图片 生成 怎么做",
+  "platform": "xhs",
+  "post": {
+    "channel_content_id": "684a5748000000002202f516",
+    "title": "如何让豆包生成逼真人物照片级图片?",
+    "content_type": "note",
+    "body_text": "很多宝子们用豆包生图,总是得不到非常真实的图像\n现在方法来啦!\n想生成真实感强,非常的逼真的人物照片,\n需要一些特别的关键词,如:高清高分辨率、大光圈、背景虚化、多巴胺风格\n还不快快试一下?\n\t\n👉适用工具:豆包/即梦\n✅【提示词】\n一位漂亮苗条的美女半身照,穿淡粉色吊带裙,戴红宝石项链,红宝石耳环,微笑露出两颗牙齿,手中拿着一束七色玫瑰花,站在暗黑的森林中,丁达尔光,概念光影,多巴胺风格,杰作,实景,相机拍摄,高质量细节,细节生动,用笔灵活,自然之美,大光圈,背景虚化,彩色光斑,中景,32K高清高分辨率\n-------------------\n实用干~货,建议~收~藏,查看主页更多实用干货!\n-------------------\n#豆包 #AI照片 #AI画图 #ai绘画 #AI中文提示词 #多巴胺风格 #人物 #逼真人像 #人像摄影 #细节生动",
+    "like_count": 378,
+    "publish_timestamp": "2025-06-12 12:27:52",
+    "images": [
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgni805nrg3u20bj91cepmu70?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgni8g5nrg3u20bj9101vf7h8?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgni905nrg3u20bj91p3q9n8o?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgni9g5nrg3u20bj914ss02g0?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgnia05nrg3u20bj91p66vr5o?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgniag5nrg3u20bj91e3l9kgo?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgnib05nrg3u20bj91q6qu3l8?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/spectrum/1040g34o31ik9c1rgnibg5nrg3u20bj91g0k4mgo?imageView2/2/w/1080/format/webp"
+    ],
+    "videos": [],
+    "channel": "xhs",
+    "link": "https://www.xiaohongshu.com/explore/684a5748000000002202f516",
+    "_quality_score": 91.0,
+    "_quality_grade": "A"
+  },
+  "llm_evaluation": {
+    "知识类型": [
+      "能力"
+    ],
+    "相关性": {
+      "和内容制作知识相关": {
+        "得分": 8,
+        "理由": "内容提供了具体的提示词(Prompt)优化方案,直接影响生成图像的视觉风格与质量,属于有效的制作知识。"
+      },
+      "和 query 相关": {
+        "得分": 9,
+        "理由": "直接针对“AI人像生成怎么做”的问题,给出了明确的工具推荐和可直接复用的提示词模板。"
+      }
+    },
+    "质量": {
+      "固定维度": {
+        "热度性": {
+          "得分": 7,
+          "理由": "拥有378个点赞,在垂直领域内属于较受欢迎的分享,互动量尚可。"
+        },
+        "评论反馈": {
+          "得分": 5,
+          "理由": "暂无评论数据,无法评估用户反馈,仅根据内容实用性给中等分。"
+        },
+        "用例": {
+          "真实感": {
+            "得分": 7,
+            "理由": "展示的图片光影和质感较好,但部分图片存在明显的AI合成痕迹(如动物头人身),整体真实感尚可。"
+          },
+          "表现力": {
+            "得分": 8,
+            "理由": "成品视觉效果精美,符合社交媒体审美,具有较强的视觉吸引力。"
+          }
+        },
+        "时效性": {
+          "得分": 1
+        }
+      },
+      "动态维度": {
+        "能力": {
+          "字段完整性": {
+            "输入完整性": {
+              "得分": 9,
+              "理由": "明确指出了需要使用的工具(豆包/即梦)以及核心提示词要素。"
+            },
+            "实现完整性": {
+              "得分": 8,
+              "理由": "提供了完整的提示词模板,涵盖了主体、环境、光影和风格描述,操作性强。"
+            },
+            "输出完整性": {
+              "得分": 7,
+              "理由": "展示了预期的输出效果,但未详细说明在不同模型下的差异或失败案例的调整方法。"
+            }
+          },
+          "泛化性": {
+            "得分": 6,
+            "理由": "提示词结构具有一定的通用性,但部分词汇(如“多巴胺风格”)高度依赖特定模型对词汇的理解,迁移到其他模型效果可能不稳定。"
+          }
+        }
+      }
+    }
+  },
+  "workflow": {
+    "source": {
+      "platform": "小红书",
+      "author": "AI研究僧",
+      "date": "2024",
+      "url": "https://www.xiaohongshu.com/explore/684a5748000000002202f516",
+      "title": "如何让豆包生成逼真人物照片级图片?",
+      "excerpt": "通过在提示词中加入高清、大光圈、背景虚化等特定关键词,提升豆包/即梦生成人物图像的真实感。"
+    },
+    "procedures": [
+      {
+        "id": "p1",
+        "name": "逼真人物图像生成",
+        "purpose": "通过结构化提示词引导AI生成高真实感的人物照片",
+        "category": "产物创造",
+        "platform": "豆包/即梦",
+        "author": "AI研究僧",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "人物设定",
+              "desc": "用户想要生成的人物主体描述"
+            }
+          ],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {
+          "人物设定": {
+            "extends": "描述",
+            "desc": "包含人物外貌、服饰、动作等核心要素的描述"
+          }
+        },
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "人物",
+            "form": "照片级真实感",
+            "directive": "",
+            "intent": "{via:human} {act:元素生成} {out-type:提示词} 组合人物设定与真实感关键词",
+            "inputs": [
+              {
+                "type": "描述",
+                "value": "一位漂亮苗条的美女半身照,穿淡粉色吊带裙,戴红宝石项链,红宝石耳环,微笑露出两颗牙齿,手中拿着一束七色玫瑰花,站在暗黑的森林中",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "提示词",
+                "value": "一位漂亮苗条的美女半身照,穿淡粉色吊带裙,戴红宝石项链,红宝石耳环,微笑露出两颗牙齿,手中拿着一束七色玫瑰花,站在暗黑的森林中,丁达尔光,概念光影,多巴胺风格,杰作,实景,相机拍摄,高质量细节,细节生动,用笔灵活,自然之美,大光圈,背景虚化,彩色光斑,中景,32K高清高分辨率",
+                "anchor": "→ s2"
+              }
+            ]
+          },
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "豆包/即梦",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "人物",
+            "form": "照片级真实感",
+            "directive": "比例 1:1",
+            "intent": "{via:豆包/即梦} {act:元素生成} {in-type:提示词} {out-type:成品图} 生成逼真人物图像",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "一位漂亮苗条的美女半身照,穿淡粉色吊带裙,戴红宝石项链,红宝石耳环,微笑露出两颗牙齿,手中拿着一束七色玫瑰花,站在暗黑的森林中,丁达尔光,概念光影,多巴胺风格,杰作,实景,相机拍摄,高质量细节,细节生动,用笔灵活,自然之美,大光圈,背景虚化,彩色光斑,中景,32K高清高分辨率",
+                "anchor": "← s1o1"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张逼真的人物照片,包含丁达尔光、背景虚化等摄影效果>",
+                "anchor": "→ 交付"
+              }
+            ]
+          }
+        ]
+      }
+    ]
+  }
+}

+ 171 - 0
examples/process_pipeline/script/search_eval/workflows/AI 人像 真实感 图片 获取 程序控制类型_A_xhs_692ebcb3.json

@@ -0,0 +1,171 @@
+{
+  "query_id": "AI 人像 真实感 图片 获取 程序控制类型",
+  "query": "AI 人像 真实感 图片 获取 程序控制类型",
+  "platform": "xhs",
+  "post": {
+    "channel_content_id": "692ebcb3000000000d00f31c",
+    "title": "拿走!真实感人像 AI Prompt 指令Banana Pro",
+    "content_type": "note",
+    "body_text": "关注 @AI 苟活手册👈,一大批 AI 模板正在路上\n#NanoBanana[话题]# #gemini[话题]# #Prompt[话题]# #Ai[话题]# #ai真实[话题]#",
+    "like_count": 1170,
+    "publish_timestamp": "2025-12-02 18:17:23",
+    "images": [
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k005o96tiv85g5oo9h21p8?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k0g5o96tiv85g5oc75h0c0?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k105o96tiv85g5oohkj538?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k1g5o96tiv85g5o8srpluo?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k205o96tiv85g5o727v51g?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k2g5o96tiv85g5olr8h09o?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k305o96tiv85g5oav7guvg?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k3g5o96tiv85g5op2306v0?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k405o96tiv85g5omltabk0?imageView2/2/w/1080/format/webp",
+      "https://ci.xiaohongshu.com/notes_pre_post/1040g3k031pjajfar4k4g5o96tiv85g5ojsrdul8?imageView2/2/w/1080/format/webp"
+    ],
+    "videos": [],
+    "channel": "xhs",
+    "link": "https://www.xiaohongshu.com/explore/692ebcb3000000000d00f31c",
+    "_quality_score": 87.0,
+    "_quality_grade": "A"
+  },
+  "llm_evaluation": {
+    "知识类型": [
+      "工具"
+    ],
+    "相关性": {
+      "和内容制作知识相关": {
+        "得分": 8,
+        "理由": "内容展示了如何通过特定的 Prompt 指令在 NanoBanana 工具中实现特定风格的人像生成,具有明确的制作指导意义。"
+      },
+      "和 query 相关": {
+        "得分": 9,
+        "理由": "帖子直接回应了 AI 人像真实感生成的需求,并提供了具体的 Prompt 模板,非常契合检索意图。"
+      }
+    },
+    "质量": {
+      "固定维度": {
+        "热度性": {
+          "得分": 9,
+          "理由": "拥有 1170 次点赞,在 AI 垂直领域属于高热度内容。"
+        },
+        "评论反馈": {
+          "得分": 0,
+          "理由": "当前数据中无评论区内容,无法评估反馈。"
+        },
+        "用例": {
+          "真实感": {
+            "得分": 9,
+            "理由": "生成的图片具有极高的真实感,光影、皮肤纹理和环境融合度极佳,几乎看不出 AI 生成痕迹。"
+          },
+          "表现力": {
+            "得分": 9,
+            "理由": "成品视觉表现力极强,完全符合社交媒体高质量人像摄影的审美标准。"
+          }
+        },
+        "时效性": {
+          "得分": 3
+        }
+      },
+      "动态维度": {
+        "工具": {
+          "能力边界覆盖": {
+            "得分": 6,
+            "理由": "展示了工具在人像一致性和风格化摄影方面的能力,但未明确说明其局限性。"
+          },
+          "有效比较": {
+            "得分": 0,
+            "理由": "未涉及与其他工具的对比。"
+          },
+          "参数/接口具体性": {
+            "得分": 7,
+            "理由": "提供了具体的 Prompt 文本,但缺乏除 Prompt 之外的参数设置说明。"
+          },
+          "实操示例": {
+            "得分": 9,
+            "理由": "提供了清晰的 Input(Prompt)到 Output(高质量图片)的对应示例。"
+          },
+          "版本&限制": {
+            "得分": 2,
+            "理由": "仅提及了工具名称,未说明版本号或使用限制。"
+          }
+        }
+      }
+    }
+  },
+  "workflow": {
+    "source": {
+      "platform": "小红书",
+      "author": "AI 苟活手册",
+      "date": "2024",
+      "url": "https://www.xiaohongshu.com/explore/692ebcb3000000000d00f31c",
+      "title": "拿走!真实感人像 AI Prompt 指令Banana Pro",
+      "excerpt": "利用 Nano Banana Pro 工具,通过固定人物参考图与场景化提示词,生成具有真实 iPhone 摄影质感的人像照片。"
+    },
+    "procedures": [
+      {
+        "id": "p1",
+        "name": "真实感人像生成",
+        "purpose": "基于特定人物身份参考,生成具有真实生活感和 iPhone 摄影风格的人像照片",
+        "category": "产物创造",
+        "platform": "Nano Banana Pro",
+        "author": "AI 苟活手册",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "参考图",
+              "name": "人物参考图",
+              "desc": "用于固定身份特征的原始人像"
+            },
+            {
+              "type": "提示词",
+              "name": "场景描述指令",
+              "desc": "定义环境、动作、光影及设备风格的提示词"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {
+          "人物参考图": {
+            "extends": "参考图",
+            "desc": "用于保持一致性的面部特征图"
+          }
+        },
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "Nano Banana Pro",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "人物",
+            "form": "iPhone 摄影风格",
+            "directive": "保持身份一致性,模拟 iPhone 真实拍摄质感,无人工模糊,保持自然氛围",
+            "intent": "{via:Nano Banana Pro} {act:元素生成} {in-type:参考图,提示词} {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "人物参考图",
+                "value": "<一张用于固定身份特征的女性面部参考图>",
+                "anchor": "← 工序输入"
+              },
+              {
+                "type": "提示词",
+                "value": "Use the attached face image as the exact identity reference and generate the same person. Create a natural iPhone-style car selfie with bright sunlight entering from the side window, captured from a low, slightly upward angle as she sits in the backseat. She wears an oversized charcoal hoodie with the hood up, layered under a black leather jacket, and has wired earphones in. Keep the lighting sharply natural, no artificial blur, and maintain a candid, unfiltered atmosphere.",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "成品图",
+                "value": "<一张车内自拍真实感人像图>",
+                "anchor": "→ 交付"
+              }
+            ]
+          }
+        ]
+      }
+    ]
+  }
+}

File diff ditekan karena terlalu besar
+ 8 - 0
examples/process_pipeline/script/search_eval/workflows/AI 人像 真实感 图片 获取 程序控制类型_A_xhs_69d51b97.json


+ 465 - 98
examples/process_pipeline/script/search_eval/workflows/AI 信息 版面设计 图片 怎么做_A_gzh_34767dfb.json

@@ -95,188 +95,555 @@
   },
   "workflow": {
     "source": {
-      "platform": "",
-      "author": "gzh",
-      "date": "2026-06-04 14:42:00",
+      "platform": "微信公众号",
+      "author": "大刘",
+      "date": "2026-06-04",
       "url": "https://mp.weixin.qq.com/s?__biz=MzIyNzQ3MDM3Mw==&idx=1&mid=2247485527&sn=b039876c08728db244001b8421afe37c",
       "title": "工作中的信息图,这个AI方法论都能生成",
-      "excerpt": "[image: https://mmbiz.qpic.cn/mmbiz_png/J1Cdba5GUc3gMjy62ZBBLCaVQK4QvMkXvQHwibGoge6h1e4s6adkHL63ah8eHiaMbncqxhgibdF5VVKQ"
+      "excerpt": "本文介绍了一套在职场上使用 AI 绘制信息图的方法论,通过将图的类型、核心模块、模块关系、风格样式和输出要求填入公式,捏成提示词喂给 AI,即可一次性画准流程图、架构图、框架图、概念图和总结图等多种职场图表。"
     },
     "procedures": [
       {
         "id": "p1",
-        "name": "职场信息图AI生成方法论提取",
-        "purpose": "将AI大刘关于职场信息图AI生成的方法论还原为可执行的工序步骤,并归纳其核心逻辑。",
-        "category": "",
-        "platform": "",
-        "author": "gzh",
+        "name": "企业 AI 智能客服系统工作流程图生成",
+        "purpose": "使用 AI 绘制一张企业 AI 智能客服系统的商务极简工作流程图",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
         "declarations": {
-          "inputs": [],
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "客服系统流程描述",
+              "desc": "包含用户提问、意图识别、知识库检索、生成回答、转人工五个核心环节及分支关系"
+            }
+          ],
           "resources": [],
           "returns": {
-            "type": "信息图生成方法论"
+            "type": "成品图"
           }
         },
+        "type_registry": {},
         "steps": [
           {
             "id": "s1",
             "kind": "step",
             "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成客服系统工作流程图的 {out-type:提示词}",
             "inputs": [
               {
-                "type": "用户需求描述",
-                "value": "【图的类型】+【核心模块有哪些】+【模块之间什么关系】+【什么风格】+【输出要求】。\n五格里最核心的是\n模块之间什么关系\n。同样几个框,关系不一样,画出来是天差地别两张图。关系无非先后(A 完了到 B)、包含(大框套小框)、并列(几块平起平坐)、对立(这边一套那边一套)这么几种,你把它点明,箭头和层级 AI 才摆得对。绝大多数生图中看到线条、箭头乱指的基本是这个问题",
-                "anchor": "← s1o1"
-              },
-              {
-                "type": "提示词",
-                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
-                "anchor": ""
+                "type": "描述",
+                "value": "前段时间我给一家企业做 AI 落地的方案,里头一张 AI 客服系统的工作流程图、一张知识库系统的架构图绕不过去。\n尝试下来,我总结了一套\n职场上 AI 画图的方法论\n。\n我个人的经验是,不直接让它画。\n先在备忘录里把这张图是个啥一项项列清楚:画啥类型、里头哪几块、什么关系、什么风格、要不要插 PPT。列完再捏成一段话喂过去。。。",
+                "anchor": "← 工序输入"
               }
             ],
             "outputs": [
               {
                 "id": "s1o1",
                 "type": "提示词",
-                "value": "【图的类型】+【核心模块有哪些】+【模块之间什么关系】+【什么风格】+【输出要求】。\n五格里最核心的是\n模块之间什么关系\n。同样几个框,关系不一样,画出来是天差地别两张图。关系无非先后(A 完了到 B)、包含(大框套小框)、并列(几块平起平坐)、对立(这边一套那边一套)这么几种,你把它点明,箭头和层级 AI 才摆得对。绝大多数生图中看到线条、箭头乱指的基本是这个问题",
-                "anchor": ""
+                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
+                "anchor": "→ s2"
               }
-            ],
-            "effect": "预处理",
-            "action": "提取/化学提取/解构",
-            "substance": "信息图",
-            "form": null,
-            "intent": "用 {via:human} {act:解构} {in-type:原文正文},得到 {out-type:提示词}"
+            ]
           },
           {
             "id": "s2",
             "kind": "step",
-            "via": "GPT-IMAGE-2",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格用商务正式、扁平化的极简信息图风格,配色干净专业。图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成客服系统工作流程的 {out-type:成品图}",
             "inputs": [
               {
                 "type": "提示词",
-                "value": "【图的类型】+【核心模块有哪些】+【模块之间什么关系】+【什么风格】+【输出要求】。\n五格里最核心的是\n模块之间什么关系\n。同样几个框,关系不一样,画出来是天差地别两张图。关系无非先后(A 完了到 B)、包含(大框套小框)、并列(几块平起平坐)、对立(这边一套那边一套)这么几种,你把它点明,箭头和层级 AI 才摆得对。绝大多数生图中看到线条、箭头乱指的基本是这个问题",
+                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
                 "anchor": "← s1o1"
-              },
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张企业 AI 智能客服系统工作流程图,包含用户提问、意图识别、知识库检索、生成回答、转人工五个核心环节,从上到下的先后流程关系,商务正式、扁平化的极简信息图风格>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "id": "p2",
+        "name": "生产项目管理工作流程图生成",
+        "purpose": "使用 AI 绘制一张生产项目管理的商务扁平化工作流程图",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "生产项目管理步骤描述",
+              "desc": "包含需求评审、生产排期、物料采购、生产加工、质量检验、入库交付等步骤"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {},
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成生产项目管理工作流程图的 {out-type:提示词}",
+            "inputs": [
+              {
+                "type": "描述",
+                "value": "场景一:业务/工作流程图\n02\n我一般再遇到需要讲一件事\"是怎么一步步发生的\",就用它。\n报销怎么走审批、生产项目怎么推进,这种带先后顺序的全归它,是职场最高频的一类。关键在\n模块之间什么关系\n,所以\"按顺序\"\"依次连接\"得说清楚。",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
               {
+                "id": "s1o1",
                 "type": "提示词",
                 "value": "帮我画一张【生产项目管理】的工作流程图。\n整个流程按先后顺序分为这几个步骤:【需求评审】→【生产排期】→【物料采购】→【生产加工】→【质量检验】→【入库交付】。\n请用箭头把这几个步骤从左到右(或从上到下)依次串联起来,体现清晰的先后推进关系。每个步骤下方可以配一个简单的小图标。\n风格:商务正式、扁平化信息图风格,配色专业、不超过三种主色。\n所有文字用中文,清晰可辨认,不要乱码。",
-                "anchor": ""
+                "anchor": "→ s2"
+              }
+            ]
+          },
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格:商务正式、扁平化信息图风格,配色专业、不超过三种主色。所有文字用中文,清晰可辨认,不要乱码。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成生产项目管理工作流程的 {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张【生产项目管理】的工作流程图。\n整个流程按先后顺序分为这几个步骤:【需求评审】→【生产排期】→【物料采购】→【生产加工】→【质量检验】→【入库交付】。\n请用箭头把这几个步骤从左到右(或从上到下)依次串联起来,体现清晰的先后推进关系。每个步骤下方可以配一个简单的小图标。\n风格:商务正式、扁平化信息图风格,配色专业、不超过三种主色。\n所有文字用中文,清晰可辨认,不要乱码。",
+                "anchor": "← s1o1"
               }
             ],
             "outputs": [
               {
                 "id": "s2o1",
                 "type": "成品图",
-                "value": "<一张企业AI智能客服系统的工作流程图,商务正式、扁平化风格>",
-                "anchor": ""
+                "value": "<一张生产项目管理工作流程图,包含需求评审、生产排期、物料采购、生产加工、质量检验、入库交付等步骤,商务正式、扁平化信息图风格>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "id": "p3",
+        "name": "企业 AI 知识库系统分层架构图生成",
+        "purpose": "使用 AI 绘制一张企业 AI 知识库系统的商务科技风分层架构图",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "知识库系统分层描述",
+              "desc": "包含用户层、应用层、大模型层、向量数据库层、数据源层等五层结构"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {},
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成企业 AI 知识库系统分层架构图的 {out-type:提示词}",
+            "inputs": [
+              {
+                "type": "描述",
+                "value": "场景二:系统架构图\n03\n什么时候用:你要讲一个系统\"由哪几层、哪几块搭起来\",用它。\n我那张知识库架构图就是典型,从上到下分用户层、应用层、大模型层、向量库、数据源。它跟流程图的不一样还在第三格,流程图是\"先后\",架构图是\"\n分层 + 包含\n\",上层调用下层,不是一条线走到底。",
+                "anchor": "← 工序输入"
               }
             ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "提示词",
+                "value": "帮我画一张企业 AI 知识库系统的分层架构图。\n整体从上到下分为五层:\n- 用户层:员工、客服、管理员;\n- 应用层:智能问答、文档检索、知识管理后台;\n- 大模型层:负责理解和生成;\n- 向量数据库层:负责知识的存储和语义检索;\n- 数据源层:企业文档、产品手册、历史工单。\n请用从上到下的分层结构来表现,上层调用下层,层与层之间用箭头表示调用关系,每一层内部的模块用并列的小方块横向排开。\n风格:商务科技风,扁平化,配色专业冷静(蓝灰色系即可)。\n所有文字用中文,标签清晰,不要乱码。",
+                "anchor": "→ s2"
+              }
+            ]
+          },
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
             "effect": "主体生成",
             "action": "生成/元素生成",
-            "substance": "信息图",
-            "form": "商务正式",
-            "intent": "用 {via:GPT-IMAGE-2} {act:元素生成} {in-type:提示词},得到 {out-type:成品图}"
-          },
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格:商务科技风,扁平化,配色专业冷静(蓝灰色系即可)。所有文字用中文,标签清晰,不要乱码。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成 {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张企业 AI 知识库系统的分层架构图。\n整体从上到下分为五层:\n- 用户层:员工、客服、管理员;\n- 应用层:智能问答、文档检索、知识管理后台;\n- 大模型层:负责理解和生成;\n- 向量数据库层:负责知识的存储和语义检索;\n- 数据源层:企业文档、产品手册、历史工单。\n请用从上到下的分层结构来表现,上层调用下层,层与层之间用箭头表示调用关系,每一层内部的模块用并列的小方块横向排开。\n风格:商务科技风,扁平化,配色专业冷静(蓝灰色系即可)。\n所有文字用中文,标签清晰,不要乱码。",
+                "anchor": "← s1o1"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张企业 AI 知识库系统的分层架构图,从上到下分为用户层、应用层、大模型层、向量数据库层、数据源层,商务科技风,扁平化>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "id": "p4",
+        "name": "复杂框架结构图生成",
+        "purpose": "使用 AI 绘制一张体现清晰层级和并列关系的复杂框架结构图",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "框架层级与并列关系描述",
+              "desc": "包含总目标、三个并列核心模块、四个并列成果/产出及上下层支撑关系"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {},
+        "steps": [
           {
-            "id": "s3",
+            "id": "s1",
             "kind": "step",
             "via": "human",
-            "directive": "按场景选择合适的图表类型,并根据需求调整风格。",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成复杂框架结构图的 {out-type:提示词}",
             "inputs": [
               {
-                "type": "{'type': '具体场景应用示例列表'}",
-                "value": "五大典型场景应用示例",
-                "anchor": ""
+                "type": "描述",
+                "value": "场景三:复杂框架图\n04\n这其实是难度最大,但是我觉得可能使用率最高的一种类型。\n组织结构、申报书的框架图、一套方案的结构关系,这种既有层级又有并列、关系还挺绕的,用它。\n难就难在关系最复杂,它经常是又有层级、又有并列。比如有人问过的\"三融合四共生\"那种申报书框架:顶上一个总目标,下面挂三个并列的\"融合\"模块,这三个又共同支撑底下四个并列的\"共生\"成果。\n上下是层级、左右是并列,两种关系叠在一起,第三格就得分开交代清楚。",
+                "anchor": "← 工序输入"
               }
             ],
             "outputs": [
               {
-                "id": "s3o1",
-                "type": "{'id': 's3o1', 'type': '风格化调整指南'}",
-                "value": "场景一:业务/工作流程图;场景二:系统架构图;场景三:复杂框架图;场景四:概念解释图;场景五:信息总结图",
-                "anchor": ""
+                "id": "s1o1",
+                "type": "提示词",
+                "value": "帮我画一张【项目名称】的框架结构图,体现清晰的层级和并列关系。\n最顶层是总目标:【一句话总目标】。\n第二层是三个并列的核心模块,横向排开、地位平等:【模块一】、【模块二】、【模块三】。这三个模块共同支撑顶层目标,用箭头向上指向总目标。\n第三层是四个并列的成果/产出,横向排开:【成果一】、【成果二】、【成果三】、【成果四】。它们由上面三个核心模块共同支撑,用箭头表示支撑关系。\n请注意:上下层之间是\"支撑/统领\"的层级关系,用纵向连接;同一层内部的模块是平等并列关系,横向对齐、大小一致。\n风格:商务正式、严谨清晰,适合放进申报书/汇报材料,配色稳重。\n所有文字用中文,清晰可辨认。",
+                "anchor": "→ s2"
+              }
+            ]
+          },
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格:商务正式、严谨清晰,适合放进申报书/汇报材料,配色稳重。所有文字用中文,清晰可辨认。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成复杂框架结构图的 {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张【项目名称】的框架结构图,体现清晰的层级和并列关系。\n最顶层是总目标:【一句话总目标】。\n第二层是三个并列的核心模块,横向排开、地位平等:【模块一】、【模块二】、【模块三】。这三个模块共同支撑顶层目标,用箭头向上指向总目标。\n第三层是四个并列的成果/产出,横向排开:【成果一】、【成果二】、【成果三】、【成果四】。它们由上面三个核心模块共同支撑,用箭头表示支撑关系。\n请注意:上下层之间是\"支撑/统领\"的层级关系,用纵向连接;同一层内部的模块是平等并列关系,横向对齐、大小一致。\n风格:商务正式、严谨清晰,适合放进申报书/汇报材料,配色稳重。\n所有文字用中文,清晰可辨认。",
+                "anchor": "← s1o1"
               }
             ],
-            "effect": "交付",
-            "action": "获取/查询/调取",
-            "intent": "用 {via:human} {act:调取} {in-type:具体场景应用示例列表},得到 {out-type:风格化调整指南}",
-            "substance": "信息图",
-            "form": "商务正式"
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张体现清晰层级和并列关系的框架结构图,包含顶层总目标、第二层三个并列核心模块、第三层四个并列成果,商务正式、严谨清晰风格>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
           }
-        ],
-        "type_registry": {
-          "用户需求描述": {
-            "desc": "职场信息图的初步构思",
-            "extends": "提示词"
-          },
-          "具体场景应用示例列表": {
-            "desc": "五大典型场景的示例",
-            "extends": "模板"
+        ]
+      },
+      {
+        "id": "p5",
+        "name": "概念解释图生成",
+        "purpose": "使用 AI 绘制一张解释核心概念与支撑能力关系的现代简洁概念图",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "核心概念与支撑模块描述",
+              "desc": "包含中心概念及环绕其周围的并列支撑能力模块"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {},
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成概念解释图的 {out-type:提示词}",
+            "inputs": [
+              {
+                "type": "描述",
+                "value": "场景四:概念解释图\n05\n一个抽象概念、一套能力,想用一张图让人秒懂,就用它。\n比如\"AI Agent 怎么像人一样完成任务\",光用文字讲半天对方还懵,画成图几个能力模块一摆就清楚。它的重点跟前面不一样,不强调先后也不强调分层,强调的是\n一个核心概念拆成几个并列模块摆在周围\n。",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "提示词",
+                "value": "帮我画一张解释\"AI Agent 如何像人类一样完成任务\"的概念图。\n画面中心是\"AI Agent\"。\n围绕中心,并列展开它的四个核心能力模块,每个模块配一个直观的小图标:\n- 感知:理解任务和环境;\n- 规划:把大任务拆成小步骤;\n- 行动:调用工具去执行;\n- 记忆:记住上下文和过往经验。\n请把这四个能力模块均匀环绕在中心\"AI Agent\"周围,用线条与中心相连,体现\"中心概念 + 支撑能力\"的关系。\n风格:现代、简洁、科技感,扁平化插画风,配色明快。\n所有文字用中文,清晰可辨认。",
+                "anchor": "→ s2"
+              }
+            ]
           },
-          "风格化调整指南": {
-            "extends": "知识库",
-            "desc": "不同场景下的风格调整建议"
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格:现代、简洁、科技感,扁平化插画风,配色明快。所有文字用中文,清晰可辨认。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成概念解释图的 {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张解释\"AI Agent 如何像人类一样完成任务\"的概念图。\n画面中心是\"AI Agent\"。\n围绕中心,并列展开它的四个核心能力模块,每个模块配一个直观的小图标:\n- 感知:理解任务和环境;\n- 规划:把大任务拆成小步骤;\n- 行动:调用工具去执行;\n- 记忆:记住上下文和过往经验。\n请把这四个能力模块均匀环绕在中心\"AI Agent\"周围,用线条与中心相连,体现\"中心概念 + 支撑能力\"的关系。\n风格:现代、简洁、科技感,扁平化插画风,配色明快。\n所有文字用中文,清晰可辨认。",
+                "anchor": "← s1o1"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张解释 AI Agent 如何像人类一样完成任务的概念图,中心是 AI Agent,周围环绕感知、规划、行动、记忆四个能力模块,现代简洁科技感扁平化插画风>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
           }
-        }
+        ]
       },
       {
-        "id": "p2",
-        "name": "",
-        "purpose": "",
-        "category": "",
-        "platform": "",
-        "author": "",
+        "id": "p6",
+        "name": "信息总结图生成",
+        "purpose": "使用 AI 将大段文字提炼并绘制成一张极简清爽的信息总结图(知识卡片)",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
         "declarations": {
-          "inputs": [],
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "待总结的文本内容",
+              "desc": "用户提供的一大段文章、段落或课程笔记"
+            }
+          ],
           "resources": [],
           "returns": {
-            "type": "风格化调整指南"
+            "type": "成品图"
           }
         },
+        "type_registry": {},
         "steps": [
           {
-            "id": "s3",
+            "id": "s1",
             "kind": "step",
-            "via": "AI总结工具",
+            "via": "human",
+            "effect": "预处理",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "",
+            "intent": "由 {via:human} 编写用于生成信息总结图的 {out-type:提示词}",
             "inputs": [
               {
-                "type": "文章/笔记内容",
+                "type": "描述",
+                "value": "场景五:信息总结图\n06\n什么时候用:你手上有一大段文字、一篇文章、一节课的内容,想浓缩成一张能转发能收藏的图,用它。这类我最近用得越来越多,好处是你甚至\n不用自己提炼\n,整段甩给它,让它替你又总结又画。",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "提示词",
                 "value": "下面这段内容,帮我提炼成一张信息总结图(也叫知识卡片)。\n【在这里把你要总结的文章、段落或课程笔记整段粘贴进来】\n要求:自己提炼出 4 到 6 个核心要点,每个要点用一个小标题 + 一句话概括,配一个简单图标;整张图有一个明确的大标题。\n排版要清晰、有条理,像一张可以直接转发到朋友圈的知识卡片。\n风格:极简、清爽,配色不超过三种。\n所有文字用中文,清晰可辨认。",
-                "anchor": "← s2o1"
-              },
+                "anchor": "→ s2"
+              }
+            ]
+          },
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": "扁平化",
+            "directive": "风格:极简、清爽,配色不超过三种。所有文字用中文,清晰可辨认。",
+            "intent": "使用 {via:(AI 生图工具)} 输入 {in-type:提示词} 生成信息总结图的 {out-type:成品图}",
+            "inputs": [
               {
                 "type": "提示词",
                 "value": "下面这段内容,帮我提炼成一张信息总结图(也叫知识卡片)。\n【在这里把你要总结的文章、段落或课程笔记整段粘贴进来】\n要求:自己提炼出 4 到 6 个核心要点,每个要点用一个小标题 + 一句话概括,配一个简单图标;整张图有一个明确的大标题。\n排版要清晰、有条理,像一张可以直接转发到朋友圈的知识卡片。\n风格:极简、清爽,配色不超过三种。\n所有文字用中文,清晰可辨认。",
-                "anchor": ""
+                "anchor": "← s1o1"
               }
             ],
             "outputs": [
               {
-                "id": "s3o1",
-                "type": "知识卡片图",
-                "value": "<一张信息总结知识卡片,包含4-6个核心要点及图标,极简风格>",
-                "anchor": ""
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张极简清爽的信息总结图,包含4到6个核心要点,每个要点有小标题和一句话概括,配有简单图标,整张图有明确大标题,适合朋友圈转发的知识卡片>",
+                "anchor": "→ 返回 成品图"
               }
-            ],
-            "effect": "后期",
-            "action": "修改/变/调整",
-            "substance": "知识卡片",
-            "form": "极简",
-            "intent": "用 {via:AI总结工具} {act:调整} {in-type:提示词},得到 {out-type:知识卡片图}",
-            "directive": "提炼核心要点,配以图标,排版清晰。"
+            ]
           }
-        ],
-        "type_registry": {
-          "文章/笔记内容": {
-            "desc": "待总结的原始文章内容",
-            "extends": "提示词"
+        ]
+      },
+      {
+        "id": "p7",
+        "name": "信息图风格切换",
+        "purpose": "通过在提示词末尾替换风格词,快速切换信息图的视觉风格",
+        "category": "产物创造",
+        "platform": "微信公众号",
+        "author": "大刘",
+        "declarations": {
+          "inputs": [
+            {
+              "type": "提示词",
+              "name": "通用提示词主体",
+              "desc": "包含图的类型、核心模块、模块关系、输出要求等内容的提示词主体"
+            },
+            {
+              "type": "描述",
+              "name": "目标风格词",
+              "desc": "如白板手绘、手绘插图、极简信息图、扁平化、等距视图、商务正式等风格词"
+            }
+          ],
+          "resources": [],
+          "returns": {
+            "type": "成品图"
+          }
+        },
+        "type_registry": {},
+        "steps": [
+          {
+            "id": "s1",
+            "kind": "step",
+            "via": "human",
+            "effect": "预处理",
+            "action": "修改/变/替换",
+            "substance": "产品",
+            "form": null,
+            "directive": "",
+            "intent": "由 {via:human} 将 {in-type:通用提示词主体} 末尾的风格描述 {in-type:描述} 进行替换,生成 {out-type:提示词}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
+                "anchor": "← 工序输入"
+              },
+              {
+                "type": "描述",
+                "value": "风格问题\n07\n在这个方法论里面,\n如果说换风格,只是在末尾加一个词的事。\n前面那一大段照旧,风格那句换掉就行:白板手绘、手绘插图、极简信息图、扁平化、等距视图、商务正式,照着挑。\n给小朋友看就加\"手绘插图、活泼配色\",放申报书就加\"商务正式、稳重\"。",
+                "anchor": "← 工序输入"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s1o1",
+                "type": "提示词",
+                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
+                "anchor": "→ s2"
+              }
+            ]
           },
-          "知识卡片图": {
-            "extends": "成品图",
-            "desc": "总结后的知识卡片"
+          {
+            "id": "s2",
+            "kind": "step",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "产品",
+            "form": null,
+            "directive": "风格换成指定的风格词。所有文字用中文,清晰可辨认。",
+            "intent": "使用 {via:(AI 生图工具)} 输入替换风格后的 {in-type:提示词} 生成对应风格的 {out-type:成品图}",
+            "inputs": [
+              {
+                "type": "提示词",
+                "value": "帮我画一张企业 AI 智能客服系统的【工作流程图】。\n核心环节有这五个:用户提问、意图识别、知识库检索、生成回答、转人工。\n它们之间是从上到下的先后流程关系,按顺序用箭头连起来;其中\"生成回答\"这一步,如果系统答不上来,要单独引出一个分支,指向\"转人工\"。\n风格用商务正式、扁平化的极简信息图风格,配色干净专业。\n图中所有文字用中文,清晰可辨认,不要出现乱码和英文。",
+                "anchor": "← s1o1"
+              }
+            ],
+            "outputs": [
+              {
+                "id": "s2o1",
+                "type": "成品图",
+                "value": "<一张对应风格的企业 AI 智能客服系统工作流程图,如白板手绘、手绘插图、等距视图等风格>",
+                "anchor": "→ 返回 成品图"
+              }
+            ]
           }
-        }
+        ]
       }
     ]
   }

+ 65 - 169
examples/process_pipeline/script/search_eval/workflows/人像 真实感 图片 生成 怎么做_A_xhs_69d51b97.json

@@ -89,143 +89,42 @@
   },
   "workflow": {
     "source": {
-      "platform": "",
-      "author": "xhs",
-      "date": "2026-04-07 22:58:31",
-      "url": "https://www.xiaohongshu.com/explore/69d51b97000000001a0370fe",
-      "title": "🔥 拒绝一眼假!4招去除 AI “塑料味”",
-      "excerpt": "宝子们!👋 是不是觉得现在的 AI 画图虽然厉害,但总有一股浓浓的“AI 味”?🤔\n\t\n那种皮肤像塑料一样光滑、光影过于完美、背景假得像建模的感觉,真的很让人出戏!😫\n\t\n其实,只要加对提示词,AI 也能拍出“原相机”级别的真实感!今天就把"
+      "platform": "xhs",
+      "author": "未知",
+      "date": "2024-05-22",
+      "url": null,
+      "title": "拒绝AI塑料味!Midjourney/SD真实感调教指南",
+      "excerpt": "通过引入瑕疵、模拟真实摄影参数、使用否定提示词及具体场景叙事,构建去AI味的真实感人像生成工作流。"
     },
     "procedures": [
       {
         "id": "p1",
-        "name": "真实感人像图片生成",
-        "purpose": "通过引入瑕疵、模拟摄影参数、使用否定提示词及结构化公式,生成告别塑料感、具有原相机真实感的人像图片",
+        "name": "真实感人像生成工作流",
+        "purpose": "通过提示词工程去除AI生成的塑料感,实现原相机级别的真实人像效果",
         "category": "产物创造",
-        "platform": "xhs",
-        "author": "xhs",
+        "platform": "Midjourney/Stable Diffusion",
+        "author": "未知",
         "declarations": {
-          "inputs": [],
+          "inputs": [
+            {
+              "type": "描述",
+              "name": "人像生成需求",
+              "desc": "用户对真实感人像的描述"
+            }
+          ],
           "resources": [],
           "returns": {
             "type": "成品图"
           }
         },
-        "steps": [
-          {
-            "id": "s1",
-            "kind": "step",
-            "via": "human",
-            "directive": "",
-            "inputs": [
-              {
-                "type": "知识库",
-                "value": "🔥 拒绝一眼假!4招去除 AI \"塑料味\"...",
-                "anchor": "← 去AI味教程"
-              }
-            ],
-            "outputs": [
-              {
-                "id": "s1o1",
-                "type": "提示词模板",
-                "value": "总结一下去 AI 味提示词公式\n你可以直接套用这个公式来构建你的提示词:\n\n主体\n定义具体特征,拒绝笼统\n35岁亚裔男性 (35-year-old Asian male), 粗糙的皮肤 (weathered skin), 凌乱的头发 (messy hair)\n\n环境\n增加真实背景\n拥挤的街道 (crowded street), 昏暗的灯光 (dim lighting), 背景虚化 (blurred background)\n\n摄影参数\n模拟真实相机成像\nCanon EOS R5, 35mm film (35mm胶片), f/1.8 aperture (光圈), Natural light (自然光)\n\n质感\n核心去味步骤\nFilm grain (胶片颗粒), Noise (噪点), Raw photo (原片),",
-                "anchor": ""
-              },
-              {
-                "id": "s1o2",
-                "type": "负向提示词",
-                "value": "3d render  (3D 渲染)\n\t\nPlastic skin  (塑料皮肤)\n\t\nAirbrushed  (喷绘/磨皮)\n\t\nCartoon/Illustration  (卡通/插画)\n\t\nSymmetrical",
-                "anchor": ""
-              }
-            ],
-            "effect": "预处理",
-            "action": "提取/化学提取/解构",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "从 {in-type:知识库} 中 {act:解构} 得到去AI味的 {out-type:提示词模板} 和 {out-type:负向提示词}"
-          },
-          {
-            "id": "s2",
-            "kind": "step",
-            "via": "human",
-            "directive": "",
-            "inputs": [
-              {
-                "type": "提示词模板",
-                "value": "总结一下去 AI 味提示词公式\n你可以直接套用这个公式来构建你的提示词:\n\n主体\n定义具体特征,拒绝笼统\n35岁亚裔男性 (35-year-old Asian male), 粗糙的皮肤 (weathered skin), 凌乱的头发 (messy hair)\n\n环境\n增加真实背景\n拥挤的街道 (crowded street), 昏暗的灯光 (dim lighting), 背景虚化 (blurred background)\n\n摄影参数\n模拟真实相机成像\nCanon EOS R5, 35mm film (35mm胶片), f/1.8 aperture (光圈), Natural light (自然光)\n\n质感\n核心去味步骤\nFilm grain (胶片颗粒), Noise (噪点), Raw photo (原片),",
-                "anchor": "← s1o1"
-              },
-              {
-                "type": "负向提示词",
-                "value": "3d render  (3D 渲染)\n\t\nPlastic skin  (塑料皮肤)\n\t\nAirbrushed  (喷绘/磨皮)\n\t\nCartoon/Illustration  (卡通/插画)\n\t\nSymmetrical",
-                "anchor": "← s1o2"
-              }
-            ],
-            "outputs": [
-              {
-                "id": "s2o1",
-                "type": "提示词",
-                "value": "一位 25 岁亚洲女性,穿着宽松卫衣,坐在杂乱咖啡馆,可见皮肤毛孔和雀斑,手持有缺口的马克杯,自然光,胶片颗粒感,Shot on 35mm lens,Raw photo。",
-                "anchor": ""
-              }
-            ],
-            "effect": "预处理",
-            "action": "生成/元素生成",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "根据 {in-type:提示词模板} 和 {in-type:负向提示词} {act:元素生成} 具体的 {out-type:提示词}"
-          },
-          {
-            "id": "s3",
-            "kind": "step",
-            "via": "(AI生图工具)",
-            "directive": "风格贴近参考图,不要过度磨皮,比例 2:3",
-            "inputs": [
-              {
-                "type": "提示词",
-                "value": "一位 25 岁亚洲女性,穿着宽松卫衣,坐在杂乱咖啡馆,可见皮肤毛孔和雀斑,手持有缺口的马克杯,自然光,胶片颗粒感,Shot on 35mm lens,Raw photo。",
-                "anchor": "← s2o1"
-              },
-              {
-                "type": "负向提示词",
-                "value": "3d render  (3D 渲染)\n\t\nPlastic skin  (塑料皮肤)\n\t\nAirbrushed  (喷绘/磨皮)\n\t\nCartoon/Illustration  (卡通/插画)\n\t\nSymmetrical",
-                "anchor": "← s1o2"
-              }
-            ],
-            "outputs": [
-              {
-                "id": "s3o1",
-                "type": "成品图",
-                "value": "<一张25岁亚洲女性坐在杂乱咖啡馆的真实感照片,可见皮肤毛孔和雀斑,自然光,胶片颗粒感>",
-                "anchor": ""
-              }
-            ],
-            "effect": "主体生成",
-            "action": "生成/元素生成",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "用 {via:(AI生图工具)} 结合 {in-type:提示词} 和 {in-type:负向提示词} {act:元素生成} 真实感 {out-type:成品图}"
-          }
-        ],
         "type_registry": {
-          "提示词模板": {
-            "extends": "模板",
-            "desc": "去AI味提示词公式与参数模板"
-          }
-        }
-      },
-      {
-        "id": "p2",
-        "name": "真实感视频生成",
-        "purpose": "在真实感图片提示词基础上,引入运镜参数,生成具有真实晃动感和生活感的AI视频",
-        "category": "产物创造",
-        "platform": "xhs",
-        "author": "xhs",
-        "declarations": {
-          "inputs": [],
-          "resources": [],
-          "returns": {
-            "type": "视频成品"
+          "提示词": {
+            "extends": "提示词",
+            "desc": "用于AI生图的描述性文本"
+          },
+          "负向提示词": {
+            "extends": "负向提示词",
+            "desc": "用于排除AI生成中不希望出现的元素"
           }
         },
         "steps": [
@@ -233,89 +132,86 @@
             "id": "s1",
             "kind": "step",
             "via": "human",
+            "effect": "预处理",
+            "action": "提取/化学提取/反推",
+            "substance": "人像",
+            "form": "真实感",
             "directive": "",
+            "intent": "{via:human} {act:反推} {out-type:提示词} 构建去AI味提示词结构",
             "inputs": [
               {
-                "type": "知识库",
-                "value": "🔥 拒绝一眼假!4招去除 AI \"塑料味\"...",
-                "anchor": "← 去AI味教程"
+                "type": "描述",
+                "value": "公式:主体 + 瑕疵细节 + 环境氛围 + 摄影参数 + 质感词",
+                "anchor": "← 工序输入"
               }
             ],
             "outputs": [
               {
                 "id": "s1o1",
-                "type": "提示词模板",
-                "value": "如果是生成视频 (如 Sora, Runway) ,除了上\n述提示词,还要强调 Camera movement (运\n镜),如 Handheld camera (手持摄影),这种\n轻微的晃动感能极大地增加真实度。",
-                "anchor": ""
+                "type": "提示词",
+                "value": "一位 25 岁亚洲女性,穿着宽松卫衣,坐在杂乱咖啡馆,可见皮肤毛孔和雀斑,手持有缺口的马克杯,自然光,胶片颗粒感,Shot on 35mm lens,Raw photo。",
+                "anchor": "→ s3"
               }
-            ],
-            "effect": "预处理",
-            "action": "提取/化学提取/解构",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "从 {in-type:知识库} 中 {act:解构} 得到视频去AI味的 {out-type:提示词模板}"
+            ]
           },
           {
             "id": "s2",
             "kind": "step",
             "via": "human",
+            "effect": "预处理",
+            "action": "提取/化学提取/反推",
+            "substance": "人像",
+            "form": "真实感",
             "directive": "",
+            "intent": "{via:human} {act:反推} {out-type:负向提示词} 确定排除的AI味元素",
             "inputs": [
               {
-                "type": "提示词模板",
-                "value": "如果是生成视频 (如 Sora, Runway) ,除了上\n述提示词,还要强调 Camera movement (运\n镜),如 Handheld camera (手持摄影),这种\n轻微的晃动感能极大地增加真实度。",
-                "anchor": "← s1o1"
+                "type": "描述",
+                "value": "3d render  (3D 渲染)\n\nPlastic skin  (塑料皮肤)\n\nAirbrushed  (喷绘/磨皮)\n\nCartoon/Illustration  (卡通/插画)\n\nSymmetrical  (绝对对称)",
+                "anchor": "← 工序输入"
               }
             ],
             "outputs": [
               {
                 "id": "s2o1",
-                "type": "提示词",
-                "value": "一位 25 岁亚洲女性,穿着宽松卫衣,坐在杂乱咖啡馆,可见皮肤毛孔和雀斑,手持有缺口的马克杯,自然光,胶片颗粒感,Shot on 35mm lens,Raw photo, Handheld camera, Camera movement",
-                "anchor": "",
-                "inferred": true,
-                "inferred_reason": "原文在视频生成特殊性中指出,在上述提示词基础上,还要强调 Camera movement (运镜),如 Handheld camera (手持摄影),因此推断出该视频提示词。"
+                "type": "负向提示词",
+                "value": "3d render  (3D 渲染)\n\nPlastic skin  (塑料皮肤)\n\nAirbrushed  (喷绘/磨皮)\n\nCartoon/Illustration  (卡通/插画)\n\nSymmetrical  (绝对对称)",
+                "anchor": "→ s3"
               }
-            ],
-            "effect": "预处理",
-            "action": "生成/元素生成",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "根据 {in-type:提示词模板} {act:元素生成} 包含运镜参数的 {out-type:提示词}"
+            ]
           },
           {
             "id": "s3",
             "kind": "step",
-            "via": "(AI视频生成工具)",
-            "directive": "强调轻微晃动感以增加真实度",
+            "via": "(AI 生图工具)",
+            "effect": "主体生成",
+            "action": "生成/元素生成",
+            "substance": "人像",
+            "form": "真实感",
+            "directive": "比例 2:3",
+            "intent": "{via:AI 生图工具} {act:元素生成} {in-type:提示词} 生成真实感人像",
             "inputs": [
               {
                 "type": "提示词",
                 "value": "一位 25 岁亚洲女性,穿着宽松卫衣,坐在杂乱咖啡馆,可见皮肤毛孔和雀斑,手持有缺口的马克杯,自然光,胶片颗粒感,Shot on 35mm lens,Raw photo。",
+                "anchor": "← s1o1"
+              },
+              {
+                "type": "负向提示词",
+                "value": "3d render  (3D 渲染)\n\nPlastic skin  (塑料皮肤)\n\nAirbrushed  (喷绘/磨皮)\n\nCartoon/Illustration  (卡通/插画)\n\nSymmetrical  (绝对对称)",
                 "anchor": "← s2o1"
               }
             ],
             "outputs": [
               {
                 "id": "s3o1",
-                "type": "视频成品",
-                "value": "<一段25岁亚洲女性坐在杂乱咖啡馆的真实感视频,带有手持摄影的轻微晃动感>",
-                "anchor": ""
+                "type": "成品",
+                "value": "<一张具有真实皮肤纹理、自然光影和生活化细节的亚洲女性人像图>",
+                "anchor": "→ 交付"
               }
-            ],
-            "effect": "主体生成",
-            "action": "生成/元素生成",
-            "substance": "人物",
-            "form": "写实",
-            "intent": "用 {via:(AI视频生成工具)} 结合 {in-type:提示词} {act:元素生成} 真实感 {out-type:视频成品}"
+            ]
           }
-        ],
-        "type_registry": {
-          "提示词模板": {
-            "extends": "模板",
-            "desc": "去AI味视频提示词公式与参数模板"
-          }
-        }
+        ]
       }
     ]
   }

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini