{
  "canonical_name": "mova-compact/mova-flat-runner",
  "compilation_id": "pack_15b48d8b4c13428ea9e08badf9047ae0",
  "created_at": "2026-05-15T08:14:49.866117+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=mcp_config, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=mcp_config, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npx -y @leryk1981/mova-flat-runner@3.3.3` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npx -y @leryk1981/mova-flat-runner@3.3.3",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_673f54decc804991b89e4a0b584a812e"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_4ac457c9b7211cbe0fb4550259bcdc1b",
    "canonical_name": "mova-compact/mova-flat-runner",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/mova-compact/mova-flat-runner",
    "slug": "mova-flat-runner",
    "source_packet_id": "phit_18f59bed32d84901b3e0a66c1c505670",
    "source_validation_id": "dval_b9c2ece545924497a3a7cc01468e2261"
  },
  "merchandising": {
    "best_for": "需要工具连接与集成能力，并使用 mcp_host的用户",
    "github_forks": 0,
    "github_stars": 0,
    "one_liner_en": "MCP Registry",
    "one_liner_zh": "MCP Registry",
    "primary_category": {
      "category_id": "tool-integrations",
      "confidence": "medium",
      "name_en": "Tool Integrations",
      "name_zh": "工具连接与集成",
      "reason": "matched_keywords:mcp, github"
    },
    "target_user": "使用 mcp_host, claude, chatgpt 等宿主 AI 的用户",
    "title_en": "mova-flat-runner",
    "title_zh": "mova-flat-runner 能力包",
    "visible_tags": [
      {
        "label_en": "Security & Permissions",
        "label_zh": "安全审查与权限治理",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-security-permissions",
        "type": "product_domain"
      },
      {
        "label_en": "Tool Integration",
        "label_zh": "工具接入扩展",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-tool-integration",
        "type": "user_job"
      },
      {
        "label_en": "Workflow Automation",
        "label_zh": "流程自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-workflow-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Checkpoint Resume",
        "label_zh": "断点恢复流程",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-checkpoint-resume",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_18f59bed32d84901b3e0a66c1c505670",
  "page_model": {
    "artifacts": {
      "artifact_slug": "mova-flat-runner",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npx -y @leryk1981/mova-flat-runner@3.3.3",
          "label": "Node.js / npx · 官方安装入口",
          "source": "https://github.com/mova-compact/mova-flat-runner#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "安全审查与权限治理",
        "工具接入扩展",
        "流程自动化",
        "断点恢复流程",
        "评测体系"
      ],
      "eyebrow": "工具连接与集成",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要工具连接与集成能力，并使用 mcp_host的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "MCP Registry"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "mcp_host, claude, chatgpt",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "mcp_config, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。",
            "category": "配置坑",
            "evidence": [
              "capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt"
            ],
            "severity": "medium",
            "suggested_check": "列出会写入的配置文件、目录和卸载/回滚步骤。",
            "title": "可能修改宿主 AI 配置",
            "user_impact": "安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个配置相关的待验证问题：v3.0.0 — Step Enforcement Runtime",
            "category": "配置坑",
            "evidence": [
              "community_evidence:github | cevd_10b68dae59184a36b21a563722829aed | https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0 | 来源类型 github_release 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：v3.0.0 — Step Enforcement Runtime",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 1,
        "forks": 0,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 0
      },
      "source_url": "https://github.com/mova-compact/mova-flat-runner",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "MCP Registry",
      "title": "mova-flat-runner 能力包",
      "trial_prompt": "# mova-flat-runner - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mova-flat-runner 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude / chatgpt\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: MCP Registry 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-project-overview：Project Overview。围绕“Project Overview”模拟一次用户任务，不展示安装或运行结果。\n2. page-core-tools：Core MCP Tools。围绕“Core MCP Tools”模拟一次用户任务，不展示安装或运行结果。\n3. page-installation-setup：Installation and Setup。围绕“Installation and Setup”模拟一次用户任务，不展示安装或运行结果。\n4. page-architecture：System Architecture。围绕“System Architecture”模拟一次用户任务，不展示安装或运行结果。\n5. page-security-guards：Security Guards。围绕“Security Guards”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-project-overview\n输入：用户提供的“Project Overview”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-core-tools\n输入：用户提供的“Core MCP Tools”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-installation-setup\n输入：用户提供的“Installation and Setup”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-architecture\n输入：用户提供的“System Architecture”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-security-guards\n输入：用户提供的“Security Guards”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-project-overview：Step 1 必须围绕“Project Overview”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-core-tools：Step 2 必须围绕“Core MCP Tools”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-installation-setup：Step 3 必须围绕“Installation and Setup”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-architecture：Step 4 必须围绕“System Architecture”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-security-guards：Step 5 必须围绕“Security Guards”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/mova-compact/mova-flat-runner\n- https://github.com/mova-compact/mova-flat-runner#readme\n- README.md\n- package.json\n- src/index.ts\n- src/types.ts\n- src/client.ts\n- src/schemas.ts\n- smithery.yaml\n- server.json\n- src/package_support.ts\n- src/transports/local_seam_bridge.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mova-flat-runner 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_release: v3.0.0 — Step Enforcement Runtime（https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_release",
              "source": "github",
              "title": "v3.0.0 — Step Enforcement Runtime",
              "url": "https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0"
            }
          ],
          "status": "已收录 1 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "工具连接与集成",
      "desc": "MCP Registry",
      "effort": "安装已验证",
      "forks": 0,
      "icon": "link",
      "name": "mova-flat-runner 能力包",
      "risk": "需复核",
      "slug": "mova-flat-runner",
      "stars": 0,
      "tags": [
        "安全审查与权限治理",
        "工具接入扩展",
        "流程自动化",
        "断点恢复流程",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/mova-compact/mova-flat-runner 项目说明书\n\n生成时间：2026-05-15 07:59:21 UTC\n\n## 目录\n\n- [Project Overview](#page-project-overview)\n- [Core MCP Tools](#page-core-tools)\n- [Installation and Setup](#page-installation-setup)\n- [System Architecture](#page-architecture)\n- [Security Guards](#page-security-guards)\n- [Transport Layer](#page-transport-layer)\n- [Domain Validators](#page-validators)\n- [Data Schemas and Types](#page-data-schemas)\n- [Deployment and Operations](#page-deployment)\n- [Extensibility and Customization](#page-extensibility)\n\n<a id='page-project-overview'></a>\n\n## Project Overview\n\n### 相关页面\n\n相关主题：[Core MCP Tools](#page-core-tools), [Installation and Setup](#page-installation-setup), [System Architecture](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Project Overview\n\n## Introduction\n\n**mova-flat-runner** (`@leryk1981/mova-flat-runner`) is an MCP (Model Context Protocol) server that provides governed AI workflows with human approval gates and audit trails. It enables AI-powered contract execution with built-in compliance controls for workflows such as invoice OCR, AML (Anti-Money Laundering) triage, credit review, and custom contract management. 资料来源：[package.json:1-15]()\n\nThe project serves as the authoritative native MCP connection for the MOVA Operator platform, allowing MCP clients like Claude Desktop and Codex to interact with governed AI workflows through a standardized interface. 资料来源：[README.md:1-30]()\n\n## High-Level Architecture\n\nThe mova-flat-runner implements a layered architecture that bridges MCP clients with the MOVA API backend, providing both remote execution through the MOVA cloud and local execution capabilities.\n\n```mermaid\ngraph TD\n    subgraph \"MCP Clients\"\n        Claude[\"Claude Desktop\"]\n        Codex[\"Codex IDE\"]\n    end\n\n    subgraph \"Mova Flat Runner\"\n        MCPServer[\"MCP Server Entry Point<br/>dist/index.js\"]\n        ToolExecutor[\"Tool Executor<br/>executeTool()\"]\n        RemoteAPI[\"Remote API Transport<br/>movaRequest()\"]\n        LocalSeamBridge[\"Local Seam Bridge<br/>local_seam_bridge.ts\"]\n        StepModeGuard[\"Step Mode Guard<br/>step_mode_guard.ts\"]\n    end\n\n    subgraph \"MOVA Backend\"\n        API[\"MOVA API<br/>api.mova-lab.eu\"]\n        ContractDB[\"Contract Registry\"]\n        RunEngine[\"Run Engine\"]\n    end\n\n    Claude --> MCPServer\n    Codex --> MCPServer\n    MCPServer --> ToolExecutor\n    ToolExecutor --> RemoteAPI\n    ToolExecutor --> LocalSeamBridge\n    RemoteAPI --> API\n    LocalSeamBridge --> RunEngine\n    API --> ContractDB\n```\n\n## Project Structure\n\n| Directory | Purpose |\n|-----------|---------|\n| `cmd/` | Application entry points (publisher CLI) |\n| `internal/api/` | HTTP handlers and routing |\n| `internal/auth/` | Authentication (GitHub OAuth, JWT, namespace blocking) |\n| `internal/config/` | Configuration management |\n| `internal/database/` | Data persistence (PostgreSQL) |\n| `internal/service/` | Business logic layer |\n| `internal/telemetry/` | Metrics and monitoring |\n| `internal/validators/` | Input validation |\n| `pkg/` | Public packages |\n| `src/` | Main application source code |\n\n资料来源：[README.md:30-50]()\n\n## Core Source Files\n\n### Entry Point: `dist/index.js`\n\nThe binary entry point is defined in `package.json`:\n\n```json\n{\n  \"bin\": {\n    \"mova-mcp\": \"dist/index.js\"\n  }\n}\n```\n\n资料来源：[package.json:22-24]()\n\nThe server is started using `npx` with the npm package `@leryk1981/mova-flat-runner`:\n\n```bash\nnpx -y @leryk1981/mova-flat-runner@3.3.3\n```\n\n资料来源：[README.md:15-20]()\n\n### Main Server Implementation: `src/index.ts`\n\nThe core implementation handles tool execution through a switch-based `executeTool()` function that routes requests to the appropriate handler. 资料来源：[src/index.ts:200-300]()\n\n#### Tool Categories\n\nThe server exposes the following tool categories:\n\n| Tool Prefix | Purpose |\n|-------------|---------|\n| `mova_run` | Execute built-in contract workflows |\n| `mova_contract` | Register and manage custom contracts |\n| `mova_query` | Query contract status and audit trails |\n| `mova_decide` | Handle decision points |\n| `mova_connector` | External system integration |\n| `mova_health` | Health check operations |\n\n资料来源：[README.md:55-65]()\n\n#### Key Tool Handlers\n\n**`mova_run` Handler** (`src/index.ts`)\n- Validates contract type against built-in manifests\n- Bridges to either remote API or local execution\n- Returns structured JSON responses\n\n**`mova_contract` Actions**:\n- `register`: `POST /api/v1/contracts/register`\n- `run`: `POST /run/{contract_id}`\n- `run_status`: `GET /run/{run_id}/status`\n\n资料来源：[src/index.ts:100-200]()\n\n**`mova_query` Views**:\n- `status`: Returns bridged run status\n- `audit`: Returns audit trail (backend-dependent for custom contracts)\n- `audit_compact`: Returns structured unavailability for custom IDs\n\n资料来源：[tasks/task061.md:1-30]()\n\n### HTTP Transport: `movaRequest()`\n\nAll API communication uses a unified transport layer:\n\n```typescript\nexport const movaGet = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPut = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\nexport const movaPost = (config, path, body) => movaRequest(config, \"POST\", path, body);\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:80-85]()\n\n### Local Seam Bridge: `src/transports/local_seam_bridge.ts`\n\nThe local seam bridge enables local execution of contract steps without requiring remote API calls. It handles:\n\n- **Execution Modes**: `AI_ATOMIC`, `HUMAN_GATE`, `DETERMINISTIC`, `CONTRACT_CALL`\n- **State Management**: Bridge state references and terminal outcomes\n- **Verification**: Pass/fail verification payloads with invariant checks\n\n```typescript\nconst producedOutput =\n  request.step.execution_mode === \"AI_ATOMIC\"\n    ? CANONICAL_STRATEGY\n    : request.stepResult ?? null;\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:1-50]()\n\n#### Bridge Response Structure\n\n| Field | Description |\n|-------|-------------|\n| `status` | `\"completed\"`, `\"advanced\"`, or `\"human_gate_required\"` |\n| `execution_mode` | Step execution mode |\n| `produced_output` | Output data for AI_ATOMIC steps |\n| `gate_required` | Boolean indicating human approval needed |\n| `next_phase` | `\"EXECUTION\"` or `\"WAIT_HUMAN\"` |\n| `verification_payload` | Pass/fail verification checks |\n\n资料来源：[src/transports/local_seam_bridge.ts:15-30]()\n\n### Security: `src/security/step_mode_guard.ts`\n\nThe step mode guard validates that contract step definitions conform to their declared execution modes:\n\n| Violation Type | Condition |\n|----------------|-----------|\n| `deterministic_with_model` | DETERMINISTIC step has a `model` field |\n| `ai_atomic_without_model` | AI_ATOMIC step missing `model` field |\n| `contract_call_without_contract_id` | CONTRACT_CALL step missing `contract_id` |\n| `human_gate_without_decisions` | HUMAN_GATE step missing `decision_options` |\n\n```typescript\nexport function findStepModeViolations(flow): Violation[] {\n  // Validates each step's execution_mode against its required fields\n}\n\nexport function assertStepModesValid(flow, requestId): FlatRunnerResult | null {\n  // Returns error result if violations found\n}\n```\n\n资料来源：[src/security/step_mode_guard.ts:1-80]()\n\n### Package Support: `src/package_support.ts`\n\nContract packages are validated for structural integrity before execution:\n\n```typescript\nfunction validateGlobalShape(value: unknown): string | null {\n  // Validates global file structure:\n  // - schema_id: \"contract_package_global_v1\"\n  // - version: required string\n  // - semantic_roles: non-empty array\n  // - non_authority_rules: non-empty array\n}\n\nfunction validatePackageManifestShape(value: unknown): string | null {\n  // Validates manifest structure:\n  // - Allowed keys: schema_id, package_id, version, flow_ref, etc.\n  // - Required strings: package_id, version, flow_ref\n}\n```\n\n资料来源：[src/package_support.ts:1-50]()\n\n## Configuration\n\n### Required Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_URL` | MOVA API base URL | `https://api.mova-lab.eu` |\n| `MOVA_API_KEY` | MOVA API authentication key | — |\n| `LLM_KEY` | OpenRouter API key for LLM analysis | — |\n| `LLM_MODEL` | OpenRouter model ID | `openai/gpt-4o-mini` |\n\n### Optional Local HTTP Mode Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_TIMEOUT_MS` | API request timeout | `30000` |\n| `MOVA_HTTP_PORT` | Local HTTP server port | `3796` |\n| `MOVA_INVOKE_TOKEN` | Local invoke authentication token | — |\n\n### Local Sandbox Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | Contract package location | `D:\\Projects_MOVA\\mova-intent\\contracts\\dockerfile-nodejs-v1` |\n| `MOVA_SANDBOX_PROJECT_PATH` | Project directory | (required) |\n| `MOVA_SANDBOX_STATE_FILE` | State persistence file | System temp directory |\n\n资料来源：[README.md:35-60]()\n\n## MCP Server Configuration\n\n### Claude Desktop Example\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n### Codex Config Example (TOML)\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:60-100]()\n\n## Build System\n\n### Available Make Targets\n\n| Target | Purpose |\n|--------|---------|\n| `make publisher` | Build the MCP publisher CLI |\n| `make check` | Run lint, unit tests, and integration tests |\n| `make help` | Display all available commands |\n\n资料来源：[README.md:10-20]()\n\n### Build Scripts (package.json)\n\n| Script | Description |\n|--------|-------------|\n| `npm run build` | Compile TypeScript and add shebang |\n| `npm run test:build` | Validate built output |\n| `npm run smoke:custom-bridge` | Smoke test for custom contract bridge |\n\n资料来源：[package.json:25-30]()\n\n### Server Registry Configuration\n\nThe `server.json` file defines the MCP server schema for the Model Context Protocol registry:\n\n```json\n{\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\",\n  \"description\": \"Governed AI workflows with human approval gates and audit trails\"\n}\n```\n\n资料来源：[server.json:1-15]()\n\n## Workflow Execution Modes\n\nThe system supports four execution modes for contract steps:\n\n```mermaid\ngraph LR\n    subgraph \"Execution Modes\"\n        AI[\"AI_ATOMIC<br/>LLM-driven step\"]\n        DET[\"DETERMINISTIC<br/>Local JS validation\"]\n        CALL[\"CONTRACT_CALL<br/>Cross-contract invocation\"]\n        GATE[\"HUMAN_GATE<br/>Human approval required\"]\n    end\n\n    AI --> Output1[\"Produces structured output\"]\n    DET --> Output2[\"Validation result\"]\n    CALL --> Output3[\"Sub-contract result\"]\n    GATE --> Output4[\"Awaiting decision\"]\n```\n\n| Mode | Model Field | Additional Fields | Use Case |\n|------|-------------|-------------------|----------|\n| `AI_ATOMIC` | Required | Output schema path | LLM analysis and decision-making |\n| `DETERMINISTIC` | Forbidden | — | Local validation logic |\n| `CONTRACT_CALL` | Optional | `contract_id` | Invoke another contract |\n| `HUMAN_GATE` | Optional | `decision_options` | Manual approval checkpoints |\n\n资料来源：[src/security/step_mode_guard.ts:30-70]()\n\n## Custom Contract Bridge\n\nThe mova-flat-runner implements a **Custom Query Bridge** to handle custom contract visibility across different API namespaces:\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant MFR as mova-flat-runner\n    participant Bridge as Custom Run Bridge\n    participant API as MOVA API\n\n    Note over Client,MFR: Contract Registration & Run\n    Client->>MFR: mova_contract register\n    MFR->>API: POST /api/v1/contracts/register\n    API-->>MFR: contract_id\n    MFR->>MFR: rememberCustomRun(contract_id, run_id)\n\n    Note over Client,MFR: Custom Query Flow\n    Client->>MFR: mova_query (404 from API)\n    MFR->>Bridge: Check CUSTOM_RUN_BRIDGE\n    Bridge-->>MFR: run_id mapping exists\n    MFR->>API: GET /api/v1/contracts/my\n    API-->>MFR: contract metadata\n    MFR-->>Client: Bridged status response\n```\n\n**Bridge Behavior**:\n- On `mova_contract run` and `run_status`: captures `contract_id -> run_id` mapping\n- On `mova_query status` (404): probes `/api/v1/contracts/my` and returns bridged status\n- On `mova_query audit` (404): returns honest `AUDIT_UNAVAILABLE` envelope\n\n资料来源：[tasks/task061.md:1-60]()\n\n## Security Considerations\n\n### API Key Management\n\n> **Security Note**: Do not commit real `MOVA_API_KEY`, `LLM_KEY`, or `MOVA_INVOKE_TOKEN`. 资料来源：[README.md:70-75]()\n\n### Step Mode Validation\n\nThe step mode guard enforces strict validation before execution:\n- Prevents DETERMINISTIC steps from using LLM models\n- Ensures AI_ATOMIC steps have model configuration\n- Validates HUMAN_GATE steps have decision options\n\n### Human Gate Protection\n\n```typescript\nconst gateGuard = await assertNotHumanGate(config, run_id, step_id, requestId);\nif (gateGuard) return gateGuard;\n```\n\nHuman gate steps cannot be completed via generic `step_complete` — they require the dedicated `gate_approve` / `gate_reject` path. 资料来源：[src/index.ts:200-250]()\n\n## References\n\n- **Repository**: https://github.com/mova-compact/mova-flat-runner\n- **npm Package**: `@leryk1981/mova-flat-runner`\n- **Current Version**: `3.3.4` 资料来源：[package.json:3]()\n- **MCP Registry**: https://registry.modelcontextprotocol.io\n- **API Health Check**: `https://api.mova-lab.eu/health`\n\n---\n\n<a id='page-core-tools'></a>\n\n## Core MCP Tools\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Transport Layer](#page-transport-layer), [System Architecture](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/schemas.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/schemas.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Core MCP Tools\n\n## Overview\n\nThe MOVA Flat Runner is an MCP (Model Context Protocol) server that provides governed AI workflow execution for Claude and MCP-compatible clients. The Core MCP Tools are the primary interface through which clients interact with the system to execute business workflows such as invoice OCR, AML triage, credit review, and custom contracts.\n\nThe tool executor is implemented in `executeTool()` within `src/index.ts` and handles all incoming tool requests via the MCP protocol. Each tool maps to a specific workflow action or API operation, with built-in validation, error handling, and security guards.\n\n资料来源：[src/index.ts:1-50]()\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client\"\n        A[Claude / Cursor / Codex]\n    end\n    \n    subgraph \"MOVA Flat Runner\"\n        B[executeTool dispatcher]\n        C[mova_run]\n        D[mova_contract]\n        E[mova_query]\n        F[mova_health]\n        G[mova_decide]\n        H[mova_connector]\n        I[mova_calibrate_intent]\n        J[step_complete / gate_approve / gate_reject]\n    end\n    \n    subgraph \"Backend Services\"\n        K[MOVA API]\n        L[OpenRouter LLM]\n        M[Local Sandbox]\n    end\n    \n    A --> B\n    B --> C\n    B --> D\n    B --> E\n    B --> F\n    B --> G\n    B --> H\n    B --> I\n    B --> J\n    \n    C --> K\n    D --> K\n    E --> K\n    C --> L\n    I --> L\n    J --> K\n    I --> M\n    \n    style B fill:#f9f,stroke:#333\n```\n\n## Available Tools Summary\n\n| Tool | Purpose | Primary API Endpoint |\n|------|---------|---------------------|\n| `mova_run` | Execute built-in contract workflows | `POST /api/v1/contracts/{id}/run` |\n| `mova_contract` | Register and run custom contracts | `POST /api/v1/contracts/register` |\n| `mova_query` | Query contract status, audit, and audit_compact | `GET /api/v1/contracts/{id}` |\n| `mova_health` | Health check for MOVA API | `GET /health` |\n| `mova_decide` | Submit human decision at approval gate | `POST /run/{run_id}/decision` |\n| `mova_connector` | Connect to external data sources | Internal service routing |\n| `mova_calibrate_intent` | Convert natural language to contract | LLM + local sandbox |\n| `step_complete` | Mark a step as complete | `POST /run/{run_id}/step/{step_id}/complete` |\n| `gate_approve` | Approve human gate | `POST /run/{run_id}/gate/approve` |\n| `gate_reject` | Reject human gate | `POST /run/{run_id}/gate/reject` |\n| `run_status` | Check run status | `GET /run/{run_id}/status` |\n\n资料来源：[src/index.ts:180-220]()\n\n## Tool Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant MCP as MOVA Flat Runner\n    participant API as MOVA Backend API\n    participant LLM as OpenRouter LLM\n    participant Sandbox as Local Sandbox\n\n    Client->>MCP: executeTool(name, args)\n    MCP->>MCP: validateArgs(args)\n    \n    alt Built-in Contract\n        MCP->>MCP: resolveManifest(contract_type)\n        MCP->>API: movaRunStepsRemote()\n        API-->>MCP: step results\n    end\n    \n    alt Custom Contract\n        MCP->>API: mova_contract register/run\n        API-->>MCP: run_id\n        MCP->>MCP: rememberCustomRun()\n    end\n    \n    alt Human Gate Required\n        MCP-->>Client: {status: \"waiting_human\", options: [...]}\n        Client->>MCP: mova_decide / gate_approve / gate_reject\n        MCP->>API: POST /run/{run_id}/decision\n    end\n    \n    alt AI Atomic Step\n        MCP->>LLM: analyze(inputs)\n        LLM-->>MCP: analysis result\n    end\n    \n    MCP-->>Client: final result\n```\n\n## Core Tools Detail\n\n### mova_run\n\nExecutes built-in contract workflows using predefined manifests. Built-in contracts include invoice OCR, AML triage, credit review, and supplier screening.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `contract_type` | string | Yes | The type of contract to execute (e.g., \"invoice_ocr\", \"aml_triage\") |\n| `inputs` | object | Yes | Initial inputs for the contract workflow |\n\n**Workflow:**\n\n1. Resolves the contract manifest from `CONTRACT_MANIFESTS`\n2. Initializes the contract via `POST /api/v1/contracts/{id}/run`\n3. Executes steps remotely via `movaRunStepsRemote()`\n4. Returns structured response with status and outputs\n\n**Security Validation:**\n\nThe `step_mode_guard.ts` validates that:\n- `AI_ATOMIC` steps have a `model` field defined\n- `DETERMINISTIC` steps do NOT have a `model` field\n- `CONTRACT_CALL` steps have a `contract_id` field\n- `HUMAN_GATE` steps have `decision_options` array\n\n资料来源：[src/index.ts:200-280]()\n\n### mova_contract\n\nHandles custom contract registration and execution. Custom contracts can be created via natural language using `mova_calibrate_intent` or by registering existing contract definitions.\n\n**Actions:**\n\n| Action | Description | API Endpoint |\n|--------|-------------|---------------|\n| `register` | Register a new contract definition | `POST /api/v1/contracts/register` |\n| `run` | Execute a custom contract | `POST /run/{contract_id}` |\n| `run_status` | Check custom contract run status | `GET /run/{run_id}/status` |\n\n**Custom Run Bridge:**\n\nWhen a custom contract is run, the system captures and persists a `contract_id -> run_id` mapping in `CUSTOM_RUN_BRIDGE`:\n\n```typescript\nconst ref = { run_id: runId, updated_at: new Date().toISOString() };\nif (typeof sourceUrl === \"string\" && sourceUrl.length > 0)\n    ref.source_url = sourceUrl;\nCUSTOM_RUN_BRIDGE.set(contractId, ref);\n```\n\nThis bridge enables `mova_query` to return status for custom contracts that may not exist in the standard contracts API namespace.\n\n资料来源：[src/index.ts:280-350]()\n\n### mova_query\n\nQueries contract status, audit records, and compact audit information. This tool provides visibility into contract execution state and historical audit trails.\n\n**Views:**\n\n| View | Description | Response Format |\n|------|-------------|-----------------|\n| `status` | Current contract/run status | Bridged status with `bridge_mode=custom_contract_run_namespace_bridge_v1` for custom contracts |\n| `audit` | Full audit record | Returns `AUDIT_UNAVAILABLE` envelope when backend namespace is absent |\n| `audit_compact` | Compact audit summary | Structured unavailable object with `ok=false, status=424` |\n\n**On 404 Response:**\n\nWhen the API returns 404, `mova_query` probes `/api/v1/contracts/my` to check if the contract exists in the user's contract list. If found via `CUSTOM_RUN_BRIDGE`, it returns bridged status rather than a 404 error.\n\n资料来源：[src/index.ts:350-420]()\n\n### mova_health\n\nPerforms a health check on the MOVA API backend.\n\n**Endpoint:** `GET /health`\n\n**Response:** Returns health status of the MOVA API service.\n\n资料来源：[server.json:1-50]()\n\n### mova_decide\n\nSubmits human decision at an approval gate. This is the primary mechanism for human-in-the-loop (HITL) interactions.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `option_id` | string | Yes | The selected decision option |\n\n**Flow:**\n\n1. Fetches decision point from `GET /api/v1/contracts/{contractId}/decision`\n2. Presents `question` and `options` to the human\n3. Human selects an `option_id`\n4. Submits via `POST /run/{run_id}/decision`\n\n资料来源：[src/transports/remote_api.ts:1-80]()\n\n### mova_calibrate_intent\n\nConverts natural language descriptions into structured contract definitions using LLM processing and local sandbox validation.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `description` | string | Yes | Natural language description of the business process |\n| `package_path` | string | No | Path to contract package for sandbox execution |\n| `project_path` | string | No | Path to project files |\n\n**Process:**\n\n1. Sends description to OpenRouter LLM for structured extraction\n2. Validates the generated contract in local sandbox via `resolveLocalSeamLocator()`\n3. Returns validated contract definition ready for registration\n\n资料来源：[src/transports/local_seam_bridge.ts:1-100]()\n\n### step_complete, gate_approve, gate_reject\n\nManagement tools for contract execution state.\n\n**step_complete:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The step to complete |\n| `outcome` | string | No | Outcome identifier (default: \"default\") |\n| `output` | object | No | Step output data |\n\n**Security Guard:** `assertNotHumanGate()` prevents generic `step_complete` from being used on `HUMAN_GATE` steps. Human gates must use the dedicated `gate_approve` / `gate_reject` paths.\n\n**gate_approve:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The gate step |\n| `notes` | string | No | Approval notes |\n\n**gate_reject:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The gate step |\n| `reason` | string | No | Rejection reason |\n\n资料来源：[src/index.ts:420-500]()\n\n## Step Execution Modes\n\nThe MOVA system supports multiple step execution modes for different workflow requirements:\n\n| Mode | Description | Required Fields |\n|------|-------------|-----------------|\n| `AI_ATOMIC` | Single LLM call that must complete atomically | `model`, `prompt` |\n| `DETERMINISTIC` | Local JavaScript evaluation, no LLM | No `model` field |\n| `HUMAN_GATE` | Requires human decision before proceeding | `decision_options` |\n| `CONTRACT_CALL` | Calls another contract | `contract_id` |\n\n资料来源：[src/security/step_mode_guard.ts:1-80]()\n\n## Local Seam Bridge\n\nFor workflows requiring local execution, the `local_seam_bridge.ts` provides an interface to sandboxed contract execution:\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs) {\n    const packagePath = process.env.MOVA_SANDBOX_PACKAGE_PATH \n        ?? \"D:\\\\Projects_MOVA\\\\mova-intent\\\\contracts\\\\dockerfile-nodejs-v1\";\n    const projectPath = process.env.MOVA_SANDBOX_PROJECT_PATH ?? \"\";\n    // ...\n}\n```\n\nThe bridge produces standardized output conforming to the canonical strategy pattern:\n\n```typescript\nreturn {\n    ok: true,\n    bridge: {\n        ok: true,\n        bridge_source: \"mova_flat_runner_canonical_bridge\",\n        status: \"completed\" | \"advanced\" | \"human_gate_required\",\n        execution_mode: request.step.execution_mode,\n        next_phase: { phase: status === \"human_gate_required\" ? \"WAIT_HUMAN\" : \"EXECUTION\" },\n        verification_payload: { status: \"PASS\", checks: [...] }\n    }\n};\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:100-180]()\n\n## Remote API Transport\n\nThe remote API transport (`remote_api.ts`) handles communication with the MOVA backend:\n\n```typescript\nexport const movaGet = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPut = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\n```\n\n**Key endpoints:**\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| `/api/v1/contracts/{contractId}/step` | POST | Execute a step |\n| `/api/v1/contracts/{contractId}/steps/{stepId}/output` | GET | Get step output |\n| `/api/v1/contracts/{contractId}/decision` | GET | Get decision point |\n| `/run/{runId}/decision` | POST | Submit decision |\n| `/run/{runId}/status` | GET | Get run status |\n\n资料来源：[src/transports/remote_api.ts:80-150]()\n\n## Error Handling\n\nAll tools return structured error responses using `flatErr()`:\n\n```typescript\nfunction flatErr(\n    code: string,\n    message: string,\n    context?: Record<string, unknown>,\n    retryable?: boolean,\n    requestId?: string\n): FlatRunnerResult\n```\n\n**Error Codes:**\n\n| Code | Description |\n|------|-------------|\n| `UNKNOWN_CONTRACT_TYPE` | Contract type not found in manifests |\n| `API_REQUEST_FAILED` | Backend API request failed |\n| `STEP_MODE_FIELD_MISMATCH` | Step execution mode doesn't match required fields |\n| `LOCAL_VALIDATION_FAILED` | Local input validation failed |\n\n资料来源：[src/index.ts:500-560]()\n\n## Configuration\n\n### Required Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_KEY` | MOVA API authentication key | Required |\n| `LLM_KEY` | OpenRouter API key for LLM steps | Required |\n| `LLM_MODEL` | OpenRouter model ID | `openai/gpt-4o-mini` |\n| `MOVA_API_URL` | Override API base URL | `https://api.mova-lab.eu` |\n\n### Optional Local HTTP Mode Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_TIMEOUT_MS` | API request timeout | `30000` |\n| `MOVA_HTTP_PORT` | Local HTTP server port | `3796` |\n| `MOVA_INVOKE_TOKEN` | Local invoke authentication | Required for HTTP mode |\n\n资料来源：[server.json:1-50]()\n\n## Resource Schema\n\nThe MCP server exposes resources via `mova://` URI scheme:\n\n| URI | Description |\n|-----|-------------|\n| `mova://registry` | Lists all available contract manifests |\n| `mova://schemas/envelopes` | Envelope schema definitions |\n| `mova://contracts/{type}/manifest` | Individual contract manifest |\n\n资料来源：[src/schemas.ts:1-50]()\n\n## Security Considerations\n\n### Step Mode Validation\n\nThe `step_mode_guard.ts` enforces strict validation on step execution modes:\n\n- Prevents `AI_ATOMIC` steps without a defined model\n- Prevents `DETERMINISTIC` steps from declaring a model\n- Prevents `HUMAN_GATE` steps without decision options\n- Prevents `CONTRACT_CALL` steps without a contract_id\n\n### Human Gate Protection\n\nThe `assertNotHumanGate()` guard prevents generic step completion from bypassing human approval requirements:\n\n```typescript\n// SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion.\n// Human confirmation requires the dedicated gate path (gate_approve / gate_reject).\n```\n\n### Output Sanitization\n\nThe `sanitizePublicShape()` function filters internal bridge metadata from public responses, excluding fields like `bridge_anchors`, `last_terminal_bridge`, `trace`, `outputs`, and `context`.\n\n资料来源：[src/transports/local_seam_bridge.ts:60-90]()\n\n## Quick Reference\n\n### Execute Built-in Contract\n```\ntool: mova_run\nargs: { contract_type: \"invoice_ocr\", inputs: { document: \"...\" } }\n```\n\n### Register and Run Custom Contract\n```\ntool: mova_contract\nargs: { action: \"register\", contract_def: {...} }\n\ntool: mova_contract\nargs: { action: \"run\", contract_id: \"custom-123\", inputs: {...} }\n```\n\n### Query Contract Status\n```\ntool: mova_query\nargs: { contract_id: \"ctr-abc\", view: \"status\" }\n```\n\n### Handle Human Approval\n```\ntool: mova_decide\nargs: { run_id: \"run-xyz\", option_id: \"approve\" }\n\n---\n\n<a id='page-installation-setup'></a>\n\n## Installation and Setup\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation page:\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [smithery.yaml](https://github.com/mova-compact/mova-flat-runner/blob/main/smithery.yaml)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n</details>\n\n# Installation and Setup\n\n## Overview\n\nThe **mova-flat-runner** is an MCP (Model Context Protocol) server that provides governed AI workflow execution with human approval gates and audit trails. It enables clients like Claude Desktop, Cursor, and Codex to interact with MOVA's contract execution engine for invoice OCR, AML triage, credit review, supplier screening, and custom contract workflows.\n\n资料来源：[README.md:1-20]()\n\n## Package Information\n\n| Property | Value |\n|----------|-------|\n| npm Package | `@leryk1981/mova-flat-runner` |\n| Package Version | `3.3.4` |\n| MCP Server Name | `io.github.mova-compact/mova-flat-runner` |\n| Server Registry Version | `2.0.6` |\n| Binary | `mova-mcp` |\n| License | `MIT-0` |\n| Runtime | Node.js (ES Module) |\n\n资料来源：[package.json:2-12](), [server.json:2-8]()\n\n## Prerequisites\n\n### System Requirements\n\n- **Node.js**: Required for running the MCP server\n- **npm** or **npx**: For package installation and execution\n- Network access to `api.mova-lab.eu` (or custom MOVA API endpoint)\n\n### Required API Keys\n\nBefore setup, obtain the following credentials:\n\n| Environment Variable | Required | Description |\n|---------------------|----------|-------------|\n| `MOVA_API_KEY` | Yes | MOVA API key for authentication. Use `test-key-001` for initial testing without registration. |\n| `LLM_KEY` | Yes | OpenRouter API key (`sk-or-v1-...`) for LLM analysis steps |\n| `LLM_MODEL` | No | OpenRouter model ID (default: `openai/gpt-4o-mini`) |\n\n资料来源：[smithery.yaml:35-45](), [server.json:15-28](), [README.md:35-42]()\n\n## Installation Methods\n\n### Method 1: Direct npx Execution\n\nThe simplest installation method uses npx to run the package directly without global installation:\n\n```bash\nnpx -y @leryk1981/mova-flat-runner@3.3.3\n```\n\nThis downloads and executes the specified version on-demand.\n\n资料来源：[README.md:19-20]()\n\n### Method 2: Global npm Installation\n\nInstall the package globally for persistent access:\n\n```bash\nnpm install -g @leryk1981/mova-flat-runner\n```\n\nAfter installation, the `mova-mcp` command becomes available system-wide.\n\n资料来源：[package.json:13-14]()\n\n### Method 3: Building from Source\n\nFor development or custom modifications:\n\n```bash\n# Clone the repository\ngit clone https://github.com/mova-compact/mova-flat-runner.git\ncd mova-flat-runner\n\n# Install dependencies\nnpm install\n\n# Build the TypeScript source\nnpm run build\n```\n\nThe build process compiles TypeScript and adds the shebang header to the output binary:\n\n```bash\n#!/usr/bin/env node\n```\n\n资料来源：[package.json:16-21]()\n\n## Client Configuration\n\n### Claude Desktop Configuration\n\nAdd the MOVA MCP server to your Claude Desktop configuration file:\n\n**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n\n**Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:57-70]()\n\n### Codex Configuration\n\nFor Codex (Cursor) integration, add to your configuration:\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:81-93]()\n\n## Environment Variables Reference\n\n### Core Configuration\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_API_URL` | No | `https://api.mova-lab.eu` | Base URL for MOVA API |\n| `MOVA_API_KEY` | Yes | — | API authentication key |\n| `LLM_KEY` | Yes | — | OpenRouter API key |\n| `LLM_MODEL` | No | `openai/gpt-4o-mini` | LLM model identifier |\n\n资料来源：[README.md:35-48](), [server.json:19-32]()\n\n### Local HTTP Mode (Optional)\n\nFor local execution mode without external API calls:\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout in milliseconds |\n| `MOVA_HTTP_PORT` | No | `3796` | Local HTTP server port |\n| `MOVA_INVOKE_TOKEN` | Conditional | — | Security token for local invocation |\n\n资料来源：[README.md:44-48]()\n\n### Local Seam Sandbox (Advanced)\n\nFor local seam bridge execution:\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | No | (project-specific) | Path to sandbox package |\n| `MOVA_SANDBOX_PROJECT_PATH` | No | — | Path to project directory |\n| `MOVA_SANDBOX_STATE_FILE` | No | (temp file) | Path to state file |\n\n资料来源：[src/transports/local_seam_bridge.ts:1-20]()\n\n## Health Check\n\nVerify the MOVA API connectivity before running workflows:\n\n```bash\ncurl -sS https://api.mova-lab.eu/health\n```\n\n资料来源：[README.md:52-53]()\n\n## Available MCP Tools\n\nOnce installed, the following tools are available:\n\n| Tool | Description |\n|------|-------------|\n| `mova_health` | Check API connectivity |\n| `mova_registry` | List available contract types |\n| `mova_run` | Execute built-in contract workflows |\n| `mova_query` | Query contract status, audit, or audit_compact |\n| `mova_decide` | Submit human decisions at approval gates |\n| `mova_connector` | Connect external data sources |\n| `mova_contract` | Register and run custom contracts |\n\n资料来源：[README.md:54-55]()\n\n## Build and Test Commands\n\nFor development, the following commands are available:\n\n```bash\n# Run lint, unit tests, and integration tests\nmake check\n\n# View all available make targets\nmake help\n\n# Build the publisher CLI\nmake publisher\n\n# Run smoke tests\nnpm run smoke:custom-bridge\n```\n\n资料来源：[README.md:22-29]()\n\n## Security Notes\n\n> **Important**: Never commit real API keys to version control.\n\n- Replace placeholders (`__SET_MOVA_API_KEY__`, `__SET_LLM_KEY__`, `__SET_MOVA_INVOKE_TOKEN__`) with actual credentials only in local configuration files\n- The MCP registry provides server listings but does not transmit secrets\n- Local invocation tokens should be used for secure local HTTP mode\n\n资料来源：[README.md:49-51](), [README.md:56-57]()\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    A[Claude Desktop / Codex] -->|MCP Protocol| B[mova-mcp Server]\n    B --> C{Execution Mode}\n    C -->|Remote API| D[MOVA API]\n    C -->|Local HTTP| E[Local Seam Bridge]\n    D --> F[Contract Execution Engine]\n    E --> G[Local Sandbox]\n    F --> H[(PostgreSQL)]\n    G --> H\n    D --> I[OpenRouter LLM]\n    E --> I\n```\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| `404 contract not found` | Use `mova_contract` with `action=run` for custom contracts instead of `mova_run` |\n| LLM analysis fails | Verify `LLM_KEY` is set to a valid OpenRouter key |\n| Connection timeout | Increase `MOVA_API_TIMEOUT_MS` or check network connectivity |\n| Human gate not advancing | Use `mova_decide` tool to submit decisions at approval gates |\n\n资料来源：[tasks/task061.md:1-30](), [src/index.ts:150-180]()\n\n## Next Steps\n\nAfter installation:\n\n1. Verify connectivity with `mova_health`\n2. Explore available contracts using `mova_registry`\n3. Run a built-in contract: `mova_run complaint`\n4. Create custom contracts with `mova_contract register`\n\n---\n\n<a id='page-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Security Guards](#page-security-guards), [Transport Layer](#page-transport-layer)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n</details>\n\n# System Architecture\n\n## Overview\n\nThe **mova-flat-runner** is a Model Context Protocol (MCP) server that provides governed AI workflow execution with human approval gates and audit trails. It acts as an intermediary layer between MCP clients (such as Claude Desktop, Codex, or other compatible tools) and the MOVA backend API.\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\nThe architecture follows a transport-agnostic design that supports both local seam execution and remote API integration, enabling flexible deployment scenarios from local development to production environments.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[Claude Desktop] --> B[MCP Protocol]\n        C[Codex] --> B\n        D[Other MCP Clients] --> B\n    end\n\n    subgraph \"mova-flat-runner\"\n        E[MCP Server Entry Point<br/>dist/index.js] --> F[Tool Executor<br/>executeTool]\n        F --> G[Built-in Contracts<br/>CONTRACT_MANIFESTS]\n        F --> H[Custom Contract Bridge<br/>CUSTOM_RUN_BRIDGE]\n        F --> I[Security Layer<br/>step_mode_guard]\n    end\n\n    subgraph \"Transport Layer\"\n        J[Local Seam Bridge<br/>local_seam_bridge.ts] \n        K[Remote API Transport<br/>remote_api.ts]\n    end\n\n    subgraph \"External Services\"\n        L[MOVA API<br/>api.mova-lab.eu]\n        M[OpenRouter LLM<br/>gpt-4o-mini]\n    end\n\n    E --> J\n    E --> K\n    J --> M\n    K --> L\n    L --> M\n```\n\n## Core Components\n\n### MCP Server Entry Point\n\nThe MCP server is implemented as a stdio-based transport server that conforms to the Model Context Protocol specification. The server binary is located at `dist/index.js` and is invoked via the `mova-mcp` command.\n\n资料来源：[package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n\n### Tool Executor (`executeTool`)\n\nThe central dispatch mechanism routes incoming tool requests to appropriate handlers based on the tool name. The executor supports the following tool categories:\n\n| Tool Category | Tools | Purpose |\n|--------------|-------|---------|\n| Workflow Execution | `mova_run`, `mova_contract` | Launch contract execution |\n| Query & Status | `mova_query`, `run_status` | Retrieve status and audit |\n| Human Gates | `gate_approve`, `gate_reject` | Human decision handling |\n| System | `mova_health`, `mova_registry` | Health checks and registry |\n\n资料来源：[src/index.ts:168-450](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\nThe executor follows a request-response pattern:\n\n```typescript\nasync function executeTool(name: string, args: Args): Promise<string> {\n  const requestId = shortId();\n  switch (name) {\n    case \"mova_run\": {\n      const contractType = args.contract_type as string;\n      const manifest = CONTRACT_MANIFESTS[contractType];\n      // ... dispatch logic\n    }\n    // ... other cases\n  }\n}\n```\n\n### Contract Manifests (`CONTRACT_MANIFESTS`)\n\nBuilt-in contracts are registered as manifests containing metadata such as:\n\n- `contract_type`: Unique identifier\n- `version`: Contract version\n- `execution_mode`: Runtime behavior (AI_ATOMIC, DETERMINISTIC, HUMAN_GATE, CONTRACT_CALL)\n- `dataspec`: Input field definitions\n- `decision_options`: Available choices for HUMAN_GATE steps\n\n资料来源：[src/index.ts:450-550](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Transport Layer Architecture\n\n### Remote API Transport\n\nThe remote transport handles communication with the MOVA backend API at `https://api.mova-lab.eu`. It provides HTTP methods for all contract operations.\n\n```typescript\nexport const movaGet  = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPost = (config, path, body) => movaRequest(config, \"POST\", path, body);\nexport const movaPut  = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\n```\n\n资料来源：[src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\nThe transport layer performs step execution through a sequential pipeline:\n\n```mermaid\ngraph LR\n    A[Start Contract] --> B[analyze step]\n    B --> C[verify step]\n    C --> D[decide step]\n    D --> E[Execute Validators]\n    E --> F[Return Result]\n```\n\n### Local Seam Bridge\n\nThe local seam bridge enables execution of contracts in a local sandbox environment without requiring remote API connectivity. It constructs a canonical bridge response format.\n\nKey features include:\n- Local project path resolution from environment variables\n- State file management for persistent execution state\n- Sanitization of public shape to filter sensitive fields\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  const excludedKeys = [\"bridge_anchors\", \"last_terminal_bridge\", \n    \"terminal_commit_count\", \"_state15_bridge\", \"trace\", \"outputs\", \"context\"];\n  // ... sanitization logic\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:80-95](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Security Architecture\n\n### Step Mode Guard (`step_mode_guard.ts`)\n\nThe security layer validates that step execution modes are consistent with their declared content fields. This prevents misconfiguration that could lead to security issues.\n\n| Execution Mode | Required Field | Violation If Missing |\n|---------------|----------------|----------------------|\n| `AI_ATOMIC` | `model` | LLM step without model configuration |\n| `DETERMINISTIC` | - (no model allowed) | Model field present in deterministic step |\n| `CONTRACT_CALL` | `contract_id` | Call to undefined contract |\n| `HUMAN_GATE` | `decision_options` | Gate without user choices |\n\n资料来源：[src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n\nThe validation function `assertStepModesValid` returns a structured error when violations are detected:\n\n```typescript\nexport function assertStepModesValid(flow: unknown, requestId: string): FlatRunnerResult | null {\n  const violations = findStepModeViolations(flow);\n  if (violations.length === 0) return null;\n  return flatErr(ERR.STEP_MODE_FIELD_MISMATCH, message, { violations, http_status_equivalent: 400 });\n}\n```\n\n### Human Gate Protection\n\nThe `step_complete` tool includes a guard that prevents completion of HUMAN_GATE steps through the generic completion path, enforcing the dedicated gate approval/rejection flow.\n\n资料来源：[src/index.ts:220-235](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Custom Contract Bridge\n\nA specialized bridge mechanism handles custom contract execution when the contract ID may not exist in the standard query namespace. This resolves the \"custom contract audit identity gap.\"\n\n```mermaid\ngraph TD\n    A[mova_contract register] --> B[POST /api/v1/contracts/register]\n    B --> C[mova_contract run]\n    C --> D[POST /run/{contract_id}]\n    D --> E[rememberCustomRun<br/>Map<contractId, runRef>]\n    E --> F[run_status]\n    F --> G[GET /run/{run_id}/status]\n    G --> H[CUSTOM_RUN_BRIDGE<br/>In-Memory Map]\n    H --> I[mova_query on 404]\n    I --> J{Contract in Bridge?}\n    J -->|Yes| K[Return bridged status]\n    J -->|No| L[Return 404]\n```\n\nThe bridge uses an in-memory `CUSTOM_RUN_BRIDGE` Map to track the relationship between custom contract IDs and their corresponding run IDs.\n\n资料来源：[src/index.ts:100-140](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Purpose |\n|----------|----------|---------|---------|\n| `MOVA_API_URL` | Yes | `https://api.mova-lab.eu` | Backend API endpoint |\n| `MOVA_API_KEY` | Yes | - | Authentication key |\n| `LLM_KEY` | Yes | - | OpenRouter API key |\n| `LLM_MODEL` | No | `openai/gpt-4o-mini` | LLM model identifier |\n| `MOVA_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout |\n| `MOVA_HTTP_PORT` | No | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | No | - | Local invoke authentication |\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\n### Configuration Object (`MovaConfig`)\n\nThe runtime configuration aggregates environment variables and validates required fields:\n\n```typescript\ninterface MovaConfig {\n  apiUrl: string;\n  apiKey: string;\n  llmKey: string;\n  llmModel: string;\n  invokeToken?: string;\n}\n```\n\n## Data Flow\n\n### Contract Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant Server as mova-flat-runner\n    participant API as MOVA API\n    participant LLM as OpenRouter\n\n    Client->>Server: mova_run(contract_type, inputs)\n    Server->>API: POST /run/{contract_id}\n    API->>LLM: Analysis request\n    LLM-->>API: Analysis result\n    API-->>Server: Step result\n    alt AI_ATOMIC step\n        Server->>API: GET /steps/{step_id}/output\n        API-->>Server: Validated output\n    end\n    alt HUMAN_GATE step\n        Server-->>Client: waiting_human status\n        Client->>Server: gate_approve/gate_reject\n        Server->>API: POST /decision\n    end\n    Server-->>Client: Final result\n```\n\n### Local Seam Execution Flow\n\nFor local execution without remote API:\n\n1. Resolve `package_path` and `project_path` from inputs or environment\n2. Execute steps in the local sandbox environment\n3. Apply output sanitization to remove internal fields\n4. Construct canonical bridge response with verification payload\n\n资料来源：[src/transports/local_seam_bridge.ts:95-150](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Package Support and Validation\n\nThe `package_support.ts` module handles contract package validation including:\n\n- Global file structure validation\n- Semantic roles verification\n- Non-authority rules checking\n- Schema path validation\n\n资料来源：[src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n\n## Build and Deployment\n\nThe project uses TypeScript with a custom build script that:\n1. Compiles TypeScript to JavaScript\n2. Injects a shebang for Unix execution\n3. Sets executable permissions on the output binary\n\n```bash\nnpm run build\n```\n\nThe server is published as an npm package `@leryk1981/mova-flat-runner` version `3.3.4` and can be invoked via `npx mova-mcp`.\n\n资料来源：[package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n\n---\n\n<a id='page-security-guards'></a>\n\n## Security Guards\n\n### 相关页面\n\n相关主题：[System Architecture](#page-architecture), [Domain Validators](#page-validators)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/security/class_definition_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/class_definition_guard.ts)\n- [src/security/determinism_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/determinism_guard.ts)\n- [src/security/flow_schema_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/flow_schema_guard.ts)\n- [src/security/gate_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/gate_guard.ts)\n- [src/security/graph_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/graph_guard.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/security/system_contract_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/system_contract_guard.ts)\n</details>\n\n# Security Guards\n\n## Overview\n\nSecurity Guards are a defensive layer in the mova-flat-runner that enforce strict validation rules on MOVA flows before they enter execution. They operate on the principle of **deny-by-default**: any flow containing unknown or potentially dangerous fields is rejected at registration time, preventing malicious or malformed data from persisting into runtime state.\n\nThe guard system addresses specific vulnerability categories identified through security audits (CFV-9, CFV-10, and others), ensuring that privilege-elevation hints, inline class definitions, and execution mode mismatches cannot be smuggled into the system. 资料来源：[src/security/flow_schema_guard.ts:1-15]()\n\n```mermaid\ngraph TD\n    A[Flow Registration] --> B[Security Guards]\n    B --> C{flow_schema_guard<br/>CFV-9}\n    B --> D{class_definition_guard<br/>CFV-10}\n    B --> E{step_mode_guard}\n    B --> F{gate_guard}\n    B --> G{graph_guard}\n    B --> H{determinism_guard}\n    B --> I{system_contract_guard}\n    C --> J{All Guards Pass?}\n    D --> J\n    E --> J\n    F --> J\n    G --> J\n    H --> J\n    I --> J\n    J -->|Yes| K[Flow Accepted]\n    J -->|No| L[Rejection with<br/>FlatRunnerResult]\n```\n\n## Guard Architecture\n\n### Core Principles\n\n| Principle | Description |\n|-----------|-------------|\n| **Strict-by-default** | Any unknown field causes rejection |\n| **Side-effect free at import** | Guards can be imported without triggering validation |\n| **Compositable** | Multiple guards run in sequence, each checking a specific concern |\n| **Audit trail** | Rejections return structured error payloads with remediation hints |\n\n### Guard Registry\n\nEach guard exports two key functions:\n\n1. **Finder function** — Scans the flow and returns a list of violations (returns `string[]` or violation objects)\n2. **Assert function** — Calls the finder, and if violations exist, returns a `FlatRunnerResult` error; otherwise returns `null`\n\n```typescript\n// Standard guard interface pattern\nexport function findXXXViolations(flow: unknown): Violation[] // Finder\nexport function assertXXXValid(flow: unknown, requestId: string): FlatRunnerResult | null // Assert\n```\n\n## Flow Schema Guard (CFV-9)\n\n**File:** `src/security/flow_schema_guard.ts`\n\n### Purpose\n\nThe flow schema guard enforces a strict allow-list of top-level keys in MOVA flow definitions. During a security audit, flows containing `__admin_override`, `__privilege_grant`, and `__debug_mode` were accepted at registration. If these fields were persisted—even silently—an attacker could smuggle privilege-elevation hints into the runtime for future code paths to read. 资料来源：[src/security/flow_schema_guard.ts:1-20]()\n\n### Allowed Top-Level Keys\n\n| Key | Purpose |\n|-----|---------|\n| `version` | Flow schema version |\n| `description` | Human-readable description |\n| `entry` | Entry point step reference |\n| `steps` | Step definitions map |\n| `parallel_steps` | Parallel step definitions |\n| `notes` | Developer notes |\n| `audit_mode` | Audit configuration |\n| `audit_mode_note` | Audit mode explanation |\n| `class_definition_ref` | Reference to registry class |\n| `CONTRACT_CALL_instructions` | Contract invocation instructions |\n| `input_schema` | Input validation schema |\n| `output_schema` | Output validation schema |\n| `metadata` | Additional metadata |\n\n### Implementation\n\n```typescript\nexport const ALLOWED_FLOW_TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n    \"version\",\n    \"description\",\n    \"entry\",\n    \"steps\",\n    \"parallel_steps\",\n    \"notes\",\n    \"audit_mode\",\n    \"audit_mode_note\",\n    \"class_definition_ref\",\n    \"CONTRACT_CALL_instructions\",\n    \"input_schema\",\n    \"output_schema\",\n    \"metadata\",\n]);\n\nexport function findUnknownFlowFields(flow: unknown): string[] {\n    if (!flow || typeof flow !== \"object\" || Array.isArray(flow)) return [];\n    const f = flow as Record<string, unknown>;\n    const out: string[] = [];\n    for (const key of Object.keys(f)) {\n        if (!ALLOWED_FLOW_TOP_LEVEL_KEYS.has(key))\n            out.push(key);\n    }\n    return out;\n}\n```\n\n### Rejection Response\n\nWhen unknown fields are detected:\n\n```json\n{\n    \"ok\": false,\n    \"code\": \"FLOW_SCHEMA_VIOLATION\",\n    \"message\": \"Flow body contains unknown top-level key(s): __admin_override, __debug_mode\",\n    \"details\": {\n        \"unknown_fields\": [\"__admin_override\", \"__debug_mode\"],\n        \"http_status_equivalent\": 400\n    }\n}\n```\n\n## Class Definition Guard (CFV-10)\n\n**File:** `src/security/class_definition_guard.ts`\n\n### Purpose\n\nThe class definition guard prevents inline class definitions within flow bodies. Class definitions define severity bands and noise control parameters that must be resolved from the registry by `class_id`. Embedding them inline creates a vector for policy tampering and bypasses the centralized authority on these security-sensitive values. 资料来源：[src/security/class_definition_guard.ts:1-35]()\n\n### Forbidden Keys\n\n```typescript\nconst FORBIDDEN_FLOW_KEYS: readonly string[] = Object.freeze([\n    \"class_definition\",\n    \"class_definition_ref\",\n    \"class_definition_inline\",\n    \"class_def_override\",\n    \"class_def\",\n]);\n```\n\n### Implementation\n\n```typescript\nexport function findInlineClassDefinitionFields(flow: unknown): string[] {\n    if (!flow || typeof flow !== \"object\") return [];\n    const f = flow as Record<string, unknown>;\n    return FORBIDDEN_FLOW_KEYS.filter((k) => Object.prototype.hasOwnProperty.call(f, k));\n}\n\nexport function assertNoInlineClassDefinition(\n    flow: unknown,\n    requestId: string,\n): FlatRunnerResult | null {\n    const found = findInlineClassDefinitionFields(flow);\n    if (found.length === 0) return null;\n    return flatErr(\n        ERR.INLINE_CLASS_DEFINITION_FORBIDDEN,\n        `Flow body contains inline class-definition field(s): ${found.join(\", \")}. ` +\n        \"Class definitions must be resolved from the registry by class_id.\",\n        {\n            forbidden_fields: found,\n            remediation: \"Remove these fields and reference the class via class_id\",\n            http_status_equivalent: 400,\n        },\n        false,\n        requestId,\n    );\n}\n```\n\n### Defense in Depth\n\nThe flow schema guard (CFV-9) catches any `class_definition*` keys not yet covered by this stricter rule, providing layered protection:\n\n> CFV-10's `class_definition*` keys are blocked specifically by `class_definition_guard.ts`; this guard catches everything else not yet covered by a stricter rule. 资料来源：[src/security/flow_schema_guard.ts:17-20]()\n\n## Step Mode Guard\n\n**File:** `src/security/step_mode_guard.ts`\n\n### Purpose\n\nThe step mode guard validates that each step's `execution_mode` agrees with the fields it contains. MOVA supports multiple execution modes, and each mode has specific field requirements. Mismatches can indicate configuration errors or attempts to bypass intended behavior.\n\n### Execution Mode Requirements\n\n| Mode | Required Field | Forbidden Field |\n|------|---------------|-----------------|\n| `DETERMINISTIC` | — | `model` |\n| `AI_ATOMIC` | `model` | — |\n| `CONTRACT_CALL` | `contract_id` | — |\n| `HUMAN_GATE` | `decision_options` array | — |\n\n### Violation Types\n\n```typescript\ninterface StepModeViolation {\n    kind: string;\n    step_id: string | undefined;\n    execution_mode: string;\n    message: string;\n}\n```\n\n1. **deterministic_with_model** — DETERMINISTIC steps run local JS checks, not LLMs\n2. **ai_atomic_without_model** — AI_ATOMIC requires a model field\n3. **contract_call_without_contract_id** — CONTRACT_CALL requires contract_id\n4. **human_gate_without_decisions** — HUMAN_GATE requires decision_options array\n\n### Implementation\n\n```typescript\nexport function findStepModeViolations(flow: unknown): StepModeViolation[] {\n    const f = flow as Flow;\n    if (!f?.steps) return [];\n    const out: StepModeViolation[] = [];\n\n    for (const [id, step] of Object.entries(f.steps)) {\n        const mode = step.execution_mode ?? \"DETERMINISTIC\";\n\n        if (mode === \"DETERMINISTIC\" && step.model !== undefined) {\n            out.push({\n                kind: \"deterministic_with_model\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is DETERMINISTIC but declares a 'model' field`,\n            });\n        }\n\n        if (mode === \"AI_ATOMIC\" && asStr(step.model) === null) {\n            out.push({\n                kind: \"ai_atomic_without_model\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is AI_ATOMIC but has no 'model' field`,\n            });\n        }\n\n        if (mode === \"CONTRACT_CALL\" && asStr(step.contract_id) === null) {\n            out.push({\n                kind: \"contract_call_without_contract_id\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is CONTRACT_CALL but has no 'contract_id'`,\n            });\n        }\n\n        if (mode === \"HUMAN_GATE\" && !Array.isArray(step.decision_options)) {\n            out.push({\n                kind: \"human_gate_without_decisions\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is HUMAN_GATE but has no 'decision_options' array`,\n            });\n        }\n    }\n    return out;\n}\n```\n\n## Additional Guards\n\n### Gate Guard\n\n**File:** `src/security/gate_guard.ts`\n\nThe gate guard enforces human gate access control, ensuring that human confirmation requires the dedicated gate path. It prevents generic step completion from bypassing human authorization requirements.\n\n### Determinism Guard\n\n**File:** `src/security/determinism_guard.ts`\n\nThe determinism guard ensures deterministic steps produce consistent results and cannot introduce non-deterministic behavior that could compromise reproducibility.\n\n### Graph Guard\n\n**File:** `src/security/graph_guard.ts`\n\nThe graph guard validates the structural integrity of the flow graph, ensuring all step references and dependencies are properly defined and no cycles or invalid references exist.\n\n### System Contract Guard\n\n**File:** `src/security/system_contract_guard.ts`\n\nThe system contract guard monitors system contract usage, preventing unauthorized access to privileged operations.\n\n## Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant MCP as MCP Server\n    participant Guards as Security Guards\n    participant API as MOVA API\n\n    Client->>MCP: mova_contract register(flow)\n    MCP->>Guards: validate(flow)\n    Guards->>Guards: flow_schema_guard\n    Guards->>Guards: class_definition_guard\n    Guards->>Guards: step_mode_guard\n    Guards->>Guards: gate_guard\n    Guards->>Guards: graph_guard\n    Guards->>Guards: determinism_guard\n    Guards->>Guards: system_contract_guard\n    \n    alt All Guards Pass\n        Guards-->>MCP: null (valid)\n        MCP->>API: POST /api/v1/contracts/register\n        API-->>MCP: registration response\n        MCP-->>Client: success\n    else Guard Violation\n        Guards-->>MCP: FlatRunnerResult (error)\n        MCP-->>Client: rejection with details\n    end\n```\n\n## Error Codes\n\n| Code | Guard | Description |\n|------|-------|-------------|\n| `FLOW_SCHEMA_VIOLATION` | flow_schema_guard | Unknown top-level keys |\n| `INLINE_CLASS_DEFINITION_FORBIDDEN` | class_definition_guard | Inline class definition present |\n| `STEP_MODE_FIELD_MISMATCH` | step_mode_guard | Execution mode doesn't match fields |\n| `GATE_ACCESS_DENIED` | gate_guard | Unauthorized gate access attempt |\n| `DETERMINISM_VIOLATION` | determinism_guard | Non-deterministic behavior detected |\n| `GRAPH_STRUCTURE_INVALID` | graph_guard | Invalid flow graph structure |\n| `SYSTEM_CONTRACT_VIOLATION` | system_contract_guard | Unauthorized system contract use |\n\n## Integration Points\n\n### Local Seam Bridge\n\nThe local seam bridge integrates security guards into the transport layer:\n\n> SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion. Human confirmation requires the dedicated gate path (gate_approve / gate_reject). Guard runs BEFORE forwarding so run state is not advanced on rejection. 资料来源：[src/index.ts:1-25]()\n\n### Custom Contract Bridge\n\nSecurity considerations are applied when bridging custom contract runs to ensure audit integrity:\n\n> Safety: Built-in path untouched. No fake audit records introduced. Bridge only activates on 404 in `mova_query`. 资料来源：[tasks/task061.md:1-40]()\n\n## Testing\n\nSecurity guards are validated through:\n\n```bash\n# Run all security checks\nmake check\n\n# Smoke test for custom contract bridge\nnpm run smoke:custom-bridge\n\n# Build validation\nnpm run build\nnpm run test:build\n```\n\n## Best Practices\n\n1. **Never disable guards** — Guards exist to prevent exploitation\n2. **Keep allow-lists updated** — Review `ALLOWED_FLOW_TOP_LEVEL_KEYS` when adding new features\n3. **Report unknown fields** — Fields that legitimately need to pass through should be explicitly allow-listed\n4. **Maintain separation** — Built-in and custom contract paths should have distinct security requirements\n5. **Audit on change** — Any schema change should trigger a security review\n\n---\n\n<a id='page-transport-layer'></a>\n\n## Transport Layer\n\n### 相关页面\n\n相关主题：[System Architecture](#page-architecture), [Core MCP Tools](#page-core-tools), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [dist-test/src/transports/local_seam_bridge.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/local_seam_bridge.js)\n- [dist-test/src/transports/remote_api.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n</details>\n\n# Transport Layer\n\nThe Transport Layer in mova-flat-runner provides the communication infrastructure for executing contract workflows across different execution environments. It abstracts the underlying HTTP communication with the MOVA backend API and provides a local seam bridge for sandboxed contract execution.\n\n## Overview\n\nThe transport layer handles two primary communication patterns:\n\n| Transport Mode | Purpose | Use Case |\n|----------------|---------|----------|\n| **Remote API** | HTTP-based communication with `api.mova-lab.eu` | Production deployments, remote contract execution |\n| **Local Seam Bridge** | In-process contract execution via local sandbox | Development, testing, isolated execution |\n\nThe layer is responsible for:\n- Managing HTTP requests to the MOVA backend\n- Routing contract step execution to appropriate handlers\n- Bridging between local execution context and remote API namespace\n- Sanitizing data shapes for public consumption\n- Handling execution modes (AI_ATOMIC, HUMAN_GATE, DETERMINISTIC, CONTRACT_CALL)\n\n资料来源：[src/transports/local_seam_bridge.ts:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n资料来源：[src/transports/remote_api.ts:1-30](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\n## Architecture\n\n```mermaid\ngraph TD\n    subgraph \"Client Layer\"\n        MCP[MCP Client]\n        CLI[CLI Tools]\n    end\n\n    subgraph \"Transport Layer\"\n        RemoteAPI[Remote API Transport]\n        LocalBridge[Local Seam Bridge]\n    end\n\n    subgraph \"Backend Services\"\n        MOVAAPI[MOVA API<br/>api.mova-lab.eu]\n        LocalSandbox[Local Sandbox]\n    end\n\n    MCP --> |HTTP| RemoteAPI\n    CLI --> |HTTP| RemoteAPI\n    \n    LocalBridge --> |Internal| LocalSandbox\n    RemoteAPI --> |HTTP| MOVAAPI\n\n    RemoteAPI -.-> |fallback| LocalBridge\n```\n\n## Remote API Transport\n\nThe Remote API transport provides HTTP-based communication with the MOVA backend service.\n\n### Core Functions\n\n| Function | Method | Purpose |\n|----------|--------|---------|\n| `movaRequest` | Core | Base HTTP request handler with error wrapping |\n| `movaGet` | GET | Retrieve data from API endpoints |\n| `movaPost` | POST | Submit data to create or trigger actions |\n| `movaPut` | PUT | Update existing resources |\n| `movaDelete` | DELETE | Remove resources |\n\n资料来源：[src/transports/remote_api.ts:50-80](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\n### Request Configuration\n\nThe remote API uses a `MovaConfig` object for authentication and endpoint configuration:\n\n```typescript\ninterface MovaConfig {\n  baseUrl: string;       // API base URL (default: api.mova-lab.eu)\n  apiKey: string;        // API authentication key\n  timeout?: number;       // Request timeout in milliseconds\n  headers?: Record<string, string>;\n}\n```\n\n### API Endpoints\n\nThe transport layer integrates with the following MOVA API endpoints:\n\n| Endpoint Pattern | Method | Usage |\n|-----------------|--------|-------|\n| `/api/v1/contracts/{contractId}` | GET | Query contract metadata |\n| `/api/v1/contracts/{contractId}/step` | POST | Execute a contract step |\n| `/api/v1/contracts/{contractId}/steps/{stepId}/output` | GET | Retrieve step output |\n| `/api/v1/contracts/{contractId}/decision` | GET | Get human decision point |\n| `/api/v1/contracts/my` | GET | List user's contracts |\n| `/run/{runId}/status` | GET | Get run execution status |\n| `/run/{contractId}` | POST | Initiate a contract run |\n\n资料来源：[dist-test/src/transports/remote_api.js:1-60](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n\n## Local Seam Bridge\n\nThe Local Seam Bridge provides an internal bridge for sandboxed contract execution when the local seam backend is available.\n\n### Bridge Invoker\n\nThe `createInternalBridgeInvoker()` function creates a bridge invoker that handles step execution within the local environment:\n\n```typescript\nfunction createInternalBridgeInvoker() {\n  return async function bridgeInvoker(request) {\n    bridgeSequence += 1;\n    const suffix = `${request.step.id}:${bridgeSequence}`;\n    \n    const status =\n      request.step.execution_mode === \"HUMAN_GATE\" && request.humanDecision == null\n        ? \"human_gate_required\"\n        : request.terminalOutcome\n          ? \"completed\"\n          : \"advanced\";\n\n    return {\n      ok: true,\n      bridge: {\n        ok: true,\n        bridge_source: \"mova_flat_runner_canonical_bridge\",\n        status,\n        execution_mode: request.step.execution_mode,\n        next_phase: { phase: status === \"human_gate_required\" ? \"WAIT_HUMAN\" : \"EXECUTION\" },\n        // ... additional bridge fields\n      },\n    };\n  };\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:50-90](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n### Execution Modes\n\nThe bridge handles different execution modes defined by the contract:\n\n| Execution Mode | Behavior | Bridge Output |\n|----------------|----------|---------------|\n| `AI_ATOMIC` | LLM-powered atomic execution | Canonical strategy output with full validation metadata |\n| `HUMAN_GATE` | Requires human decision | Returns `human_gate_required` status, awaits confirmation |\n| `DETERMINISTIC` | Local JavaScript execution | Passes through step result |\n| `CONTRACT_CALL` | Calls another contract | Forwards to referenced contract |\n\n资料来源：[dist-test/src/security/step_mode_guard.js:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/security/step_mode_guard.js)\n\n### Status Handling\n\n```mermaid\ngraph TD\n    A[Step Execution Request] --> B{Execution Mode}\n    \n    B -->|AI_ATOMIC| C[Generate Canonical Output]\n    B -->|HUMAN_GATE| D{Human Decision?}\n    B -->|DETERMINISTIC| E[Pass Through Result]\n    B -->|CONTRACT_CALL| F[Forward to Contract]\n    \n    D -->|No| G[Status: human_gate_required<br/>Phase: WAIT_HUMAN]\n    D -->|Yes| H[Status: advanced<br/>Phase: EXECUTION]\n    \n    C --> I[Return Bridged Response]\n    E --> I\n    F --> I\n    G --> I\n    H --> I\n```\n\n## Data Sanitization\n\nThe transport layer includes a `sanitizePublicShape` function to filter sensitive or internal fields from response data:\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  if (Array.isArray(value)) {\n    return value.every((item) => sanitizePublicShape(item));\n  }\n  \n  const FORBIDDEN_KEYS = [\n    \"bridge_anchors\",\n    \"last_terminal_bridge\", \n    \"terminal_commit_count\",\n    \"_state15_bridge\",\n    \"trace\",\n    \"outputs\",\n    \"context\"\n  ];\n\n  for (const [key, child] of Object.entries(value)) {\n    if (FORBIDDEN_KEYS.includes(key)) {\n      return false;\n    }\n    if (!sanitizePublicShape(child)) {\n      return false;\n    }\n  }\n  return true;\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:120-145](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Package Locator Resolution\n\nThe Local Seam Bridge includes logic to resolve package references for contract execution:\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs) {\n  const packagePath = initialInputs.package_path \n    ?? process.env.MOVA_SANDBOX_PACKAGE_PATH \n    ?? \"D:\\\\Projects_MOVA\\\\mova-intent\\\\contracts\\\\dockerfile-nodejs-v1\";\n    \n  const projectPath = initialInputs.project_path \n    ?? process.env.MOVA_SANDBOX_PROJECT_PATH \n    ?? \"\";\n    \n  if (!projectPath) {\n    throw new Error(\"missing_local_seam_project_path\");\n  }\n  // ... additional resolution logic\n}\n```\n\n资料来源：[dist-test/src/transports/local_seam_bridge.js:80-100](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/local_seam_bridge.js)\n\n## Custom Contract Bridge\n\nFor custom contracts registered outside the standard `/api/v1/contracts` namespace, the transport layer provides a bridge mechanism:\n\n### Bridge Map\n\nThe system maintains an in-memory mapping of custom contracts:\n\n```typescript\nCUSTOM_RUN_BRIDGE: Map<contract_id, {\n  run_id: string,\n  updated_at: string,\n  source_url?: string\n}>\n```\n\n资料来源：[src/index.ts:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n### Custom Query Handling\n\nWhen a contract is not found in the standard namespace, the bridge checks:\n\n1. Local `CUSTOM_RUN_BRIDGE` map for run history\n2. `/api/v1/contracts/my` for contract metadata\n3. `/run/{runId}/status` for execution status\n\n```mermaid\ngraph LR\n    A[mova_query Request] --> B{API 404?}\n    \n    B -->|Yes| C[Check CUSTOM_RUN_BRIDGE]\n    B -->|No| Z[Normal Response]\n    \n    C --> D{Run Found?}\n    D -->|Yes| E[Return Bridged Status]\n    D -->|No| F[Query /contracts/my]\n    \n    F --> G{Record Found?}\n    G -->|Yes| H[Return with Contract Record]\n    G -->|No| I[Return Error]\n```\n\n## Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `MOVA_API_URL` | `https://api.mova-lab.eu` | MOVA API base URL |\n| `MOVA_API_KEY` | - | API authentication key |\n| `MOVA_API_TIMEOUT_MS` | `30000` | Request timeout in milliseconds |\n| `MOVA_HTTP_PORT` | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | - | Token for local HTTP invocation |\n| `MOVA_SANDBOX_PACKAGE_PATH` | - | Package path for local seam |\n| `MOVA_SANDBOX_PROJECT_PATH` | - | Project path for local seam |\n| `MOVA_SCHEMA_PATH` | - | Additional schema lookup path |\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\n## Remote Step Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant RemoteAPI\n    participant MOVA as MOVA Backend\n    \n    Client->>RemoteAPI: movaRunStepsRemote(contractId)\n    \n    loop For each step: analyze, verify, decide\n        RemoteAPI->>MOVA: POST /api/v1/contracts/{id}/step\n        MOVA-->>RemoteAPI: Step result\n        \n        alt step === \"analyze\"\n            RemoteAPI->>MOVA: GET /steps/analyze/output\n            MOVA-->>RemoteAPI: Analysis output\n            Note over RemoteAPI: Apply validators\n        end\n        \n        alt status === \"waiting_human\"\n            RemoteAPI->>MOVA: GET /decision\n            MOVA-->>RemoteAPI: Decision point (question, options)\n            Note over RemoteAPI: Return for human input\n        end\n    end\n    \n    RemoteAPI-->>Client: Aggregated results\n```\n\n## Error Handling\n\nThe transport layer wraps errors with structured error codes:\n\n| Error Code | Description |\n|------------|-------------|\n| `API_REQUEST_FAILED` | HTTP request to backend failed |\n| `AUDIT_UNAVAILABLE` | Audit endpoint not accessible |\n| `CONTRACT_NOT_FOUND` | Contract ID not found in any namespace |\n| `LOCAL_VALIDATION_FAILED` | Local input validation failed |\n| `UNKNOWN_CONTRACT_TYPE` | Contract type not in manifest registry |\n\n资料来源：[dist-test/src/transports/remote_api.js:40-80](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n\n## Testing\n\nThe compiled test files verify transport behavior:\n\n- **dist-test/src/transports/remote_api.js** - Tests for HTTP transport functions\n- **dist-test/src/transports/local_seam_bridge.js** - Tests for local bridge execution\n- **dist-test/src/package_support.js** - Tests for package resolution\n\nTo run tests:\n```bash\nnpm run build\nnpm run test:build\nnpm run smoke:custom-bridge\n\n---\n\n<a id='page-validators'></a>\n\n## Domain Validators\n\n### 相关页面\n\n相关主题：[Data Schemas and Types](#page-data-schemas), [Security Guards](#page-security-guards)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation:\n\n- [src/validators/registry.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/registry.ts)\n- [src/validators/aml.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/aml.ts)\n- [src/validators/churn.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/churn.ts)\n- [src/validators/complaint.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/complaint.ts)\n- [src/validators/compliance.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/compliance.ts)\n- [src/validators/contract_gen.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/contract_gen.ts)\n- [src/validators/credit.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/credit.ts)\n- [src/validators/invoice.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/invoice.ts)\n- [src/validators/po.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/po.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/validators/trade.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/trade.ts)\n- [src/validators/content_flywheel.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/content_flywheel.ts)\n</details>\n\n# Domain Validators\n\nDomain Validators are the core validation layer in MOVA Flat Runner's contract execution engine. They provide domain-specific input validation for each workflow type, ensuring data integrity before contract execution proceeds through subsequent steps.\n\n## Overview\n\nDomain Validators serve as a security boundary and data validation checkpoint within the MOVA contract execution model. Every validator function must be registered in the central `VALIDATOR_REGISTRY` before it can be invoked during contract execution.\n\n资料来源：[src/validators/registry.ts:1-28]()\n\n```mermaid\ngraph TD\n    A[Contract Execution] --> B[ValidatorRef from Manifest]\n    B --> C{Registry Lookup}\n    C -->|Found| D[Execute ValidatorFn]\n    C -->|Not Found| E[VALIDATOR_NOT_ALLOWED Error]\n    D --> F[Return Validation Result]\n    E --> G[Log Error to Analysis]\n    F --> H[Proceed to Next Step]\n    G --> H\n```\n\n## Architecture\n\n### Validator Function Type\n\nAll domain validators conform to the `ValidatorFn` interface defined in the types module:\n\n```typescript\ntype ValidatorFn = (inputs: Record<string, unknown>) => {\n    ok: boolean;\n    value: Record<string, unknown>;\n    step_id: string;\n};\n```\n\n资料来源：[dist-test/src/types.d.ts:1-7]()\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `ok` | `boolean` | Indicates whether validation passed |\n| `value` | `Record<string, unknown>` | Validation results and derived fields |\n| `step_id` | `string` | Identifier of the step being validated |\n\n### Registry Structure\n\nThe registry is implemented as a `Map<string, ValidatorFn>` where keys are validator IDs in the format `{domain}.{validator_name}_v{version}`:\n\n```typescript\nexport const VALIDATOR_REGISTRY = new Map<string, ValidatorFn>(\n  all.map(v => [v.id, v.fn])\n);\n```\n\n资料来源：[src/validators/registry.ts:25-27]()\n\n## Registered Validator Domains\n\nThe validator registry aggregates validators from 10 domain-specific modules:\n\n| Domain | Module | Purpose |\n|--------|--------|---------|\n| Invoice | `invoice.ts` | Invoice OCR and extraction validation |\n| Purchase Order | `po.ts` | PO ID and approver validation |\n| Trade | `trade.ts` | Trade finance validation |\n| AML | `aml.ts` | Anti-money laundering screening |\n| Complaint | `complaint.ts` | Customer complaint processing |\n| Compliance | `compliance.ts` | Regulatory framework validation |\n| Credit | `credit.ts` | Credit review validation |\n| Supply Chain | `supply_chain.ts` | Supplier data validation |\n| Churn | `churn.ts` | Customer churn prediction |\n| Contract Gen | `contract_gen.ts` | Contract generation validation |\n\n资料来源：[src/validators/registry.ts:3-13]()\n\n## Validator Invocation Flow\n\nDuring contract execution, validators are invoked through the remote API transport layer when processing the `analyze` step:\n\n```typescript\nconst validatorContext = { ...initialInputs, ...analysis };\nfor (const validator of validators) {\n    const fn = VALIDATOR_REGISTRY.get(validator.validator_id);\n    if (!fn) {\n        analysis[`${validator.step_id}_error`] = `VALIDATOR_NOT_ALLOWED: \"${validator.validator_id}\" not in registry`;\n        continue;\n    }\n    try {\n        const resultValue = fn(validatorContext);\n        Object.assign(analysis, resultValue.value ?? {});\n    } catch (error) {\n        analysis[`${validator.step_id}_error`] = `VALIDATOR_FAILED: ${String(error)}`;\n    }\n}\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:1-20]()\n\n### Error Handling\n\n| Error Type | Constant | Description |\n|------------|----------|-------------|\n| Validator not in registry | `VALIDATOR_NOT_ALLOWED` | Attempted to call unregistered validator |\n| Validator execution failed | `VALIDATOR_FAILED` | Validator threw an exception |\n| Local validation failed | `LOCAL_VALIDATION_FAILED` | Client-side validation error |\n\n资料来源：[dist-test/src/types.d.ts:18-20]()\n\n## Example Validators\n\n### Supply Chain Validator\n\nValidates supplier array input with country code format checking:\n\n```typescript\n{\n  id: \"supply_chain.validate_inputs_v0\",\n  fn: (inputs) => {\n    const suppliers = Array.isArray(inputs.suppliers) \n      ? inputs.suppliers as Record<string, unknown>[] \n      : [];\n    const non_empty    = suppliers.length > 0;\n    const valid_items  = suppliers.filter(s =>\n      s &&\n      typeof s === \"object\" &&\n      String(s[\"id\"]      || \"\").length > 0 &&\n      String(s[\"name\"]    || \"\").length > 0 &&\n      /^[A-Z]{2}$/.test(String(s[\"country\"] || \"\"))\n    );\n    const invalid_count = suppliers.length - valid_items.length;\n    return {\n      ok: true,\n      value: {\n        inputs_valid:          non_empty && invalid_count === 0,\n        supplier_count:        suppliers.length,\n        valid_supplier_count:  valid_items.length,\n        invalid_supplier_count: invalid_count,\n        has_suppliers:         non_empty,\n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[src/validators/supply_chain.ts:1-35]()\n\n### Purchase Order Validator\n\nValidates PO ID and approver employee ID presence:\n\n```typescript\n{\n  id: \"po.validate_inputs_v0\",\n  fn: (inputs) => {\n    const po  = String(inputs.po_id                || \"\");\n    const emp = String(inputs.approver_employee_id || \"\");\n    const po_ok  = po.length  >= 3;\n    const emp_ok = emp.length >= 3;\n    return {\n      ok: true,\n      value: { \n        inputs_valid: po_ok && emp_ok, \n        po_id_present: po_ok, \n        approver_present: emp_ok \n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[src/validators/po.ts:1-20]()\n\n### Compliance Framework Validator\n\nValidates document URL protocol, framework type, and organization name:\n\n```typescript\nconst VALID_FRAMEWORKS = [\"gdpr\", \"pci_dss\", \"iso_27001\", \"soc2\"];\n\n{\n  id: \"compliance.validate_inputs_v0\",\n  fn: (inputs) => {\n    const url = String(inputs.document_url || \"\");\n    const fw = String(inputs.framework || \"\");\n    const url_ok = url.startsWith(\"https://\");\n    const fw_ok = VALID_FRAMEWORKS.includes(fw);\n    const org_ok = String(inputs.org_name || \"\").trim().length >= 2;\n    return {\n      ok: true,\n      value: {\n        inputs_valid: url_ok && fw_ok && org_ok,\n        url_ok,\n        framework_ok: fw_ok,\n        org_ok,\n        document_url: url,\n        framework: fw,\n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[dist-test/src/validators/compliance.js:1-30]()\n\n## Adding a New Validator\n\nTo add a new domain validator:\n\n1. Create a new file in `src/validators/` (e.g., `new_domain.ts`)\n2. Export an array conforming to `Array<{ id: string; fn: ValidatorFn }>`\n3. Import and add to the aggregator in `src/validators/registry.ts`\n4. Use the naming convention: `{domain}.{validator_name}_v{version}`\n\n资料来源：[src/validators/registry.ts:1-2]()\n\n### Naming Convention\n\n| Component | Format | Example |\n|-----------|--------|---------|\n| Domain prefix | `{domain}` | `invoice`, `supply_chain` |\n| Validator name | `{validator_name}` | `validate_inputs`, `sanity_check` |\n| Version | `_v{version}` | `_v0`, `_v1` |\n\n## Security Model\n\nThe validator registry enforces a strict allowlist:\n\n- **No dynamic code execution**: Validators must be pre-registered\n- **No external function calls**: Only functions in the registry may execute\n- **No runtime injection**: Validator IDs must match registry entries exactly\n\n```mermaid\nsequenceDiagram\n    participant Contract as Contract Manifest\n    participant Registry as VALIDATOR_REGISTRY\n    participant Executor as Contract Executor\n    \n    Contract->>Executor: ValidatorRef{validator_id}\n    Executor->>Registry: get(validator_id)\n    alt ID exists in registry\n        Registry-->>Executor: ValidatorFn\n        Executor->>Executor: Call fn(inputs)\n        Executor-->>Contract: result.value\n    else ID not in registry\n        Registry-->>Executor: undefined\n        Executor-->>Contract: VALIDATOR_NOT_ALLOWED error\n    end\n```\n\nThis security boundary ensures that contract execution can only call explicitly approved validation logic, preventing arbitrary code execution during workflow runs.\n\n## Validation Result Usage\n\nValidation results populate the `analysis` object in contract state:\n\n| Key Pattern | Source | Description |\n|-------------|--------|-------------|\n| `inputs_valid` | All validators | Boolean pass/fail indicator |\n| `{field}_ok` | Domain validators | Individual field validation status |\n| `{step_id}_error` | Executor | Error messages on failure |\n\nThese values are then available as `validatorContext` for subsequent validators in the same step, enabling cascading validation logic.\n\n---\n\n<a id='page-data-schemas'></a>\n\n## Data Schemas and Types\n\n### 相关页面\n\n相关主题：[Domain Validators](#page-validators), [Core MCP Tools](#page-core-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/schemas.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/types.ts)\n- [src/validation/dataspec.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validation/dataspec.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Data Schemas and Types\n\nThis document describes the core data schemas, type definitions, and validation mechanisms in the mova-flat-runner MCP server. The system uses TypeScript-first type definitions with JSON Schema validation for package manifests and runtime data validation.\n\n## Overview\n\nThe mova-flat-runner implements a governed AI workflow execution engine with multiple execution modes, contract-based state management, and human-in-the-loop approval gates. The type system is designed to enforce contract integrity across local and remote execution contexts.\n\n```mermaid\ngraph TB\n    subgraph \"Type System Layers\"\n        JS[TypeScript Types]\n        SCH[JSON Schemas]\n        VAL[Validators]\n    end\n    \n    subgraph \"Runtime Contexts\"\n        LOCAL[Local Seam Bridge]\n        REMOTE[Remote API Bridge]\n    end\n    \n    subgraph \"Execution Modes\"\n        AI[AI_ATOMIC]\n        DET[DETERMINISTIC]\n        HUM[HUMAN_GATE]\n        CTR[CONTRACT_CALL]\n    end\n    \n    JS --> SCH\n    JS --> VAL\n    SCH --> LOCAL\n    SCH --> REMOTE\n```\n\n## Core Type Definitions\n\n### MovaConfig\n\nConfiguration object for MOVA API connectivity. Required for all MCP tool executions.\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `apiUrl` | `string` | Yes | Base URL for MOVA API (default: `https://api.mova-lab.eu`) |\n| `apiKey` | `string` | Yes | API authentication key |\n| `llmKey` | `string` | No | OpenRouter API key for LLM analysis steps |\n| `llmModel` | `string` | No | OpenRouter model ID (default: `openai/gpt-4o-mini`) |\n| `timeoutMs` | `number` | No | Request timeout in milliseconds |\n| `invokeToken` | `string` | No | Local HTTP mode invocation token |\n\n资料来源：[src/index.ts:MovaConfig]()\n\n### FlatRunnerResult\n\nStandard response envelope for all MCP tool operations.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `ok` | `boolean` | Success indicator |\n| `error_code` | `string` | Error code on failure |\n| `error_message` | `string` | Human-readable error description |\n| `http_status` | `number` | HTTP status equivalent |\n\n```typescript\ninterface FlatRunnerResult {\n  ok: boolean;\n  error_code?: string;\n  error_message?: string;\n  http_status?: number;\n}\n```\n\n资料来源：[src/index.ts:FlatRunnerResult]()\n\n### ValidatorFn\n\nFunction signature for custom contract validators.\n\n```typescript\ntype ValidatorFn = (context: Record<string, unknown>) => {\n  ok: boolean;\n  value?: Record<string, unknown>;\n  step_id?: string;\n};\n```\n\n资料来源：[src/validators/supply_chain.ts:ValidatorFn]()\n\n## Execution Modes\n\nThe system defines four distinct execution modes for contract steps:\n\n| Mode | Description | Required Fields | Validation |\n|------|-------------|-----------------|------------|\n| `AI_ATOMIC` | LLM-powered single-step execution | `model` | Step must declare a model field |\n| `DETERMINISTIC` | Local JavaScript execution | None | Cannot have model field |\n| `HUMAN_GATE` | Human approval required | `decision_options` | Must have decision_options array |\n| `CONTRACT_CALL` | Cross-contract invocation | `contract_id` | Must specify target contract |\n\n```mermaid\nstateDiagram-v2\n    [*] --> DETERMINISTIC: Local check\n    [*] --> AI_ATOMIC: LLM analysis\n    [*] --> HUMAN_GATE: Approval required\n    [*] --> CONTRACT_CALL: Cross-contract\n\n    DETERMINISTIC --> [*]: Complete\n    AI_ATOMIC --> [*]: Complete\n    HUMAN_GATE --> APPROVED: Human approves\n    HUMAN_GATE --> REJECTED: Human rejects\n    CONTRACT_CALL --> [*]: Complete\n```\n\n资料来源：[src/security/step_mode_guard.ts:StepExecutionMode]()\n\n## Step Mode Validation\n\nThe `step_mode_guard` module enforces execution mode consistency through the `assertStepModesValid` function:\n\n```typescript\nexport function assertStepModesValid(\n  flow: unknown,\n  requestId: string,\n): FlatRunnerResult | null {\n  const violations = findStepModeViolations(flow);\n  if (violations.length === 0) return null;\n  return flatErr(\n    ERR.STEP_MODE_FIELD_MISMATCH,\n    `Step execution_mode does not agree with content fields`,\n    { violations, http_status_equivalent: 400 }\n  );\n}\n```\n\n**Violation Types:**\n\n| Kind | Condition |\n|------|-----------|\n| `ai_atomic_without_model` | AI_ATOMIC mode without `model` field |\n| `deterministic_with_model` | DETERMINISTIC mode with `model` field declared |\n| `contract_call_without_contract_id` | CONTRACT_CALL without target `contract_id` |\n| `human_gate_without_decisions` | HUMAN_GATE without `decision_options` array |\n\n资料来源：[src/security/step_mode_guard.ts:findStepModeViolations]()\n\n## Package Manifest Schema\n\n### Global Package Shape\n\nThe `validatePackageGlobalShape` function enforces structure for contract package manifests:\n\n```typescript\nexport function validatePackageGlobalShape(value: unknown): string | null {\n  if (!isObject(value)) return \"global file must be a JSON object\";\n  const allowedKeys = new Set([\n    \"schema_id\", \"global_id\", \"version\", \"scope\",\n    \"extends\", \"semantic_roles\", \"non_authority_rules\"\n  ]);\n  // ... validation logic\n}\n```\n\n**Required Fields:**\n\n| Field | Type | Constraint |\n|-------|------|------------|\n| `schema_id` | `string` | Non-empty |\n| `global_id` | `string` | Non-empty |\n| `version` | `string` | Non-empty |\n| `scope` | `string` | Must be `\"contract_package\"` |\n| `semantic_roles` | `array` | Non-empty array of role objects |\n| `non_authority_rules` | `array` | Non-empty array |\n\n资料来源：[src/package_support.ts:validatePackageGlobalShape]()\n\n### Semantic Role Structure\n\n```typescript\ninterface SemanticRole {\n  id: string;\n  role: string;\n  authority: string;\n  maturity: string;\n  applies_to?: string[];\n  allowed_use?: string[];\n  forbidden_use?: string[];\n  notes?: string;\n}\n```\n\n**Allowed Keys:** `id`, `role`, `authority`, `maturity`, `applies_to`, `allowed_use`, `forbidden_use`, `notes`\n\n资料来源：[src/package_support.ts:roleKeys]()\n\n## Output Schema Resolution\n\nThe `resolveOutputSchema` function locates JSON schemas for contract step outputs:\n\n```typescript\nasync function resolveOutputSchema(\n  schemaRef: string,\n  flowDir: string\n): Promise<Record<string, unknown> | null> {\n  const candidates = [\n    path.join(flowDir, \"_schemas\", `${schemaRef}.json`),\n    path.join(flowDir, \"..\", \"_data-schemas\", `${schemaRef}.json`),\n    path.join(flowDir, \"..\", \"..\", \"_data-schemas\", `${schemaRef}.json`),\n    ...(process.env.MOVA_SCHEMA_PATH \n      ? [path.join(process.env.MOVA_SCHEMA_PATH, `${schemaRef}.json`)]\n      : []\n    ),\n  ];\n  // ... search logic\n}\n```\n\n**Search Order (priority):**\n1. `{flowDir}/_schemas/{schemaRef}.json`\n2. `{flowDir}/../_data-schemas/{schemaRef}.json`\n3. `{flowDir}/../../_data-schemas/{schemaRef}.json`\n4. `$MOVA_SCHEMA_PATH/{schemaRef}.json` (if set)\n\n资料来源：[src/package_support.ts:resolveOutputSchema]()\n\n## Local Seam Bridge Types\n\n### BridgeRequest\n\n```typescript\ninterface BridgeRequest {\n  contractRef: string;\n  packagePath: string;\n  step: {\n    id: string;\n    execution_mode: StepExecutionMode;\n  };\n  outputSchemaPath?: string;\n  taskType?: string;\n  stepResult?: unknown;\n  terminalOutcome?: string;\n  humanDecision?: string;\n  routeKey?: string;\n}\n```\n\n### BridgeResponse\n\n```typescript\ninterface BridgeResponse {\n  ok: boolean;\n  bridge: {\n    ok: boolean;\n    bridge_source: string;\n    status: \"completed\" | \"advanced\" | \"human_gate_required\";\n    contract_ref: string;\n    current_step_id: string;\n    execution_mode: StepExecutionMode;\n    produced_output: unknown;\n    proof_ref: string;\n    state_ref: string;\n    next_state_ref: string;\n    decision_kind: { kind: \"Pass\" | \"Fail\" };\n    commit_effect: { kind: \"Apply\" | \"Skip\" };\n    next_phase: { phase: \"EXECUTION\" | \"WAIT_HUMAN\" };\n  };\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:BridgeRequest]()\n\n## Contract Manifest\n\nThe `CONTRACT_MANIFESTS` registry defines built-in contract types:\n\n```typescript\ninterface ContractManifest {\n  contract_type: string;\n  title: string;\n  version: string;\n  execution_mode: StepExecutionMode;\n  template_id?: string;\n  policy_id?: string;\n  dataspec: {\n    inputs: Array<{\n      key: string;\n      label?: string;\n      type: string;\n      required?: boolean;\n    }>;\n  };\n  decision_options?: Array<{\n    id: string;\n    label: string;\n    description?: string;\n  }>;\n}\n```\n\n资料来源：[src/index.ts:CONTRACT_MANIFESTS]()\n\n## Validation Utilities\n\n### Required String Validation\n\n```typescript\nfunction validateRequiredString(\n  obj: Record<string, unknown>,\n  key: string,\n  scope: string\n): string | null {\n  if (typeof obj[key] !== \"string\" || (obj[key] as string).trim().length === 0) {\n    return `${scope} is missing required string field \"${key}\"`;\n  }\n  return null;\n}\n```\n\n### Public Shape Sanitization\n\nThe `sanitizePublicShape` function filters internal bridge fields from public responses:\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  const BLOCKED_KEYS = [\n    \"bridge_anchors\",\n    \"last_terminal_bridge\",\n    \"terminal_commit_count\",\n    \"_state15_bridge\",\n    \"trace\",\n    \"outputs\",\n    \"context\"\n  ];\n  // Recursively validates and filters\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:sanitizePublicShape]()\n\n## MCP Server Configuration Schema\n\nDefined in `server.json` per Model Context Protocol specification:\n\n```json\n{\n  \"$schema\": \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\",\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\"\n}\n```\n\n**Environment Variables:**\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `MOVA_API_KEY` | Yes | API key for MOVA backend |\n| `LLM_KEY` | Yes | OpenRouter API key |\n| `LLM_MODEL` | No | OpenRouter model ID |\n| `MOVA_API_URL` | No | Override default API URL |\n\n资料来源：[server.json:environmentVariables]()\n\n## Error Types\n\n| Error Code | HTTP Status | Description |\n|------------|-------------|-------------|\n| `UNKNOWN_CONTRACT_TYPE` | 404 | Contract type not found in manifests |\n| `LOCAL_VALIDATION_FAILED` | 400 | Input validation failed |\n| `STEP_MODE_FIELD_MISMATCH` | 400 | Execution mode conflicts with fields |\n| `MOVA_API_ERROR` | 502 | Upstream API failure |\n| `MOVA_API_404` | 404 | Resource not found on backend |\n\n资料来源：[src/index.ts:ERR]()\n\n## Type Exports Summary\n\n| File | Primary Exports |\n|------|-----------------|\n| `src/types.ts` | Core type interfaces (MovaConfig, FlatRunnerResult) |\n| `src/schemas.ts` | JSON Schema definitions for validation |\n| `src/validation/dataspec.ts` | Data specification validators |\n| `src/package_support.ts` | Package manifest validation |\n| `src/security/step_mode_guard.ts` | Execution mode validation |\n\n资料来源：[src/types.ts](), [src/schemas.ts](), [src/validation/dataspec.ts]()\n\n---\n\n<a id='page-deployment'></a>\n\n## Deployment and Operations\n\n### 相关页面\n\n相关主题：[Installation and Setup](#page-installation-setup), [Transport Layer](#page-transport-layer), [Extensibility and Customization](#page-extensibility)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n</details>\n\n# Deployment and Operations\n\n## Overview\n\nThe MOVA Flat Runner is distributed as an MCP (Model Context Protocol) server package (`@leryk1981/mova-flat-runner`) that provides governed AI workflow capabilities including invoice OCR, AML triage, credit review, and custom contracts with human approval gates and audit trails.\n\nThis section covers the deployment architecture, build system, runtime configuration, publishing workflow, and operational considerations for running the MOVA Flat Runner in production and development environments.\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    subgraph \"Client Layer\"\n        Claude[\"Claude Desktop\"]\n        Codex[\"Codex IDE\"]\n    end\n    \n    subgraph \"MCP Transport\"\n        STDIO[\"STDIO Transport\"]\n        HTTP[\"Local HTTP Mode\"]\n    end\n    \n    subgraph \"MOVA Flat Runner\"\n        Index[\"src/index.ts\"]\n        API[\"HTTP Handlers\"]\n        Auth[\"Authentication\"]\n        Service[\"Business Logic\"]\n    end\n    \n    subgraph \"External Services\"\n        MOVA_API[\"MOVA API\"]\n        LLM[\"LLM Provider\"]\n    end\n    \n    Claude --> STDIO\n    Codex --> HTTP\n    STDIO --> Index\n    HTTP --> Index\n    Index --> API\n    Index --> Auth\n    Index --> Service\n    Service --> MOVA_API\n    Service --> LLM\n```\n\n## Build System\n\n### TypeScript Configuration\n\nThe project uses TypeScript with separate configurations for production and testing builds.\n\n**Production Build (`tsconfig.json`)**\n\n| Setting | Value | Purpose |\n|---------|-------|---------|\n| `target` | `ES2022` | ECMAScript target version |\n| `module` | `ES2022` / `NodeNext` | ESM module system |\n| `outDir` | `dist` | Compiled output directory |\n| `rootDir` | `src` | Source root directory |\n| `strict` | `true` | Enable strict type checking |\n\n**Test Build (`tsconfig.test.json`)**\n\n| Setting | Value | Purpose |\n|---------|-------|---------|\n| `extends` | `./tsconfig.json` | Inherits base config |\n| `outDir` | `dist-test` | Separate test output directory |\n| `rootDir` | `src` | Source root directory |\n\n### Build Pipeline\n\n```mermaid\ngraph LR\n    A[\"src/*.ts\"] --> B[\"tsc compiler\"]\n    B --> C[\"dist/index.js\"]\n    C --> D[\"shebang injection\"]\n    D --> E[\"chmod +x\"]\n    \n    F[\"src/*.ts\"] --> G[\"tsc (test config)\"]\n    G --> H[\"dist-test/\"]\n```\n\n### npm Scripts\n\n| Script | Command | Purpose |\n|--------|---------|---------|\n| `build` | `tsc && node -e \"...\"` | Compile TypeScript and make executable |\n| `check` | `make check` | Run lint, unit tests, and integration tests |\n| `test:build` | `tsc -p tsconfig.test.json` | Build test artifacts |\n\n资料来源：[package.json:18-24]()\n\n## MCP Server Configuration\n\n### Server Metadata\n\n```json\n{\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\",\n  \"description\": \"Governed AI workflows with human approval gates and audit trails\",\n  \"repository\": {\n    \"url\": \"https://github.com/mova-compact/mova-flat-runner\",\n    \"source\": \"github\"\n  }\n}\n```\n\n### Runtime Hints\n\n| Property | Value | Notes |\n|----------|-------|-------|\n| `runtimeHint` | `node` | Requires Node.js runtime |\n| `transport` | `stdio` | Primary transport protocol |\n\n资料来源：[server.json:1-15]()\n\n## Environment Variables\n\n### Required Variables\n\n| Variable | Description | Example |\n|----------|-------------|---------|\n| `MOVA_API_KEY` | MOVA API authentication key | `__SET_MOVA_API_KEY__` |\n| `LLM_KEY` | OpenRouter API key for LLM analysis | `__SET_LLM_KEY__` |\n\n### Optional Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `MOVA_API_URL` | `https://api.mova-lab.eu` | MOVA API base URL |\n| `LLM_MODEL` | `openai/gpt-4o-mini` | OpenRouter model ID |\n| `MOVA_API_TIMEOUT_MS` | `30000` | API request timeout |\n| `MOVA_HTTP_PORT` | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | — | Token for local HTTP invocation |\n\n资料来源：[README.md:40-57]()\n\n## Publishing and Distribution\n\n### Publishing Workflow\n\nThe project includes a dedicated CLI tool for publishing servers to the MCP registry.\n\n```bash\n# Build the publisher CLI\nmake publisher\n\n# Publish a server\n./bin/mcp-publisher --help\n```\n\n### npm Distribution\n\nThe package is published to npm as `@leryk1981/mova-flat-runner`:\n\n| Property | Value |\n|----------|-------|\n| Package Name | `@leryk1981/mova-flat-runner` |\n| Current Version | `3.3.4` |\n| Binary | `mova-mcp` |\n| Entry Point | `dist/index.js` |\n\n资料来源：[package.json:3-6]()\n\n### Client Configuration Examples\n\n**Claude Desktop (JSON)**\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n**Codex (TOML)**\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:63-100]()\n\n## Deployment Configuration\n\n### Project Structure\n\n```\nmova-flat-runner/\n├── cmd/                     # Application entry points\n│   └── publisher/           # Server publishing tool\n├── deploy/                  # Deployment configuration (Pulumi)\n├── internal/                # Private application code\n│   ├── api/                 # HTTP handlers and routing\n│   ├── auth/                # Authentication (GitHub OAuth, JWT)\n│   ├── config/              # Configuration management\n│   ├── database/            # Data persistence (PostgreSQL)\n│   ├── service/             # Business logic\n│   ├── telemetry/           # Metrics and monitoring\n│   └── validators/          # Input validation\n├── pkg/                     # Public packages\n└── tools/                   # Operational tools\n```\n\n### Pulumi Deployment\n\nInfrastructure is managed via Pulumi in the `deploy/` directory. This enables repeatable, version-controlled infrastructure deployments.\n\n资料来源：[README.md:12-29]()\n\n## Health Monitoring\n\n### Health Check Endpoint\n\n```bash\ncurl -sS https://api.mova-lab.eu/health\n```\n\n### Available Tools for Monitoring\n\n| Tool | Purpose |\n|------|---------|\n| `mova_health` | Server health status |\n| `mova_registry` | MCP registry information |\n| `mova_run` | Contract execution |\n| `mova_query` | Query contract status |\n| `mova_decide` | Human decision handling |\n| `mova_connector` | External system integration |\n| `mova_contract` | Contract management |\n\n资料来源：[README.md:58-60]()\n\n## Local HTTP Mode Operations\n\n### Overview\n\nThe flat runner supports an optional local HTTP transport mode for environments where STDIO is not suitable.\n\n```mermaid\ngraph TD\n    Client[\"MCP Client\"] --> |HTTP Request| LocalHTTP[\"Local HTTP Bridge\"]\n    LocalHTTP --> |STDIO| MOVA_MCP[\"MOVA MCP Server\"]\n    MOVA_MCP --> |Response| LocalHTTP\n    LocalHTTP --> |HTTP Response| Client\n    \n    subgraph \"Local Environment\"\n        LocalHTTP\n        MOVA_MCP\n    end\n```\n\n### Configuration\n\n```env\nMOVA_HTTP_PORT=3796\nMOVA_INVOKE_TOKEN=__SET_LOCAL_INVOKE_TOKEN__\nMOVA_API_TIMEOUT_MS=30000\n```\n\n### Security Considerations\n\n- `MOVA_INVOKE_TOKEN` must be set to authorize local HTTP requests\n- API timeouts prevent hanging requests (default: 30 seconds)\n- Health checks should be performed before heavy operations\n\n资料来源：[README.md:50-55]()\n\n## Development Operations\n\n### Makefile Targets\n\n| Target | Purpose |\n|--------|---------|\n| `make check` | Run lint, unit tests, integration tests |\n| `make help` | Display available commands |\n| `make publisher` | Build the MCP publisher CLI |\n\n### Validation Workflow\n\n```mermaid\ngraph LR\n    A[\"npm run build\"] --> B[\"npm run test:build\"]\n    B --> C[\"npm run smoke:*\"]\n    C --> D[\"Validation Complete\"]\n```\n\n### Smoke Testing\n\nCustom bridge validation:\n\n```bash\nnpm run smoke:custom-bridge\n```\n\nThis validates the custom contract query bridge for handling `mova_query` requests when the backend namespace is absent.\n\n资料来源：[tasks/task061.md:1-50]()\n\n## Operational Data Flows\n\n### Local Seam Bridge Execution\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as Local Seam Bridge\n    participant Machine as State Machine\n    participant FS as File System\n    \n    MCP->>Bridge: Execute step with state\n    Bridge->>Machine: Load machine module\n    Machine->>FS: Read state file\n    FS-->>Machine: State data\n    Machine->>Machine: Execute step logic\n    Machine->>FS: Write updated state\n    Bridge->>MCP: Return result with proofs\n```\n\n### Custom Contract Bridge\n\nFor custom contract IDs (prefixed with `local-*` or `remote-*`), the system maintains an in-memory bridge map:\n\n```typescript\nCUSTOM_RUN_BRIDGE: Map<contract_id, {run_id, updated_at, source_url?}>\n```\n\n资料来源：[src/index.ts:1-100]()\n\n## Security Notes\n\n### Environment Variable Security\n\n| Practice | Requirement |\n|----------|-------------|\n| Placeholders in docs | Use `__SET_*__` format |\n| Real secrets | Never commit to repository |\n| API keys | Use `MOVA_API_KEY`, `LLM_KEY` |\n\n> **Warning**: Do not commit real `MOVA_API_KEY`, `LLM_KEY`, or `MOVA_INVOKE_TOKEN` to version control.\n\n资料来源：[README.md:37-39]()\n\n### Step Mode Validation\n\nThe system validates step execution modes at runtime:\n\n| Mode | Validation Rule |\n|------|-----------------|\n| `DETERMINISTIC` | Cannot have `model` field |\n| `AI_ATOMIC` | Must have `model` field |\n| `CONTRACT_CALL` | Must have `contract_id` |\n| `HUMAN_GATE` | Must have `decision_options` array |\n\n资料来源：[dist-test/src/security/step_mode_guard.js:1-50]()\n\n## Deployment Environments\n\n### Build Variants\n\n| Branch | Purpose | Build Output |\n|--------|---------|--------------|\n| `main` | Production builds | `dist/` |\n| `main-<date>-<sha>` | Specific commit builds | `dist/` |\n\n### Continuous Integration\n\n```\nmain branch → Continuous build → Latest stable release\n```\n\n资料来源：[README.md:1-5]()\n\n## Troubleshooting\n\n| Issue | Resolution |\n|-------|------------|\n| Build fails | Run `npm run build` |\n| Test failures | Run `make check` |\n| MCP connection issues | Verify `MOVA_API_KEY` and `LLM_KEY` |\n| Custom contract 404 | Use `mova_contract` for custom IDs |\n| Human gate timeout | Check `MOVA_API_TIMEOUT_MS` setting |\n\n## Related Documentation\n\n- [Quickstart Guide](./docs/modelcontextprotocol-io/quickstart.mdx)\n- [Live API Docs](https://registry.modelcontextprotocol.io/docs)\n- [Ecosystem Vision](./docs/design/ecosystem-vision.md)\n\n---\n\n<a id='page-extensibility'></a>\n\n## Extensibility and Customization\n\n### 相关页面\n\n相关主题：[Domain Validators](#page-validators), [Security Guards](#page-security-guards), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/validators/registry.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/registry.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [dist-test/src/package_support.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/package_support.js)\n</details>\n\n# Extensibility and Customization\n\nThe mova-flat-runner provides multiple layers of extensibility, allowing operators to add custom validators, define new contract types, extend execution modes, and integrate with external systems. This document describes the core extension points and customization mechanisms available in the MCP server.\n\n## 1. Validator Registry System\n\n### 1.1 Architecture Overview\n\nThe validator registry is the primary extension point for business logic validation. It implements a **whitelist-based security model** where only explicitly registered validator functions may be invoked during contract execution. Dynamic code execution is prohibited.\n\n```mermaid\ngraph TD\n    A[Contract Execution] --> B{ValidatorRef found?}\n    B -->|Yes| C[Lookup in VALIDATOR_REGISTRY]\n    B -->|No| D[Return VALIDATOR_NOT_ALLOWED error]\n    C --> E{Validator registered?}\n    E -->|Yes| F[Execute ValidatorFn]\n    E -->|No| D\n    F --> G[Return validation result]\n    D --> H[Audit log: validator blocked]\n```\n\n### 1.2 Registry Implementation\n\nThe `VALIDATOR_REGISTRY` is a `Map<string, ValidatorFn>` that maps each validator's unique identifier to its implementation function. All validators must conform to the `ValidatorFn` type signature.\n\n**Type Signature:**\n```typescript\ntype ValidatorFn = (inputs: Record<string, unknown>) => {\n    ok: boolean;\n    value: Record<string, unknown>;\n    step_id: string;\n};\n```\n\n### 1.3 Registered Validator Modules\n\n| Module | Source File | Validators |\n|--------|-------------|------------|\n| Invoice | `invoice.ts` | invoice validation validators |\n| Purchase Order | `po.ts` | PO validation validators |\n| Trade | `trade.ts` | trade validation validators |\n| AML | `aml.ts` | AML triage validators |\n| Complaint | `complaint.ts` | complaint handling validators |\n| Compliance | `compliance.ts` | compliance check validators |\n| Credit | `credit.ts` | credit review validators |\n| Supply Chain | `supply_chain.ts` | supplier validation validators |\n| Churn | `churn.ts` | churn prediction validators |\n| Contract Gen | `contract_gen.ts` | contract generation validators |\n\n资料来源：[src/validators/registry.ts:1-28]()\n\n### 1.4 Adding a New Validator\n\nTo add a new validator:\n\n1. **Implement the validator function** in a contract-specific file following the `ValidatorFn` signature\n2. **Export it** as part of a validator array with a unique `id`\n3. **Register it** in `src/validators/registry.ts`\n\n**Example from supply_chain.ts:**\n```typescript\nexport const supplyChainValidators: Array<{ id: string; fn: ValidatorFn }> = [\n  {\n    id: \"supply_chain.validate_inputs_v0\",\n    fn: (inputs) => {\n      const suppliers = Array.isArray(inputs.suppliers) ? inputs.suppliers : [];\n      const valid_items = suppliers.filter(s =>\n        s && typeof s === \"object\" &&\n        String(s[\"id\"] || \"\").length > 0 &&\n        /^[A-Z]{2}$/.test(String(s[\"country\"] || \"\"))\n      );\n      return {\n        ok: true,\n        value: {\n          inputs_valid: valid_items.length === suppliers.length,\n          supplier_count: suppliers.length,\n        },\n        step_id: \"validate_inputs\",\n      };\n    },\n  },\n];\n```\n\n资料来源：[src/validators/supply_chain.ts:1-35]()\n\n### 1.5 Security Model\n\nThe registry enforces these security constraints:\n\n| Constraint | Description |\n|------------|-------------|\n| Whitelist-only | Only functions in the registry may execute |\n| No dynamic code | Arbitrary code execution is forbidden |\n| Type enforcement | All validators must return `{ok, value, step_id}` |\n| Step isolation | Validators operate on sanitized input contexts |\n\nDuring contract execution, the runner checks each `ValidatorRef` against the registry before invocation:\n\n```typescript\nconst fn = VALIDATOR_REGISTRY.get(validator.validator_id);\nif (!fn) {\n    analysis[`${validator.step_id}_error`] = `VALIDATOR_NOT_ALLOWED: \"${validator.validator_id}\" not in registry`;\n    continue;\n}\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:1-25]()\n\n## 2. Contract Manifest System\n\n### 2.1 Manifest Structure\n\nContract manifests define the metadata, inputs, and behavior of each contract type. Built-in manifests are stored in `CONTRACT_MANIFESTS`:\n\n```typescript\ntype ContractManifest = {\n    contract_type: string;\n    title: string;\n    version: string;\n    execution_mode: \"AI_ATOMIC\" | \"HUMAN_GATE\" | \"LOCAL_SEAM\";\n    template_id: string;\n    policy_id: string;\n    dataspec: { inputs: InputSpec[] };\n    decision_options?: DecisionOption[];\n};\n```\n\n### 2.2 Manifest Registry Resources\n\nThe MCP server exposes manifests via the `mova://` URI scheme:\n\n| Resource URI | Description |\n|--------------|-------------|\n| `mova://registry` | Lists all available contract types |\n| `mova://schemas/envelopes` | Returns envelope schema definition |\n| `mova://contracts/{type}/manifest` | Returns specific contract manifest |\n\n```typescript\nfunction readResource(uri: string): unknown {\n  if (uri === \"mova://registry\") {\n    return {\n      schema_version: \"1.0\",\n      contracts: Object.values(CONTRACT_MANIFESTS).map(m => ({\n        contract_type: m.contract_type,\n        title: m.title,\n        version: m.version,\n        manifest_resource: `mova://contracts/${m.contract_type}/manifest`,\n      })),\n    };\n  }\n  // ...\n}\n```\n\n资料来源：[src/index.ts:300-350]()\n\n## 3. Custom Contract Bridge\n\n### 3.1 The Namespace Gap Problem\n\nCustom contracts registered via `mova_contract register` use `local-*` or `remote-*` ID prefixes and execute in the `/run/*` namespace. However, `mova_query` operations query the `/api/v1/contracts/*` namespace, resulting in 404 errors for custom contracts.\n\n### 3.2 Bridge Implementation\n\nThe custom contract bridge provides a mitigation layer:\n\n```mermaid\ngraph LR\n    A[register] --> B[rememberCustomRun]\n    B --> C[CUSTOM_RUN_BRIDGE Map]\n    C --> D[mova_query status]\n    D --> E{404 from API?}\n    E -->|Yes| F[getMyContractRecord]\n    F --> G{Bridge entry found?}\n    G -->|Yes| H[Return bridged status]\n    G -->|No| I[Return error]\n```\n\n### 3.3 Bridge Components\n\n| Component | Type | Purpose |\n|-----------|------|---------|\n| `CUSTOM_RUN_BRIDGE` | `Map<contract_id, {run_id, updated_at, source_url?}>` | In-memory ID mapping |\n| `rememberCustomRun()` | Function | Captures and persists contract→run mapping |\n| `getMyContractRecord()` | Function | Probes `/api/v1/contracts/my` for metadata |\n\n**Memory Bridge Map:**\n```typescript\nconst CUSTOM_RUN_BRIDGE = new Map<string, CustomRunRef>();\n\nfunction rememberCustomRun(contractId: string, runId: string, sourceUrl?: string): void {\n    if (typeof contractId !== \"string\" || typeof runId !== \"string\") return;\n    const ref = { run_id: runId, updated_at: new Date().toISOString() };\n    if (sourceUrl) ref.source_url = sourceUrl;\n    CUSTOM_RUN_BRIDGE.set(contractId, ref);\n}\n```\n\n资料来源：[src/index.ts:400-420]()\n\n### 3.4 Bridge Response Modes\n\n| View Mode | Behavior |\n|-----------|----------|\n| `status` | Returns structured bridged status with `bridge_mode=custom_contract_run_namespace_bridge_v1` |\n| `audit` | Returns `AUDIT_UNAVAILABLE` envelope (honest unavailability) |\n| `audit_compact` | Returns `{ok=false, status=424}` with JSON journal explaining bridge |\n\n资料来源：[tasks/task061.md:1-60]()\n\n## 4. Local Seam Execution Mode\n\n### 4.1 Overview\n\nThe `LOCAL_SEAM` execution mode allows contracts to run entirely within the MCP server process, bypassing the remote MOVA API. This is critical for offline development and testing scenarios.\n\n### 4.2 Execution Flow\n\n```mermaid\ngraph TD\n    A[mova_run contract_type] --> B{Is LOCAL_SEAM?}\n    B -->|No| C[Remote API execution]\n    B -->|Yes| D[Resolve local locator]\n    D --> E[Load sandbox package]\n    E --> F[Execute steps locally]\n    F --> G{Step type?}\n    G -->|AI_ATOMIC| H[LLM invocation]\n    G -->|HUMAN_GATE| I[Wait for gate decision]\n    G -->|Standard| J[Apply step logic]\n    H --> K[Validate output schema]\n    I --> L[Bridge to human approval]\n    J --> K\n    K --> M{More steps?}\n    M -->|Yes| F\n    M -->|No| N[Return FlatRunnerResult]\n```\n\n### 4.3 Local Seam Locator Resolution\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs: Record<string, unknown>): Promise<SeamLocator> {\n    const packagePath = initialInputs.package_path \n        ?? process.env.MOVA_SANDBOX_PACKAGE_PATH \n        ?? \"default-contract-path\";\n    const projectPath = initialInputs.project_path \n        ?? process.env.MOVA_SANDBOX_PROJECT_PATH \n        ?? \"\";\n    // ...\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:50-80]()\n\n### 4.4 Sandbox Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | Path to contract package | Project-specific |\n| `MOVA_SANDBOX_PROJECT_PATH` | Path to project directory | Required |\n| `MOVA_SANDBOX_STATE_FILE` | State persistence file | System temp |\n\n## 5. Package Global Support\n\n### 5.1 Package Manifest Validation\n\nCustom contract packages must include a `global` file conforming to the `contract_package` scope. The validation enforces strict schema requirements:\n\n**Required Fields:**\n\n| Field | Type | Constraint |\n|-------|------|------------|\n| `global_id` | string | Non-empty |\n| `version` | string | Non-empty |\n| `scope` | string | Must be `contract_package` |\n| `extends` | array | Optional, must be array if present |\n| `semantic_roles` | array | Non-empty, objects with allowed keys |\n| `non_authority_rules` | array | Non-empty |\n\n**Validation Rules for semantic_roles:**\n```javascript\nconst roleKeys = new Set([\n    \"id\", \"role\", \"authority\", \"maturity\", \n    \"applies_to\", \"allowed_use\", \"forbidden_use\", \"notes\"\n]);\nfor (const key of Object.keys(role)) {\n    if (!roleKeys.has(key))\n        return `global semantic_roles[${index}] contains unsupported field \"${key}\"`;\n}\n```\n\n资料来源：[dist-test/src/package_support.js:1-30]()\n\n### 5.2 Global File Schema\n\n```typescript\ninterface PackageGlobal {\n    global_id: string;\n    version: string;\n    scope: \"contract_package\";\n    extends?: string[];\n    semantic_roles: Array<{\n        id: string;\n        role: string;\n        authority: string;\n        maturity: string;\n        applies_to?: string;\n        allowed_use?: string[];\n        forbidden_use?: string[];\n        notes?: string;\n    }>;\n    non_authority_rules: string[];\n}\n```\n\n## 6. MCP Tool Extensibility\n\n### 6.1 Available Tools\n\n| Tool | Purpose | Extensibility |\n|------|---------|---------------|\n| `mova_health` | Health check | Fixed |\n| `mova_registry` | List contract types | Fixed |\n| `mova_run` | Execute built-in contracts | Extend via CONTRACT_MANIFESTS |\n| `mova_query` | Query contract status/audit | Bridge extensible |\n| `mova_decide` | Submit human decisions | Fixed |\n| `mova_connector` | Connect to external systems | Fixed |\n| `mova_contract` | Custom contract operations | Core extensibility interface |\n\n### 6.2 Tool Executor Pattern\n\nTools are registered in a switch-based executor that maps tool names to handler functions:\n\n```typescript\nasync function executeTool(name: string, args: Args): Promise<string> {\n  const requestId = shortId();\n  switch (name) {\n    case \"mova_run\": {\n      const manifest = CONTRACT_MANIFESTS[contractType];\n      if (!manifest) {\n        return JSON.stringify(flatErr(\n          ERR.UNKNOWN_CONTRACT_TYPE,\n          `Unknown contract_type \"${contractType}\". For custom contracts use mova_contract action=run.`,\n          { available: Object.keys(CONTRACT_MANIFESTS) },\n          false, requestId\n        ));\n      }\n      // ...\n    }\n  }\n}\n```\n\n资料来源：[src/index.ts:450-480]()\n\n## 7. Configuration Extension Points\n\n### 7.1 Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `MOVA_API_URL` | Yes | MOVA API base URL |\n| `MOVA_API_KEY` | Yes | API authentication key |\n| `LLM_KEY` | Conditional | OpenRouter API key for LLM steps |\n| `LLM_MODEL` | No | Model identifier, default: `openai/gpt-4o-mini` |\n| `MOVA_API_TIMEOUT_MS` | No | HTTP timeout in milliseconds |\n| `MOVA_HTTP_PORT` | No | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | No | Local invoke authentication |\n\n### 7.2 Config Merging\n\nThe configuration system supports runtime overrides through environment variables, with precedence: CLI args > env vars > defaults.\n\n## 8. Extension Summary\n\n```mermaid\ngraph TD\n    subgraph Extension Points\n        A[Validator Registry]\n        B[Contract Manifests]\n        C[Package Global]\n        D[Local Seam Mode]\n    end\n    \n    subgraph Security Layer\n        E[Whitelist Enforcement]\n        F[Type Validation]\n        G[Schema Validation]\n    end\n    \n    subgraph MCP Tools\n        H[mova_contract]\n        I[mova_run]\n        J[mova_query]\n    end\n    \n    A --> E\n    B --> G\n    C --> G\n    D --> F\n    H --> A\n    H --> B\n    I --> A\n    J --> C\n    J --> D\n```\n\nThe mova-flat-runner's extensibility model is designed for **operator-controlled customization** while maintaining strict security boundaries. Validators, contracts, and execution modes can be extended without modifying core server code, enabling safe customization in regulated environments.\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：mova-compact/mova-flat-runner\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。\n\n## 1. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt\n\n## 2. 配置坑 · 来源证据：v3.0.0 — Step Enforcement Runtime\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：v3.0.0 — Step Enforcement Runtime\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_10b68dae59184a36b21a563722829aed | https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown\n\n<!-- canonical_name: mova-compact/mova-flat-runner; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "mova-flat-runner",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1212840167",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/mova-compact/mova-flat-runner"
        },
        {
          "evidence_id": "art_3c8daee931ea4ef491323c91edd1b001",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/mova-compact/mova-flat-runner#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "mova-flat-runner 说明书",
      "toc": [
        "https://github.com/mova-compact/mova-flat-runner 项目说明书",
        "目录",
        "Project Overview",
        "Introduction",
        "High-Level Architecture",
        "Project Structure",
        "Core Source Files",
        "Configuration",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "e19d6945aa0befed8d0508bbe47ba81a8888786e",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "package.json",
      "README.md",
      "docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_V0.md",
      "docs/PROMOTION_PATCH_2_NOTE_v1.md",
      "docs/CODEX_NATIVE_MCP_SETUP_V0.md",
      "docs/FLAT_RUNNER_BOUNDARY_v0.md",
      "docs/CONTENT_FLYWHEEL_REGISTERED_PACK_RUNBOOK_V0.md",
      "docs/MCP_PACKAGE_GLOBAL_SUPPORT_V0.md",
      "docs/MCP_CONTRACT_EXTENSION_AUDIT_V0.md",
      "docs/PACKAGE_GLOBAL_PARITY_AUDIT_V0.md",
      "docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_RESULT.json",
      "src/schemas.ts",
      "src/index.ts",
      "src/client.ts",
      "src/types.ts",
      "src/package_support.ts",
      "src/transports/remote_api.ts",
      "src/transports/local_seam_bridge.ts",
      "src/validators/trade.ts",
      "src/validators/invoice.ts",
      "src/validators/compliance.ts",
      "src/validators/credit.ts",
      "src/validators/supply_chain.ts",
      "src/validators/registry.ts",
      "src/validators/complaint.ts",
      "src/validators/churn.ts",
      "src/validators/contract_gen.ts",
      "src/validators/aml.ts",
      "src/validators/po.ts",
      "src/validation/dataspec.ts",
      "src/security/system_contract_guard.ts",
      "src/security/determinism_guard.ts",
      "src/security/flow_schema_guard.ts",
      "src/security/graph_guard.ts",
      "src/security/gate_guard.ts",
      "src/security/class_definition_guard.ts",
      "src/security/step_mode_guard.ts"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# @leryk1981/mova-flat-runner - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 @leryk1981/mova-flat-runner 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `curl -sS https://api.mova-lab.eu/health` 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`, `dist-test/src/index.js`, `dist-test/tests/smoke/api.d.ts`, `dist-test/tests/smoke/api.js` 等\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0004` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0005` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：152\n- 重要文件覆盖：31/152\n- 证据索引条目：31\n- 角色 / Skill 条目：11\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 @leryk1981/mova-flat-runner 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 @leryk1981/mova-flat-runner 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 @leryk1981/mova-flat-runner 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 11 个角色 / Skill / 项目文档条目。\n\n- **MCP Registry**（project_doc）：Authoritative native MCP connection: - npm package: @leryk1981/mova-flat-runner - version: 3.3.3 - binary: mova-mcp - command: npx -y @leryk1981/mova-flat-runner@3.3.3 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **Package Global Support Fixture**（project_doc）：This fixture exercises package-manifest registration with optional global ref . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`tests/fixtures/package_global_support_v0/README.md`\n- **CODEX Native MCP Setup V0**（project_doc）：Date: 2026-05-08 Repository: D:\\Projects MOVA\\mova-mcp 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CODEX_NATIVE_MCP_SETUP_V0.md`\n- **Content Flywheel Registered Pack Runbook v0**（project_doc）：Content Flywheel Registered Pack Runbook v0 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CONTENT_FLYWHEEL_REGISTERED_PACK_RUNBOOK_V0.md`\n- **MOVA Flat Runner — Layer Boundary v0**（project_doc）：MOVA Flat Runner — Layer Boundary v0 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/FLAT_RUNNER_BOUNDARY_v0.md`\n- **LOCAL MSR RUNTIME RUN AUDIT V0**（project_doc）：Date: 2026-05-08 Repo: D:/Projects MOVA/mova-mcp 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_V0.md`\n- **MCP Contract Extension Audit v0**（project_doc）：mova-mcp currently exposes two contract models in parallel: 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/MCP_CONTRACT_EXTENSION_AUDIT_V0.md`\n- **MCP Package Global Support v0**（project_doc）：mova-mcp supports optional package-local global ref on package manifests as read-only semantic metadata. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/MCP_PACKAGE_GLOBAL_SUPPORT_V0.md`\n- **Package Global Parity Audit v0**（project_doc）：Core package-global parity is present between mova-contract-spec@e657b77 and mova-mcp@747b5c2 , including field naming schema id and non-authoritative intent. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/PACKAGE_GLOBAL_PARITY_AUDIT_V0.md`\n- **Promotion Patch 2 Note v1**（project_doc）：What Was Moved Into mova-flat-runner - bridged local transport in src/transports/local seam bridge.ts - remote transport in src/transports/remote api.ts - thin facade and selector in src/client.ts - canonical freeze test and bridged e2e test 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/PROMOTION_PATCH_2_NOTE_v1.md`\n- **task061 — Fix custom contract audit identity bridge in mova-mcp**（project_doc）：task061 — Fix custom contract audit identity bridge in mova-mcp 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`tasks/task061.md`\n\n## 证据索引\n\n- 共索引 31 条证据。\n\n- **MCP Registry**（documentation）：Authoritative native MCP connection: - npm package: @leryk1981/mova-flat-runner - version: 3.3.3 - binary: mova-mcp - command: npx -y @leryk1981/mova-flat-runner@3.3.3 证据：`README.md`\n- **Package Global Support Fixture**（documentation）：This fixture exercises package-manifest registration with optional global ref . 证据：`tests/fixtures/package_global_support_v0/README.md`\n- **Package**（package_manifest）：{ \"name\": \"@leryk1981/mova-flat-runner\", \"version\": \"3.3.4\", \"mcpName\": \"io.github.mova-compact/mova-flat-runner\", \"description\": \"MCP server for governed AI workflows — invoice OCR, AML triage, credit review, and custom contracts with human approval gates and audit trails\", \"type\": \"module\", \"license\": \"MIT-0\", \"keywords\": \"mcp\", \"mcp-server\", \"model-context-protocol\", \"claude\", \"cursor\", \"anthropic\", \"hitl\", \"human-in-the-loop\", \"audit-trail\", \"invoice-ocr\", \"aml\", \"compliance\", \"workflow-automation\", \"contract-execution\", \"mova\" , \"homepage\": \"https://github.com/mova-compact/mova-flat-runner\", \"repository\": { \"type\": \"git\", \"url\": \"git+https://github.com/mova-compact/mova-flat-runner.git… 证据：`package.json`\n- **License**（source_file）：The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 \"Apache-2.0\" . All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions excluding specifications are licensed under CC-BY-4.0. 证据：`LICENSE`\n- **CODEX Native MCP Setup V0**（documentation）：Date: 2026-05-08 Repository: D:\\Projects MOVA\\mova-mcp 证据：`docs/CODEX_NATIVE_MCP_SETUP_V0.md`\n- **Content Flywheel Registered Pack Runbook v0**（documentation）：Content Flywheel Registered Pack Runbook v0 证据：`docs/CONTENT_FLYWHEEL_REGISTERED_PACK_RUNBOOK_V0.md`\n- **MOVA Flat Runner — Layer Boundary v0**（documentation）：MOVA Flat Runner — Layer Boundary v0 证据：`docs/FLAT_RUNNER_BOUNDARY_v0.md`\n- **LOCAL MSR RUNTIME RUN AUDIT V0**（documentation）：Date: 2026-05-08 Repo: D:/Projects MOVA/mova-mcp 证据：`docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_V0.md`\n- **MCP Contract Extension Audit v0**（documentation）：mova-mcp currently exposes two contract models in parallel: 证据：`docs/MCP_CONTRACT_EXTENSION_AUDIT_V0.md`\n- **MCP Package Global Support v0**（documentation）：mova-mcp supports optional package-local global ref on package manifests as read-only semantic metadata. 证据：`docs/MCP_PACKAGE_GLOBAL_SUPPORT_V0.md`\n- **Package Global Parity Audit v0**（documentation）：Core package-global parity is present between mova-contract-spec@e657b77 and mova-mcp@747b5c2 , including field naming schema id and non-authoritative intent. 证据：`docs/PACKAGE_GLOBAL_PARITY_AUDIT_V0.md`\n- **Promotion Patch 2 Note v1**（documentation）：What Was Moved Into mova-flat-runner - bridged local transport in src/transports/local seam bridge.ts - remote transport in src/transports/remote api.ts - thin facade and selector in src/client.ts - canonical freeze test and bridged e2e test 证据：`docs/PROMOTION_PATCH_2_NOTE_v1.md`\n- **task061 — Fix custom contract audit identity bridge in mova-mcp**（documentation）：task061 — Fix custom contract audit identity bridge in mova-mcp 证据：`tasks/task061.md`\n- **Local Msr Runtime Run Audit Result**（structured_config）：{ \"started at\": \"2026-05-08T14:39:25.909Z\", \"launch method\": { \"working directory\": \"D:/Projects MOVA/mova-mcp\", \"command\": \"node dist/index.js\", \"transport\": \"local HTTP invoke endpoint /invoke \", \"url\": \"http://127.0.0.1:3796/invoke\", \"auth\": \"Bearer MOVA INVOKE TOKEN\", \"env keys used\": \"MOVA API URL\", \"MOVA API KEY\", \"LLM KEY\", \"LLM MODEL\", \"MOVA API TIMEOUT MS\", \"MOVA HTTP PORT\", \"MOVA INVOKE TOKEN\" }, \"invocation shape\": { \"request body\": \"{ \\\"tool\\\": \\\" \\\", \\\"args\\\": { ... } }\", \"tools tested\": \"mova health\", \"mova run\", \"mova query\", \"mova contract\" }, \"candidates tested\": { \"id\": \"health\", \"tool\": \"mova health\", \"payload\": {}, \"source path\": null, \"result\": { \"ok\": true, \"request id… 证据：`docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_RESULT.json`\n- **Server**（structured_config）：{ \"$schema\": \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\", \"name\": \"io.github.mova-compact/mova-flat-runner\", \"version\": \"2.0.6\", \"description\": \"Governed AI workflows with human approval gates and audit trails for Claude and MCP clients.\", \"repository\": { \"url\": \"https://github.com/mova-compact/mova-flat-runner\", \"source\": \"github\" }, \"packages\": { \"registryType\": \"npm\", \"identifier\": \"mova-mcp\", \"version\": \"2.0.6\", \"runtimeHint\": \"node\", \"transport\": { \"type\": \"stdio\" }, \"environmentVariables\": { \"name\": \"MOVA API KEY\", \"description\": \"MOVA API key. Use test-key-001 to get started without registration.\", \"required\": true }, { \"name\": \"LLM KEY\", \"descripti… 证据：`server.json`\n- **Tsconfig**（structured_config）：{ \"compilerOptions\": { \"target\": \"ES2022\", \"module\": \"NodeNext\", \"moduleResolution\": \"NodeNext\", \"outDir\": \"./dist\", \"rootDir\": \"./src\", \"strict\": true, \"esModuleInterop\": true, \"skipLibCheck\": true, \"declaration\": true }, \"include\": \"src/ / \" } 证据：`tsconfig.json`\n- **Tsconfig.Test**（structured_config）：{ \"extends\": \"./tsconfig.json\", \"compilerOptions\": { \"rootDir\": \".\", \"outDir\": \"./dist-test\" }, \"include\": \"src/ / \", \"tests/ / \" } 证据：`tsconfig.test.json`\n- **Flow**（structured_config）：{ \"version\": \"1.0\", \"description\": \"Minimal external pack flow fixture for registration-path guard smoke.\", \"entry\": \"analyze\", \"steps\": { \"id\": \"analyze\", \"execution mode\": \"AI ATOMIC\", \"model\": \"openai/gpt-4o-mini\", \"next\": { \"default\": { \"step\": \"verify\" } } }, { \"id\": \"verify\", \"execution mode\": \"DETERMINISTIC\", \"next\": { \"default\": { \"step\": \"decide\" } } }, { \"id\": \"decide\", \"execution mode\": \"HUMAN GATE\", \"decision options\": { \"option id\": \"APPROVED FOR PUBLICATION\", \"label\": \"Approve\" }, { \"option id\": \"NEEDS REWRITE\", \"label\": \"Rewrite\" } , \"next\": { \"approved\": { \"terminal\": \"published\" }, \"default\": { \"terminal\": \"stopped\" } } } } 证据：`tests/fixtures/content_flywheel_registered_pack/flow.json`\n- **Flow**（structured_config）：{ \"version\": \"1.0\", \"description\": \"Minimal external pack flow fixture for registration-path guard smoke.\", \"entry\": \"analyze\", \"steps\": { \"id\": \"analyze\", \"execution mode\": \"AI ATOMIC\", \"model\": \"openai/gpt-4o-mini\", \"next\": { \"default\": { \"step\": \"verify\" } } }, { \"id\": \"verify\", \"execution mode\": \"DETERMINISTIC\", \"next\": { \"default\": { \"step\": \"decide\" } } }, { \"id\": \"decide\", \"execution mode\": \"HUMAN GATE\", \"decision options\": { \"option id\": \"APPROVED FOR PUBLICATION\", \"label\": \"Approve\" }, { \"option id\": \"NEEDS REWRITE\", \"label\": \"Rewrite\" } , \"next\": { \"approved\": { \"terminal\": \"published\" }, \"default\": { \"terminal\": \"stopped\" } } } } 证据：`tests/fixtures/package_global_support_v0/flow.json`\n- **Global**（structured_config）：{ \"schema id\": \"package.global v0\", \"global id\": \"content flywheel pipeline global v0\", \"version\": \"0.1.0\", \"scope\": \"contract package\", \"extends\": , \"semantic roles\": { \"id\": \"manifest\", \"role\": \"package manifest\", \"authority\": \"documentation\", \"maturity\": \"canonical\", \"applies to\": \"manifest.json\" , \"allowed use\": \"discover package metadata\", \"load package references\" , \"forbidden use\": \"execute runtime\", \"choose flow transitions\" , \"notes\": \"Package entrypoint and references only.\" }, { \"id\": \"flow\", \"role\": \"contract flow\", \"authority\": \"structural\", \"maturity\": \"canonical\", \"applies to\": \"flow.json\" , \"allowed use\": \"inspect step topology\", \"load flow structure\" , \"forbidden use\": \"ove… 证据：`tests/fixtures/package_global_support_v0/global.json`\n- **Manifest**（structured_config）：{ \"schema id\": \"package.contract package manifest v0\", \"package id\": \"content flywheel pipeline v0\", \"version\": \"0.1.0\", \"global ref\": \"global.json\", \"flow ref\": \"flow.json\", \"classification policy ref\": \"classification policy.json\", \"classification result set ref\": \"classification results.json\", \"classification result refs\": \"classification://analyze\", \"classification://verify\", \"classification://decide\" , \"runtime binding set ref\": \"runtime binding set.json\", \"model refs\": \"models/input model v0.json\", \"models/verification model v0.json\" , \"fixture refs\": \"fixtures/\" , \"package invariants\": \"global is non-authoritative semantic context only\" } 证据：`tests/fixtures/package_global_support_v0/manifest.json`\n- **.gitignore**（source_file）：node modules/ mcp-publisher.exe mcp-publisher.tar.gz registry-1.6.0.zip registry-1.6.0/ .env.local .global-run. .log .mova-http. .log 证据：`.gitignore`\n- **Smithery**（source_file）：name: mova-flat-runner displayName: MOVA Flat Runner description: Governed AI workflow execution for Claude and MCP-compatible clients. Run invoice OCR, AML triage, credit review, supplier screening, and custom contracts — each with a mandatory human decision gate and a cryptographically signed audit trail. 证据：`smithery.yaml`\n- **Client**（source_file）：import { type FlatRunnerResult, type ValidatorRef } from \"./types.js\"; import { type MovaConfig, isLocalSeamConfig, movaGetDecisionPointLocal, movaGetTerminalOutcomeLocal, movaResumeContractLocal, movaRunStepsLocal, movaSubmitDecisionLocal, shortId, } from \"./transports/local seam bridge.js\"; import { movaDelete, movaGet, movaPost, movaPut, movaRunStepsRemote, } from \"./transports/remote api.js\"; 证据：`src/client.ts`\n- **!/usr/bin/env node**（source_file）：!/usr/bin/env node import { Server } from \"@modelcontextprotocol/sdk/server/index.js\"; import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"; import { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\"; import { createServer } from \"node:http\"; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, } from \"@modelcontextprotocol/sdk/types.js\"; import { movaPost, movaGet, movaPut, movaDelete, movaRunSteps, shortId, type MovaConfig, } from \"./client.js\"; import { CONTRACT MANIFESTS, ENVELOPE SCHEMA } from \"./schemas.js\"; import { ERR, fla… 证据：`src/index.ts`\n- **Package Support**（source_file）：import fs from \"node:fs/promises\"; import path from \"node:path\"; 证据：`src/package_support.ts`\n- **Schemas**（source_file）：// ── MOVA Schema Layer ───────────────────────────────────────────────────────── // Contract manifests, DataSpecs, and Envelope type definitions. // This is the structural source of truth for the MCP server. // Business logic lives on the MOVA platform; this file carries only the // schema skeleton needed for input validation and Resource exposure. 证据：`src/schemas.ts`\n- **Types**（source_file）：// ── MOVA Flat Runner — canonical types ──────────────────────────────────────── 证据：`src/types.ts`\n- **Bridge Contract V1.Freeze.Test**（source_file）：import test from \"node:test\"; import assert from \"node:assert/strict\"; import fs from \"node:fs/promises\"; import os from \"node:os\"; import path from \"node:path\"; 证据：`tests/bridge_contract_v1.freeze.test.ts`\n- **Flat Runner Bridge V1.Test**（source_file）：import test from \"node:test\"; import assert from \"node:assert/strict\"; import fs from \"node:fs/promises\"; import os from \"node:os\"; import path from \"node:path\"; 证据：`tests/flat_runner_bridge_v1.test.ts`\n- **Start Http Local**（source_file）：$envFile = Join-Path $PSScriptRoot '..\\.env.local' if ! Test-Path -LiteralPath $envFile { throw \".env.local not found at $envFile\" } Get-Content -LiteralPath $envFile ForEach-Object { if $ -match '^ A-Z0-9 +=' { $k,$v = $ .Split '=',2 Environment ::SetEnvironmentVariable $k,$v,'Process' } } $root = Resolve-Path Join-Path $PSScriptRoot '..' Set-Location $root & 'D:\\DevTools\\node.exe' 'dist/index.js' 证据：`tools/start-http-local.ps1`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `tests/fixtures/package_global_support_v0/README.md`, `package.json`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `tests/fixtures/package_global_support_v0/README.md`, `package.json`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **Project Overview**：importance `high`\n  - source_paths: README.md, package.json, src/index.ts, src/types.ts\n- **Core MCP Tools**：importance `high`\n  - source_paths: src/client.ts, src/index.ts, src/schemas.ts\n- **Installation and Setup**：importance `high`\n  - source_paths: README.md, package.json, smithery.yaml, server.json\n- **System Architecture**：importance `high`\n  - source_paths: src/index.ts, src/client.ts, src/package_support.ts, src/transports/local_seam_bridge.ts, src/transports/remote_api.ts\n- **Security Guards**：importance `high`\n  - source_paths: src/security/class_definition_guard.ts, src/security/determinism_guard.ts, src/security/flow_schema_guard.ts, src/security/gate_guard.ts, src/security/graph_guard.ts\n- **Transport Layer**：importance `high`\n  - source_paths: src/transports/local_seam_bridge.ts, src/transports/remote_api.ts, tools/start-http-local.ps1\n- **Domain Validators**：importance `high`\n  - source_paths: src/validators/registry.ts, src/validators/aml.ts, src/validators/churn.ts, src/validators/complaint.ts, src/validators/compliance.ts\n- **Data Schemas and Types**：importance `medium`\n  - source_paths: src/schemas.ts, src/types.ts, src/validation/dataspec.ts, src/package_support.ts\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `e19d6945aa0befed8d0508bbe47ba81a8888786e`\n- inspected_files: `package.json`, `README.md`, `docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_V0.md`, `docs/PROMOTION_PATCH_2_NOTE_v1.md`, `docs/CODEX_NATIVE_MCP_SETUP_V0.md`, `docs/FLAT_RUNNER_BOUNDARY_v0.md`, `docs/CONTENT_FLYWHEEL_REGISTERED_PACK_RUNBOOK_V0.md`, `docs/MCP_PACKAGE_GLOBAL_SUPPORT_V0.md`, `docs/MCP_CONTRACT_EXTENSION_AUDIT_V0.md`, `docs/PACKAGE_GLOBAL_PARITY_AUDIT_V0.md`, `docs/LOCAL_MSR_RUNTIME_RUN_AUDIT_RESULT.json`, `src/schemas.ts`, `src/index.ts`, `src/client.ts`, `src/types.ts`, `src/package_support.ts`, `src/transports/remote_api.ts`, `src/transports/local_seam_bridge.ts`, `src/validators/trade.ts`, `src/validators/invoice.ts`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 可能修改宿主 AI 配置\n\n- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。\n- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- Evidence: capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 来源证据：v3.0.0 — Step Enforcement Runtime\n\n- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：v3.0.0 — Step Enforcement Runtime\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_10b68dae59184a36b21a563722829aed | https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0 | 来源类型 github_release 暴露的待验证使用条件。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：mova-compact/mova-flat-runner\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：mcp_host, claude, chatgpt\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## 项目专属踩坑\n\n- 可能修改宿主 AI 配置（medium）：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 来源证据：v3.0.0 — Step Enforcement Runtime（medium）：可能影响升级、迁移或版本选择。 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/mova-compact/mova-flat-runner 项目说明书\n\n生成时间：2026-05-15 07:59:21 UTC\n\n## 目录\n\n- [Project Overview](#page-project-overview)\n- [Core MCP Tools](#page-core-tools)\n- [Installation and Setup](#page-installation-setup)\n- [System Architecture](#page-architecture)\n- [Security Guards](#page-security-guards)\n- [Transport Layer](#page-transport-layer)\n- [Domain Validators](#page-validators)\n- [Data Schemas and Types](#page-data-schemas)\n- [Deployment and Operations](#page-deployment)\n- [Extensibility and Customization](#page-extensibility)\n\n<a id='page-project-overview'></a>\n\n## Project Overview\n\n### 相关页面\n\n相关主题：[Core MCP Tools](#page-core-tools), [Installation and Setup](#page-installation-setup), [System Architecture](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Project Overview\n\n## Introduction\n\n**mova-flat-runner** (`@leryk1981/mova-flat-runner`) is an MCP (Model Context Protocol) server that provides governed AI workflows with human approval gates and audit trails. It enables AI-powered contract execution with built-in compliance controls for workflows such as invoice OCR, AML (Anti-Money Laundering) triage, credit review, and custom contract management. 资料来源：[package.json:1-15]()\n\nThe project serves as the authoritative native MCP connection for the MOVA Operator platform, allowing MCP clients like Claude Desktop and Codex to interact with governed AI workflows through a standardized interface. 资料来源：[README.md:1-30]()\n\n## High-Level Architecture\n\nThe mova-flat-runner implements a layered architecture that bridges MCP clients with the MOVA API backend, providing both remote execution through the MOVA cloud and local execution capabilities.\n\n```mermaid\ngraph TD\n    subgraph \"MCP Clients\"\n        Claude[\"Claude Desktop\"]\n        Codex[\"Codex IDE\"]\n    end\n\n    subgraph \"Mova Flat Runner\"\n        MCPServer[\"MCP Server Entry Point<br/>dist/index.js\"]\n        ToolExecutor[\"Tool Executor<br/>executeTool()\"]\n        RemoteAPI[\"Remote API Transport<br/>movaRequest()\"]\n        LocalSeamBridge[\"Local Seam Bridge<br/>local_seam_bridge.ts\"]\n        StepModeGuard[\"Step Mode Guard<br/>step_mode_guard.ts\"]\n    end\n\n    subgraph \"MOVA Backend\"\n        API[\"MOVA API<br/>api.mova-lab.eu\"]\n        ContractDB[\"Contract Registry\"]\n        RunEngine[\"Run Engine\"]\n    end\n\n    Claude --> MCPServer\n    Codex --> MCPServer\n    MCPServer --> ToolExecutor\n    ToolExecutor --> RemoteAPI\n    ToolExecutor --> LocalSeamBridge\n    RemoteAPI --> API\n    LocalSeamBridge --> RunEngine\n    API --> ContractDB\n```\n\n## Project Structure\n\n| Directory | Purpose |\n|-----------|---------|\n| `cmd/` | Application entry points (publisher CLI) |\n| `internal/api/` | HTTP handlers and routing |\n| `internal/auth/` | Authentication (GitHub OAuth, JWT, namespace blocking) |\n| `internal/config/` | Configuration management |\n| `internal/database/` | Data persistence (PostgreSQL) |\n| `internal/service/` | Business logic layer |\n| `internal/telemetry/` | Metrics and monitoring |\n| `internal/validators/` | Input validation |\n| `pkg/` | Public packages |\n| `src/` | Main application source code |\n\n资料来源：[README.md:30-50]()\n\n## Core Source Files\n\n### Entry Point: `dist/index.js`\n\nThe binary entry point is defined in `package.json`:\n\n```json\n{\n  \"bin\": {\n    \"mova-mcp\": \"dist/index.js\"\n  }\n}\n```\n\n资料来源：[package.json:22-24]()\n\nThe server is started using `npx` with the npm package `@leryk1981/mova-flat-runner`:\n\n```bash\nnpx -y @leryk1981/mova-flat-runner@3.3.3\n```\n\n资料来源：[README.md:15-20]()\n\n### Main Server Implementation: `src/index.ts`\n\nThe core implementation handles tool execution through a switch-based `executeTool()` function that routes requests to the appropriate handler. 资料来源：[src/index.ts:200-300]()\n\n#### Tool Categories\n\nThe server exposes the following tool categories:\n\n| Tool Prefix | Purpose |\n|-------------|---------|\n| `mova_run` | Execute built-in contract workflows |\n| `mova_contract` | Register and manage custom contracts |\n| `mova_query` | Query contract status and audit trails |\n| `mova_decide` | Handle decision points |\n| `mova_connector` | External system integration |\n| `mova_health` | Health check operations |\n\n资料来源：[README.md:55-65]()\n\n#### Key Tool Handlers\n\n**`mova_run` Handler** (`src/index.ts`)\n- Validates contract type against built-in manifests\n- Bridges to either remote API or local execution\n- Returns structured JSON responses\n\n**`mova_contract` Actions**:\n- `register`: `POST /api/v1/contracts/register`\n- `run`: `POST /run/{contract_id}`\n- `run_status`: `GET /run/{run_id}/status`\n\n资料来源：[src/index.ts:100-200]()\n\n**`mova_query` Views**:\n- `status`: Returns bridged run status\n- `audit`: Returns audit trail (backend-dependent for custom contracts)\n- `audit_compact`: Returns structured unavailability for custom IDs\n\n资料来源：[tasks/task061.md:1-30]()\n\n### HTTP Transport: `movaRequest()`\n\nAll API communication uses a unified transport layer:\n\n```typescript\nexport const movaGet = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPut = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\nexport const movaPost = (config, path, body) => movaRequest(config, \"POST\", path, body);\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:80-85]()\n\n### Local Seam Bridge: `src/transports/local_seam_bridge.ts`\n\nThe local seam bridge enables local execution of contract steps without requiring remote API calls. It handles:\n\n- **Execution Modes**: `AI_ATOMIC`, `HUMAN_GATE`, `DETERMINISTIC`, `CONTRACT_CALL`\n- **State Management**: Bridge state references and terminal outcomes\n- **Verification**: Pass/fail verification payloads with invariant checks\n\n```typescript\nconst producedOutput =\n  request.step.execution_mode === \"AI_ATOMIC\"\n    ? CANONICAL_STRATEGY\n    : request.stepResult ?? null;\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:1-50]()\n\n#### Bridge Response Structure\n\n| Field | Description |\n|-------|-------------|\n| `status` | `\"completed\"`, `\"advanced\"`, or `\"human_gate_required\"` |\n| `execution_mode` | Step execution mode |\n| `produced_output` | Output data for AI_ATOMIC steps |\n| `gate_required` | Boolean indicating human approval needed |\n| `next_phase` | `\"EXECUTION\"` or `\"WAIT_HUMAN\"` |\n| `verification_payload` | Pass/fail verification checks |\n\n资料来源：[src/transports/local_seam_bridge.ts:15-30]()\n\n### Security: `src/security/step_mode_guard.ts`\n\nThe step mode guard validates that contract step definitions conform to their declared execution modes:\n\n| Violation Type | Condition |\n|----------------|-----------|\n| `deterministic_with_model` | DETERMINISTIC step has a `model` field |\n| `ai_atomic_without_model` | AI_ATOMIC step missing `model` field |\n| `contract_call_without_contract_id` | CONTRACT_CALL step missing `contract_id` |\n| `human_gate_without_decisions` | HUMAN_GATE step missing `decision_options` |\n\n```typescript\nexport function findStepModeViolations(flow): Violation[] {\n  // Validates each step's execution_mode against its required fields\n}\n\nexport function assertStepModesValid(flow, requestId): FlatRunnerResult | null {\n  // Returns error result if violations found\n}\n```\n\n资料来源：[src/security/step_mode_guard.ts:1-80]()\n\n### Package Support: `src/package_support.ts`\n\nContract packages are validated for structural integrity before execution:\n\n```typescript\nfunction validateGlobalShape(value: unknown): string | null {\n  // Validates global file structure:\n  // - schema_id: \"contract_package_global_v1\"\n  // - version: required string\n  // - semantic_roles: non-empty array\n  // - non_authority_rules: non-empty array\n}\n\nfunction validatePackageManifestShape(value: unknown): string | null {\n  // Validates manifest structure:\n  // - Allowed keys: schema_id, package_id, version, flow_ref, etc.\n  // - Required strings: package_id, version, flow_ref\n}\n```\n\n资料来源：[src/package_support.ts:1-50]()\n\n## Configuration\n\n### Required Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_URL` | MOVA API base URL | `https://api.mova-lab.eu` |\n| `MOVA_API_KEY` | MOVA API authentication key | — |\n| `LLM_KEY` | OpenRouter API key for LLM analysis | — |\n| `LLM_MODEL` | OpenRouter model ID | `openai/gpt-4o-mini` |\n\n### Optional Local HTTP Mode Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_TIMEOUT_MS` | API request timeout | `30000` |\n| `MOVA_HTTP_PORT` | Local HTTP server port | `3796` |\n| `MOVA_INVOKE_TOKEN` | Local invoke authentication token | — |\n\n### Local Sandbox Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | Contract package location | `D:\\Projects_MOVA\\mova-intent\\contracts\\dockerfile-nodejs-v1` |\n| `MOVA_SANDBOX_PROJECT_PATH` | Project directory | (required) |\n| `MOVA_SANDBOX_STATE_FILE` | State persistence file | System temp directory |\n\n资料来源：[README.md:35-60]()\n\n## MCP Server Configuration\n\n### Claude Desktop Example\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n### Codex Config Example (TOML)\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:60-100]()\n\n## Build System\n\n### Available Make Targets\n\n| Target | Purpose |\n|--------|---------|\n| `make publisher` | Build the MCP publisher CLI |\n| `make check` | Run lint, unit tests, and integration tests |\n| `make help` | Display all available commands |\n\n资料来源：[README.md:10-20]()\n\n### Build Scripts (package.json)\n\n| Script | Description |\n|--------|-------------|\n| `npm run build` | Compile TypeScript and add shebang |\n| `npm run test:build` | Validate built output |\n| `npm run smoke:custom-bridge` | Smoke test for custom contract bridge |\n\n资料来源：[package.json:25-30]()\n\n### Server Registry Configuration\n\nThe `server.json` file defines the MCP server schema for the Model Context Protocol registry:\n\n```json\n{\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\",\n  \"description\": \"Governed AI workflows with human approval gates and audit trails\"\n}\n```\n\n资料来源：[server.json:1-15]()\n\n## Workflow Execution Modes\n\nThe system supports four execution modes for contract steps:\n\n```mermaid\ngraph LR\n    subgraph \"Execution Modes\"\n        AI[\"AI_ATOMIC<br/>LLM-driven step\"]\n        DET[\"DETERMINISTIC<br/>Local JS validation\"]\n        CALL[\"CONTRACT_CALL<br/>Cross-contract invocation\"]\n        GATE[\"HUMAN_GATE<br/>Human approval required\"]\n    end\n\n    AI --> Output1[\"Produces structured output\"]\n    DET --> Output2[\"Validation result\"]\n    CALL --> Output3[\"Sub-contract result\"]\n    GATE --> Output4[\"Awaiting decision\"]\n```\n\n| Mode | Model Field | Additional Fields | Use Case |\n|------|-------------|-------------------|----------|\n| `AI_ATOMIC` | Required | Output schema path | LLM analysis and decision-making |\n| `DETERMINISTIC` | Forbidden | — | Local validation logic |\n| `CONTRACT_CALL` | Optional | `contract_id` | Invoke another contract |\n| `HUMAN_GATE` | Optional | `decision_options` | Manual approval checkpoints |\n\n资料来源：[src/security/step_mode_guard.ts:30-70]()\n\n## Custom Contract Bridge\n\nThe mova-flat-runner implements a **Custom Query Bridge** to handle custom contract visibility across different API namespaces:\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant MFR as mova-flat-runner\n    participant Bridge as Custom Run Bridge\n    participant API as MOVA API\n\n    Note over Client,MFR: Contract Registration & Run\n    Client->>MFR: mova_contract register\n    MFR->>API: POST /api/v1/contracts/register\n    API-->>MFR: contract_id\n    MFR->>MFR: rememberCustomRun(contract_id, run_id)\n\n    Note over Client,MFR: Custom Query Flow\n    Client->>MFR: mova_query (404 from API)\n    MFR->>Bridge: Check CUSTOM_RUN_BRIDGE\n    Bridge-->>MFR: run_id mapping exists\n    MFR->>API: GET /api/v1/contracts/my\n    API-->>MFR: contract metadata\n    MFR-->>Client: Bridged status response\n```\n\n**Bridge Behavior**:\n- On `mova_contract run` and `run_status`: captures `contract_id -> run_id` mapping\n- On `mova_query status` (404): probes `/api/v1/contracts/my` and returns bridged status\n- On `mova_query audit` (404): returns honest `AUDIT_UNAVAILABLE` envelope\n\n资料来源：[tasks/task061.md:1-60]()\n\n## Security Considerations\n\n### API Key Management\n\n> **Security Note**: Do not commit real `MOVA_API_KEY`, `LLM_KEY`, or `MOVA_INVOKE_TOKEN`. 资料来源：[README.md:70-75]()\n\n### Step Mode Validation\n\nThe step mode guard enforces strict validation before execution:\n- Prevents DETERMINISTIC steps from using LLM models\n- Ensures AI_ATOMIC steps have model configuration\n- Validates HUMAN_GATE steps have decision options\n\n### Human Gate Protection\n\n```typescript\nconst gateGuard = await assertNotHumanGate(config, run_id, step_id, requestId);\nif (gateGuard) return gateGuard;\n```\n\nHuman gate steps cannot be completed via generic `step_complete` — they require the dedicated `gate_approve` / `gate_reject` path. 资料来源：[src/index.ts:200-250]()\n\n## References\n\n- **Repository**: https://github.com/mova-compact/mova-flat-runner\n- **npm Package**: `@leryk1981/mova-flat-runner`\n- **Current Version**: `3.3.4` 资料来源：[package.json:3]()\n- **MCP Registry**: https://registry.modelcontextprotocol.io\n- **API Health Check**: `https://api.mova-lab.eu/health`\n\n---\n\n<a id='page-core-tools'></a>\n\n## Core MCP Tools\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Transport Layer](#page-transport-layer), [System Architecture](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/schemas.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/schemas.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Core MCP Tools\n\n## Overview\n\nThe MOVA Flat Runner is an MCP (Model Context Protocol) server that provides governed AI workflow execution for Claude and MCP-compatible clients. The Core MCP Tools are the primary interface through which clients interact with the system to execute business workflows such as invoice OCR, AML triage, credit review, and custom contracts.\n\nThe tool executor is implemented in `executeTool()` within `src/index.ts` and handles all incoming tool requests via the MCP protocol. Each tool maps to a specific workflow action or API operation, with built-in validation, error handling, and security guards.\n\n资料来源：[src/index.ts:1-50]()\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client\"\n        A[Claude / Cursor / Codex]\n    end\n    \n    subgraph \"MOVA Flat Runner\"\n        B[executeTool dispatcher]\n        C[mova_run]\n        D[mova_contract]\n        E[mova_query]\n        F[mova_health]\n        G[mova_decide]\n        H[mova_connector]\n        I[mova_calibrate_intent]\n        J[step_complete / gate_approve / gate_reject]\n    end\n    \n    subgraph \"Backend Services\"\n        K[MOVA API]\n        L[OpenRouter LLM]\n        M[Local Sandbox]\n    end\n    \n    A --> B\n    B --> C\n    B --> D\n    B --> E\n    B --> F\n    B --> G\n    B --> H\n    B --> I\n    B --> J\n    \n    C --> K\n    D --> K\n    E --> K\n    C --> L\n    I --> L\n    J --> K\n    I --> M\n    \n    style B fill:#f9f,stroke:#333\n```\n\n## Available Tools Summary\n\n| Tool | Purpose | Primary API Endpoint |\n|------|---------|---------------------|\n| `mova_run` | Execute built-in contract workflows | `POST /api/v1/contracts/{id}/run` |\n| `mova_contract` | Register and run custom contracts | `POST /api/v1/contracts/register` |\n| `mova_query` | Query contract status, audit, and audit_compact | `GET /api/v1/contracts/{id}` |\n| `mova_health` | Health check for MOVA API | `GET /health` |\n| `mova_decide` | Submit human decision at approval gate | `POST /run/{run_id}/decision` |\n| `mova_connector` | Connect to external data sources | Internal service routing |\n| `mova_calibrate_intent` | Convert natural language to contract | LLM + local sandbox |\n| `step_complete` | Mark a step as complete | `POST /run/{run_id}/step/{step_id}/complete` |\n| `gate_approve` | Approve human gate | `POST /run/{run_id}/gate/approve` |\n| `gate_reject` | Reject human gate | `POST /run/{run_id}/gate/reject` |\n| `run_status` | Check run status | `GET /run/{run_id}/status` |\n\n资料来源：[src/index.ts:180-220]()\n\n## Tool Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant MCP as MOVA Flat Runner\n    participant API as MOVA Backend API\n    participant LLM as OpenRouter LLM\n    participant Sandbox as Local Sandbox\n\n    Client->>MCP: executeTool(name, args)\n    MCP->>MCP: validateArgs(args)\n    \n    alt Built-in Contract\n        MCP->>MCP: resolveManifest(contract_type)\n        MCP->>API: movaRunStepsRemote()\n        API-->>MCP: step results\n    end\n    \n    alt Custom Contract\n        MCP->>API: mova_contract register/run\n        API-->>MCP: run_id\n        MCP->>MCP: rememberCustomRun()\n    end\n    \n    alt Human Gate Required\n        MCP-->>Client: {status: \"waiting_human\", options: [...]}\n        Client->>MCP: mova_decide / gate_approve / gate_reject\n        MCP->>API: POST /run/{run_id}/decision\n    end\n    \n    alt AI Atomic Step\n        MCP->>LLM: analyze(inputs)\n        LLM-->>MCP: analysis result\n    end\n    \n    MCP-->>Client: final result\n```\n\n## Core Tools Detail\n\n### mova_run\n\nExecutes built-in contract workflows using predefined manifests. Built-in contracts include invoice OCR, AML triage, credit review, and supplier screening.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `contract_type` | string | Yes | The type of contract to execute (e.g., \"invoice_ocr\", \"aml_triage\") |\n| `inputs` | object | Yes | Initial inputs for the contract workflow |\n\n**Workflow:**\n\n1. Resolves the contract manifest from `CONTRACT_MANIFESTS`\n2. Initializes the contract via `POST /api/v1/contracts/{id}/run`\n3. Executes steps remotely via `movaRunStepsRemote()`\n4. Returns structured response with status and outputs\n\n**Security Validation:**\n\nThe `step_mode_guard.ts` validates that:\n- `AI_ATOMIC` steps have a `model` field defined\n- `DETERMINISTIC` steps do NOT have a `model` field\n- `CONTRACT_CALL` steps have a `contract_id` field\n- `HUMAN_GATE` steps have `decision_options` array\n\n资料来源：[src/index.ts:200-280]()\n\n### mova_contract\n\nHandles custom contract registration and execution. Custom contracts can be created via natural language using `mova_calibrate_intent` or by registering existing contract definitions.\n\n**Actions:**\n\n| Action | Description | API Endpoint |\n|--------|-------------|---------------|\n| `register` | Register a new contract definition | `POST /api/v1/contracts/register` |\n| `run` | Execute a custom contract | `POST /run/{contract_id}` |\n| `run_status` | Check custom contract run status | `GET /run/{run_id}/status` |\n\n**Custom Run Bridge:**\n\nWhen a custom contract is run, the system captures and persists a `contract_id -> run_id` mapping in `CUSTOM_RUN_BRIDGE`:\n\n```typescript\nconst ref = { run_id: runId, updated_at: new Date().toISOString() };\nif (typeof sourceUrl === \"string\" && sourceUrl.length > 0)\n    ref.source_url = sourceUrl;\nCUSTOM_RUN_BRIDGE.set(contractId, ref);\n```\n\nThis bridge enables `mova_query` to return status for custom contracts that may not exist in the standard contracts API namespace.\n\n资料来源：[src/index.ts:280-350]()\n\n### mova_query\n\nQueries contract status, audit records, and compact audit information. This tool provides visibility into contract execution state and historical audit trails.\n\n**Views:**\n\n| View | Description | Response Format |\n|------|-------------|-----------------|\n| `status` | Current contract/run status | Bridged status with `bridge_mode=custom_contract_run_namespace_bridge_v1` for custom contracts |\n| `audit` | Full audit record | Returns `AUDIT_UNAVAILABLE` envelope when backend namespace is absent |\n| `audit_compact` | Compact audit summary | Structured unavailable object with `ok=false, status=424` |\n\n**On 404 Response:**\n\nWhen the API returns 404, `mova_query` probes `/api/v1/contracts/my` to check if the contract exists in the user's contract list. If found via `CUSTOM_RUN_BRIDGE`, it returns bridged status rather than a 404 error.\n\n资料来源：[src/index.ts:350-420]()\n\n### mova_health\n\nPerforms a health check on the MOVA API backend.\n\n**Endpoint:** `GET /health`\n\n**Response:** Returns health status of the MOVA API service.\n\n资料来源：[server.json:1-50]()\n\n### mova_decide\n\nSubmits human decision at an approval gate. This is the primary mechanism for human-in-the-loop (HITL) interactions.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `option_id` | string | Yes | The selected decision option |\n\n**Flow:**\n\n1. Fetches decision point from `GET /api/v1/contracts/{contractId}/decision`\n2. Presents `question` and `options` to the human\n3. Human selects an `option_id`\n4. Submits via `POST /run/{run_id}/decision`\n\n资料来源：[src/transports/remote_api.ts:1-80]()\n\n### mova_calibrate_intent\n\nConverts natural language descriptions into structured contract definitions using LLM processing and local sandbox validation.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `description` | string | Yes | Natural language description of the business process |\n| `package_path` | string | No | Path to contract package for sandbox execution |\n| `project_path` | string | No | Path to project files |\n\n**Process:**\n\n1. Sends description to OpenRouter LLM for structured extraction\n2. Validates the generated contract in local sandbox via `resolveLocalSeamLocator()`\n3. Returns validated contract definition ready for registration\n\n资料来源：[src/transports/local_seam_bridge.ts:1-100]()\n\n### step_complete, gate_approve, gate_reject\n\nManagement tools for contract execution state.\n\n**step_complete:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The step to complete |\n| `outcome` | string | No | Outcome identifier (default: \"default\") |\n| `output` | object | No | Step output data |\n\n**Security Guard:** `assertNotHumanGate()` prevents generic `step_complete` from being used on `HUMAN_GATE` steps. Human gates must use the dedicated `gate_approve` / `gate_reject` paths.\n\n**gate_approve:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The gate step |\n| `notes` | string | No | Approval notes |\n\n**gate_reject:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `run_id` | string | Yes | The run identifier |\n| `step_id` | string | Yes | The gate step |\n| `reason` | string | No | Rejection reason |\n\n资料来源：[src/index.ts:420-500]()\n\n## Step Execution Modes\n\nThe MOVA system supports multiple step execution modes for different workflow requirements:\n\n| Mode | Description | Required Fields |\n|------|-------------|-----------------|\n| `AI_ATOMIC` | Single LLM call that must complete atomically | `model`, `prompt` |\n| `DETERMINISTIC` | Local JavaScript evaluation, no LLM | No `model` field |\n| `HUMAN_GATE` | Requires human decision before proceeding | `decision_options` |\n| `CONTRACT_CALL` | Calls another contract | `contract_id` |\n\n资料来源：[src/security/step_mode_guard.ts:1-80]()\n\n## Local Seam Bridge\n\nFor workflows requiring local execution, the `local_seam_bridge.ts` provides an interface to sandboxed contract execution:\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs) {\n    const packagePath = process.env.MOVA_SANDBOX_PACKAGE_PATH \n        ?? \"D:\\\\Projects_MOVA\\\\mova-intent\\\\contracts\\\\dockerfile-nodejs-v1\";\n    const projectPath = process.env.MOVA_SANDBOX_PROJECT_PATH ?? \"\";\n    // ...\n}\n```\n\nThe bridge produces standardized output conforming to the canonical strategy pattern:\n\n```typescript\nreturn {\n    ok: true,\n    bridge: {\n        ok: true,\n        bridge_source: \"mova_flat_runner_canonical_bridge\",\n        status: \"completed\" | \"advanced\" | \"human_gate_required\",\n        execution_mode: request.step.execution_mode,\n        next_phase: { phase: status === \"human_gate_required\" ? \"WAIT_HUMAN\" : \"EXECUTION\" },\n        verification_payload: { status: \"PASS\", checks: [...] }\n    }\n};\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:100-180]()\n\n## Remote API Transport\n\nThe remote API transport (`remote_api.ts`) handles communication with the MOVA backend:\n\n```typescript\nexport const movaGet = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPut = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\n```\n\n**Key endpoints:**\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| `/api/v1/contracts/{contractId}/step` | POST | Execute a step |\n| `/api/v1/contracts/{contractId}/steps/{stepId}/output` | GET | Get step output |\n| `/api/v1/contracts/{contractId}/decision` | GET | Get decision point |\n| `/run/{runId}/decision` | POST | Submit decision |\n| `/run/{runId}/status` | GET | Get run status |\n\n资料来源：[src/transports/remote_api.ts:80-150]()\n\n## Error Handling\n\nAll tools return structured error responses using `flatErr()`:\n\n```typescript\nfunction flatErr(\n    code: string,\n    message: string,\n    context?: Record<string, unknown>,\n    retryable?: boolean,\n    requestId?: string\n): FlatRunnerResult\n```\n\n**Error Codes:**\n\n| Code | Description |\n|------|-------------|\n| `UNKNOWN_CONTRACT_TYPE` | Contract type not found in manifests |\n| `API_REQUEST_FAILED` | Backend API request failed |\n| `STEP_MODE_FIELD_MISMATCH` | Step execution mode doesn't match required fields |\n| `LOCAL_VALIDATION_FAILED` | Local input validation failed |\n\n资料来源：[src/index.ts:500-560]()\n\n## Configuration\n\n### Required Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_KEY` | MOVA API authentication key | Required |\n| `LLM_KEY` | OpenRouter API key for LLM steps | Required |\n| `LLM_MODEL` | OpenRouter model ID | `openai/gpt-4o-mini` |\n| `MOVA_API_URL` | Override API base URL | `https://api.mova-lab.eu` |\n\n### Optional Local HTTP Mode Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_API_TIMEOUT_MS` | API request timeout | `30000` |\n| `MOVA_HTTP_PORT` | Local HTTP server port | `3796` |\n| `MOVA_INVOKE_TOKEN` | Local invoke authentication | Required for HTTP mode |\n\n资料来源：[server.json:1-50]()\n\n## Resource Schema\n\nThe MCP server exposes resources via `mova://` URI scheme:\n\n| URI | Description |\n|-----|-------------|\n| `mova://registry` | Lists all available contract manifests |\n| `mova://schemas/envelopes` | Envelope schema definitions |\n| `mova://contracts/{type}/manifest` | Individual contract manifest |\n\n资料来源：[src/schemas.ts:1-50]()\n\n## Security Considerations\n\n### Step Mode Validation\n\nThe `step_mode_guard.ts` enforces strict validation on step execution modes:\n\n- Prevents `AI_ATOMIC` steps without a defined model\n- Prevents `DETERMINISTIC` steps from declaring a model\n- Prevents `HUMAN_GATE` steps without decision options\n- Prevents `CONTRACT_CALL` steps without a contract_id\n\n### Human Gate Protection\n\nThe `assertNotHumanGate()` guard prevents generic step completion from bypassing human approval requirements:\n\n```typescript\n// SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion.\n// Human confirmation requires the dedicated gate path (gate_approve / gate_reject).\n```\n\n### Output Sanitization\n\nThe `sanitizePublicShape()` function filters internal bridge metadata from public responses, excluding fields like `bridge_anchors`, `last_terminal_bridge`, `trace`, `outputs`, and `context`.\n\n资料来源：[src/transports/local_seam_bridge.ts:60-90]()\n\n## Quick Reference\n\n### Execute Built-in Contract\n```\ntool: mova_run\nargs: { contract_type: \"invoice_ocr\", inputs: { document: \"...\" } }\n```\n\n### Register and Run Custom Contract\n```\ntool: mova_contract\nargs: { action: \"register\", contract_def: {...} }\n\ntool: mova_contract\nargs: { action: \"run\", contract_id: \"custom-123\", inputs: {...} }\n```\n\n### Query Contract Status\n```\ntool: mova_query\nargs: { contract_id: \"ctr-abc\", view: \"status\" }\n```\n\n### Handle Human Approval\n```\ntool: mova_decide\nargs: { run_id: \"run-xyz\", option_id: \"approve\" }\n\n---\n\n<a id='page-installation-setup'></a>\n\n## Installation and Setup\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation page:\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [smithery.yaml](https://github.com/mova-compact/mova-flat-runner/blob/main/smithery.yaml)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n</details>\n\n# Installation and Setup\n\n## Overview\n\nThe **mova-flat-runner** is an MCP (Model Context Protocol) server that provides governed AI workflow execution with human approval gates and audit trails. It enables clients like Claude Desktop, Cursor, and Codex to interact with MOVA's contract execution engine for invoice OCR, AML triage, credit review, supplier screening, and custom contract workflows.\n\n资料来源：[README.md:1-20]()\n\n## Package Information\n\n| Property | Value |\n|----------|-------|\n| npm Package | `@leryk1981/mova-flat-runner` |\n| Package Version | `3.3.4` |\n| MCP Server Name | `io.github.mova-compact/mova-flat-runner` |\n| Server Registry Version | `2.0.6` |\n| Binary | `mova-mcp` |\n| License | `MIT-0` |\n| Runtime | Node.js (ES Module) |\n\n资料来源：[package.json:2-12](), [server.json:2-8]()\n\n## Prerequisites\n\n### System Requirements\n\n- **Node.js**: Required for running the MCP server\n- **npm** or **npx**: For package installation and execution\n- Network access to `api.mova-lab.eu` (or custom MOVA API endpoint)\n\n### Required API Keys\n\nBefore setup, obtain the following credentials:\n\n| Environment Variable | Required | Description |\n|---------------------|----------|-------------|\n| `MOVA_API_KEY` | Yes | MOVA API key for authentication. Use `test-key-001` for initial testing without registration. |\n| `LLM_KEY` | Yes | OpenRouter API key (`sk-or-v1-...`) for LLM analysis steps |\n| `LLM_MODEL` | No | OpenRouter model ID (default: `openai/gpt-4o-mini`) |\n\n资料来源：[smithery.yaml:35-45](), [server.json:15-28](), [README.md:35-42]()\n\n## Installation Methods\n\n### Method 1: Direct npx Execution\n\nThe simplest installation method uses npx to run the package directly without global installation:\n\n```bash\nnpx -y @leryk1981/mova-flat-runner@3.3.3\n```\n\nThis downloads and executes the specified version on-demand.\n\n资料来源：[README.md:19-20]()\n\n### Method 2: Global npm Installation\n\nInstall the package globally for persistent access:\n\n```bash\nnpm install -g @leryk1981/mova-flat-runner\n```\n\nAfter installation, the `mova-mcp` command becomes available system-wide.\n\n资料来源：[package.json:13-14]()\n\n### Method 3: Building from Source\n\nFor development or custom modifications:\n\n```bash\n# Clone the repository\ngit clone https://github.com/mova-compact/mova-flat-runner.git\ncd mova-flat-runner\n\n# Install dependencies\nnpm install\n\n# Build the TypeScript source\nnpm run build\n```\n\nThe build process compiles TypeScript and adds the shebang header to the output binary:\n\n```bash\n#!/usr/bin/env node\n```\n\n资料来源：[package.json:16-21]()\n\n## Client Configuration\n\n### Claude Desktop Configuration\n\nAdd the MOVA MCP server to your Claude Desktop configuration file:\n\n**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n\n**Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n资料来源：[README.md:57-70]()\n\n### Codex Configuration\n\nFor Codex (Cursor) integration, add to your configuration:\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:81-93]()\n\n## Environment Variables Reference\n\n### Core Configuration\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_API_URL` | No | `https://api.mova-lab.eu` | Base URL for MOVA API |\n| `MOVA_API_KEY` | Yes | — | API authentication key |\n| `LLM_KEY` | Yes | — | OpenRouter API key |\n| `LLM_MODEL` | No | `openai/gpt-4o-mini` | LLM model identifier |\n\n资料来源：[README.md:35-48](), [server.json:19-32]()\n\n### Local HTTP Mode (Optional)\n\nFor local execution mode without external API calls:\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout in milliseconds |\n| `MOVA_HTTP_PORT` | No | `3796` | Local HTTP server port |\n| `MOVA_INVOKE_TOKEN` | Conditional | — | Security token for local invocation |\n\n资料来源：[README.md:44-48]()\n\n### Local Seam Sandbox (Advanced)\n\nFor local seam bridge execution:\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | No | (project-specific) | Path to sandbox package |\n| `MOVA_SANDBOX_PROJECT_PATH` | No | — | Path to project directory |\n| `MOVA_SANDBOX_STATE_FILE` | No | (temp file) | Path to state file |\n\n资料来源：[src/transports/local_seam_bridge.ts:1-20]()\n\n## Health Check\n\nVerify the MOVA API connectivity before running workflows:\n\n```bash\ncurl -sS https://api.mova-lab.eu/health\n```\n\n资料来源：[README.md:52-53]()\n\n## Available MCP Tools\n\nOnce installed, the following tools are available:\n\n| Tool | Description |\n|------|-------------|\n| `mova_health` | Check API connectivity |\n| `mova_registry` | List available contract types |\n| `mova_run` | Execute built-in contract workflows |\n| `mova_query` | Query contract status, audit, or audit_compact |\n| `mova_decide` | Submit human decisions at approval gates |\n| `mova_connector` | Connect external data sources |\n| `mova_contract` | Register and run custom contracts |\n\n资料来源：[README.md:54-55]()\n\n## Build and Test Commands\n\nFor development, the following commands are available:\n\n```bash\n# Run lint, unit tests, and integration tests\nmake check\n\n# View all available make targets\nmake help\n\n# Build the publisher CLI\nmake publisher\n\n# Run smoke tests\nnpm run smoke:custom-bridge\n```\n\n资料来源：[README.md:22-29]()\n\n## Security Notes\n\n> **Important**: Never commit real API keys to version control.\n\n- Replace placeholders (`__SET_MOVA_API_KEY__`, `__SET_LLM_KEY__`, `__SET_MOVA_INVOKE_TOKEN__`) with actual credentials only in local configuration files\n- The MCP registry provides server listings but does not transmit secrets\n- Local invocation tokens should be used for secure local HTTP mode\n\n资料来源：[README.md:49-51](), [README.md:56-57]()\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    A[Claude Desktop / Codex] -->|MCP Protocol| B[mova-mcp Server]\n    B --> C{Execution Mode}\n    C -->|Remote API| D[MOVA API]\n    C -->|Local HTTP| E[Local Seam Bridge]\n    D --> F[Contract Execution Engine]\n    E --> G[Local Sandbox]\n    F --> H[(PostgreSQL)]\n    G --> H\n    D --> I[OpenRouter LLM]\n    E --> I\n```\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| `404 contract not found` | Use `mova_contract` with `action=run` for custom contracts instead of `mova_run` |\n| LLM analysis fails | Verify `LLM_KEY` is set to a valid OpenRouter key |\n| Connection timeout | Increase `MOVA_API_TIMEOUT_MS` or check network connectivity |\n| Human gate not advancing | Use `mova_decide` tool to submit decisions at approval gates |\n\n资料来源：[tasks/task061.md:1-30](), [src/index.ts:150-180]()\n\n## Next Steps\n\nAfter installation:\n\n1. Verify connectivity with `mova_health`\n2. Explore available contracts using `mova_registry`\n3. Run a built-in contract: `mova_run complaint`\n4. Create custom contracts with `mova_contract register`\n\n---\n\n<a id='page-architecture'></a>\n\n## System Architecture\n\n### 相关页面\n\n相关主题：[Project Overview](#page-project-overview), [Security Guards](#page-security-guards), [Transport Layer](#page-transport-layer)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n</details>\n\n# System Architecture\n\n## Overview\n\nThe **mova-flat-runner** is a Model Context Protocol (MCP) server that provides governed AI workflow execution with human approval gates and audit trails. It acts as an intermediary layer between MCP clients (such as Claude Desktop, Codex, or other compatible tools) and the MOVA backend API.\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\nThe architecture follows a transport-agnostic design that supports both local seam execution and remote API integration, enabling flexible deployment scenarios from local development to production environments.\n\n## High-Level Architecture\n\n```mermaid\ngraph TD\n    subgraph \"MCP Client Layer\"\n        A[Claude Desktop] --> B[MCP Protocol]\n        C[Codex] --> B\n        D[Other MCP Clients] --> B\n    end\n\n    subgraph \"mova-flat-runner\"\n        E[MCP Server Entry Point<br/>dist/index.js] --> F[Tool Executor<br/>executeTool]\n        F --> G[Built-in Contracts<br/>CONTRACT_MANIFESTS]\n        F --> H[Custom Contract Bridge<br/>CUSTOM_RUN_BRIDGE]\n        F --> I[Security Layer<br/>step_mode_guard]\n    end\n\n    subgraph \"Transport Layer\"\n        J[Local Seam Bridge<br/>local_seam_bridge.ts] \n        K[Remote API Transport<br/>remote_api.ts]\n    end\n\n    subgraph \"External Services\"\n        L[MOVA API<br/>api.mova-lab.eu]\n        M[OpenRouter LLM<br/>gpt-4o-mini]\n    end\n\n    E --> J\n    E --> K\n    J --> M\n    K --> L\n    L --> M\n```\n\n## Core Components\n\n### MCP Server Entry Point\n\nThe MCP server is implemented as a stdio-based transport server that conforms to the Model Context Protocol specification. The server binary is located at `dist/index.js` and is invoked via the `mova-mcp` command.\n\n资料来源：[package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n\n### Tool Executor (`executeTool`)\n\nThe central dispatch mechanism routes incoming tool requests to appropriate handlers based on the tool name. The executor supports the following tool categories:\n\n| Tool Category | Tools | Purpose |\n|--------------|-------|---------|\n| Workflow Execution | `mova_run`, `mova_contract` | Launch contract execution |\n| Query & Status | `mova_query`, `run_status` | Retrieve status and audit |\n| Human Gates | `gate_approve`, `gate_reject` | Human decision handling |\n| System | `mova_health`, `mova_registry` | Health checks and registry |\n\n资料来源：[src/index.ts:168-450](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\nThe executor follows a request-response pattern:\n\n```typescript\nasync function executeTool(name: string, args: Args): Promise<string> {\n  const requestId = shortId();\n  switch (name) {\n    case \"mova_run\": {\n      const contractType = args.contract_type as string;\n      const manifest = CONTRACT_MANIFESTS[contractType];\n      // ... dispatch logic\n    }\n    // ... other cases\n  }\n}\n```\n\n### Contract Manifests (`CONTRACT_MANIFESTS`)\n\nBuilt-in contracts are registered as manifests containing metadata such as:\n\n- `contract_type`: Unique identifier\n- `version`: Contract version\n- `execution_mode`: Runtime behavior (AI_ATOMIC, DETERMINISTIC, HUMAN_GATE, CONTRACT_CALL)\n- `dataspec`: Input field definitions\n- `decision_options`: Available choices for HUMAN_GATE steps\n\n资料来源：[src/index.ts:450-550](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Transport Layer Architecture\n\n### Remote API Transport\n\nThe remote transport handles communication with the MOVA backend API at `https://api.mova-lab.eu`. It provides HTTP methods for all contract operations.\n\n```typescript\nexport const movaGet  = (config, path) => movaRequest(config, \"GET\", path);\nexport const movaPost = (config, path, body) => movaRequest(config, \"POST\", path, body);\nexport const movaPut  = (config, path, body) => movaRequest(config, \"PUT\", path, body);\nexport const movaDelete = (config, path) => movaRequest(config, \"DELETE\", path);\n```\n\n资料来源：[src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\nThe transport layer performs step execution through a sequential pipeline:\n\n```mermaid\ngraph LR\n    A[Start Contract] --> B[analyze step]\n    B --> C[verify step]\n    C --> D[decide step]\n    D --> E[Execute Validators]\n    E --> F[Return Result]\n```\n\n### Local Seam Bridge\n\nThe local seam bridge enables execution of contracts in a local sandbox environment without requiring remote API connectivity. It constructs a canonical bridge response format.\n\nKey features include:\n- Local project path resolution from environment variables\n- State file management for persistent execution state\n- Sanitization of public shape to filter sensitive fields\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  const excludedKeys = [\"bridge_anchors\", \"last_terminal_bridge\", \n    \"terminal_commit_count\", \"_state15_bridge\", \"trace\", \"outputs\", \"context\"];\n  // ... sanitization logic\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:80-95](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Security Architecture\n\n### Step Mode Guard (`step_mode_guard.ts`)\n\nThe security layer validates that step execution modes are consistent with their declared content fields. This prevents misconfiguration that could lead to security issues.\n\n| Execution Mode | Required Field | Violation If Missing |\n|---------------|----------------|----------------------|\n| `AI_ATOMIC` | `model` | LLM step without model configuration |\n| `DETERMINISTIC` | - (no model allowed) | Model field present in deterministic step |\n| `CONTRACT_CALL` | `contract_id` | Call to undefined contract |\n| `HUMAN_GATE` | `decision_options` | Gate without user choices |\n\n资料来源：[src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n\nThe validation function `assertStepModesValid` returns a structured error when violations are detected:\n\n```typescript\nexport function assertStepModesValid(flow: unknown, requestId: string): FlatRunnerResult | null {\n  const violations = findStepModeViolations(flow);\n  if (violations.length === 0) return null;\n  return flatErr(ERR.STEP_MODE_FIELD_MISMATCH, message, { violations, http_status_equivalent: 400 });\n}\n```\n\n### Human Gate Protection\n\nThe `step_complete` tool includes a guard that prevents completion of HUMAN_GATE steps through the generic completion path, enforcing the dedicated gate approval/rejection flow.\n\n资料来源：[src/index.ts:220-235](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Custom Contract Bridge\n\nA specialized bridge mechanism handles custom contract execution when the contract ID may not exist in the standard query namespace. This resolves the \"custom contract audit identity gap.\"\n\n```mermaid\ngraph TD\n    A[mova_contract register] --> B[POST /api/v1/contracts/register]\n    B --> C[mova_contract run]\n    C --> D[POST /run/{contract_id}]\n    D --> E[rememberCustomRun<br/>Map<contractId, runRef>]\n    E --> F[run_status]\n    F --> G[GET /run/{run_id}/status]\n    G --> H[CUSTOM_RUN_BRIDGE<br/>In-Memory Map]\n    H --> I[mova_query on 404]\n    I --> J{Contract in Bridge?}\n    J -->|Yes| K[Return bridged status]\n    J -->|No| L[Return 404]\n```\n\nThe bridge uses an in-memory `CUSTOM_RUN_BRIDGE` Map to track the relationship between custom contract IDs and their corresponding run IDs.\n\n资料来源：[src/index.ts:100-140](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Default | Purpose |\n|----------|----------|---------|---------|\n| `MOVA_API_URL` | Yes | `https://api.mova-lab.eu` | Backend API endpoint |\n| `MOVA_API_KEY` | Yes | - | Authentication key |\n| `LLM_KEY` | Yes | - | OpenRouter API key |\n| `LLM_MODEL` | No | `openai/gpt-4o-mini` | LLM model identifier |\n| `MOVA_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout |\n| `MOVA_HTTP_PORT` | No | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | No | - | Local invoke authentication |\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\n### Configuration Object (`MovaConfig`)\n\nThe runtime configuration aggregates environment variables and validates required fields:\n\n```typescript\ninterface MovaConfig {\n  apiUrl: string;\n  apiKey: string;\n  llmKey: string;\n  llmModel: string;\n  invokeToken?: string;\n}\n```\n\n## Data Flow\n\n### Contract Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client as MCP Client\n    participant Server as mova-flat-runner\n    participant API as MOVA API\n    participant LLM as OpenRouter\n\n    Client->>Server: mova_run(contract_type, inputs)\n    Server->>API: POST /run/{contract_id}\n    API->>LLM: Analysis request\n    LLM-->>API: Analysis result\n    API-->>Server: Step result\n    alt AI_ATOMIC step\n        Server->>API: GET /steps/{step_id}/output\n        API-->>Server: Validated output\n    end\n    alt HUMAN_GATE step\n        Server-->>Client: waiting_human status\n        Client->>Server: gate_approve/gate_reject\n        Server->>API: POST /decision\n    end\n    Server-->>Client: Final result\n```\n\n### Local Seam Execution Flow\n\nFor local execution without remote API:\n\n1. Resolve `package_path` and `project_path` from inputs or environment\n2. Execute steps in the local sandbox environment\n3. Apply output sanitization to remove internal fields\n4. Construct canonical bridge response with verification payload\n\n资料来源：[src/transports/local_seam_bridge.ts:95-150](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Package Support and Validation\n\nThe `package_support.ts` module handles contract package validation including:\n\n- Global file structure validation\n- Semantic roles verification\n- Non-authority rules checking\n- Schema path validation\n\n资料来源：[src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n\n## Build and Deployment\n\nThe project uses TypeScript with a custom build script that:\n1. Compiles TypeScript to JavaScript\n2. Injects a shebang for Unix execution\n3. Sets executable permissions on the output binary\n\n```bash\nnpm run build\n```\n\nThe server is published as an npm package `@leryk1981/mova-flat-runner` version `3.3.4` and can be invoked via `npx mova-mcp`.\n\n资料来源：[package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n\n---\n\n<a id='page-security-guards'></a>\n\n## Security Guards\n\n### 相关页面\n\n相关主题：[System Architecture](#page-architecture), [Domain Validators](#page-validators)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/security/class_definition_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/class_definition_guard.ts)\n- [src/security/determinism_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/determinism_guard.ts)\n- [src/security/flow_schema_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/flow_schema_guard.ts)\n- [src/security/gate_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/gate_guard.ts)\n- [src/security/graph_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/graph_guard.ts)\n- [src/security/step_mode_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/step_mode_guard.ts)\n- [src/security/system_contract_guard.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/security/system_contract_guard.ts)\n</details>\n\n# Security Guards\n\n## Overview\n\nSecurity Guards are a defensive layer in the mova-flat-runner that enforce strict validation rules on MOVA flows before they enter execution. They operate on the principle of **deny-by-default**: any flow containing unknown or potentially dangerous fields is rejected at registration time, preventing malicious or malformed data from persisting into runtime state.\n\nThe guard system addresses specific vulnerability categories identified through security audits (CFV-9, CFV-10, and others), ensuring that privilege-elevation hints, inline class definitions, and execution mode mismatches cannot be smuggled into the system. 资料来源：[src/security/flow_schema_guard.ts:1-15]()\n\n```mermaid\ngraph TD\n    A[Flow Registration] --> B[Security Guards]\n    B --> C{flow_schema_guard<br/>CFV-9}\n    B --> D{class_definition_guard<br/>CFV-10}\n    B --> E{step_mode_guard}\n    B --> F{gate_guard}\n    B --> G{graph_guard}\n    B --> H{determinism_guard}\n    B --> I{system_contract_guard}\n    C --> J{All Guards Pass?}\n    D --> J\n    E --> J\n    F --> J\n    G --> J\n    H --> J\n    I --> J\n    J -->|Yes| K[Flow Accepted]\n    J -->|No| L[Rejection with<br/>FlatRunnerResult]\n```\n\n## Guard Architecture\n\n### Core Principles\n\n| Principle | Description |\n|-----------|-------------|\n| **Strict-by-default** | Any unknown field causes rejection |\n| **Side-effect free at import** | Guards can be imported without triggering validation |\n| **Compositable** | Multiple guards run in sequence, each checking a specific concern |\n| **Audit trail** | Rejections return structured error payloads with remediation hints |\n\n### Guard Registry\n\nEach guard exports two key functions:\n\n1. **Finder function** — Scans the flow and returns a list of violations (returns `string[]` or violation objects)\n2. **Assert function** — Calls the finder, and if violations exist, returns a `FlatRunnerResult` error; otherwise returns `null`\n\n```typescript\n// Standard guard interface pattern\nexport function findXXXViolations(flow: unknown): Violation[] // Finder\nexport function assertXXXValid(flow: unknown, requestId: string): FlatRunnerResult | null // Assert\n```\n\n## Flow Schema Guard (CFV-9)\n\n**File:** `src/security/flow_schema_guard.ts`\n\n### Purpose\n\nThe flow schema guard enforces a strict allow-list of top-level keys in MOVA flow definitions. During a security audit, flows containing `__admin_override`, `__privilege_grant`, and `__debug_mode` were accepted at registration. If these fields were persisted—even silently—an attacker could smuggle privilege-elevation hints into the runtime for future code paths to read. 资料来源：[src/security/flow_schema_guard.ts:1-20]()\n\n### Allowed Top-Level Keys\n\n| Key | Purpose |\n|-----|---------|\n| `version` | Flow schema version |\n| `description` | Human-readable description |\n| `entry` | Entry point step reference |\n| `steps` | Step definitions map |\n| `parallel_steps` | Parallel step definitions |\n| `notes` | Developer notes |\n| `audit_mode` | Audit configuration |\n| `audit_mode_note` | Audit mode explanation |\n| `class_definition_ref` | Reference to registry class |\n| `CONTRACT_CALL_instructions` | Contract invocation instructions |\n| `input_schema` | Input validation schema |\n| `output_schema` | Output validation schema |\n| `metadata` | Additional metadata |\n\n### Implementation\n\n```typescript\nexport const ALLOWED_FLOW_TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n    \"version\",\n    \"description\",\n    \"entry\",\n    \"steps\",\n    \"parallel_steps\",\n    \"notes\",\n    \"audit_mode\",\n    \"audit_mode_note\",\n    \"class_definition_ref\",\n    \"CONTRACT_CALL_instructions\",\n    \"input_schema\",\n    \"output_schema\",\n    \"metadata\",\n]);\n\nexport function findUnknownFlowFields(flow: unknown): string[] {\n    if (!flow || typeof flow !== \"object\" || Array.isArray(flow)) return [];\n    const f = flow as Record<string, unknown>;\n    const out: string[] = [];\n    for (const key of Object.keys(f)) {\n        if (!ALLOWED_FLOW_TOP_LEVEL_KEYS.has(key))\n            out.push(key);\n    }\n    return out;\n}\n```\n\n### Rejection Response\n\nWhen unknown fields are detected:\n\n```json\n{\n    \"ok\": false,\n    \"code\": \"FLOW_SCHEMA_VIOLATION\",\n    \"message\": \"Flow body contains unknown top-level key(s): __admin_override, __debug_mode\",\n    \"details\": {\n        \"unknown_fields\": [\"__admin_override\", \"__debug_mode\"],\n        \"http_status_equivalent\": 400\n    }\n}\n```\n\n## Class Definition Guard (CFV-10)\n\n**File:** `src/security/class_definition_guard.ts`\n\n### Purpose\n\nThe class definition guard prevents inline class definitions within flow bodies. Class definitions define severity bands and noise control parameters that must be resolved from the registry by `class_id`. Embedding them inline creates a vector for policy tampering and bypasses the centralized authority on these security-sensitive values. 资料来源：[src/security/class_definition_guard.ts:1-35]()\n\n### Forbidden Keys\n\n```typescript\nconst FORBIDDEN_FLOW_KEYS: readonly string[] = Object.freeze([\n    \"class_definition\",\n    \"class_definition_ref\",\n    \"class_definition_inline\",\n    \"class_def_override\",\n    \"class_def\",\n]);\n```\n\n### Implementation\n\n```typescript\nexport function findInlineClassDefinitionFields(flow: unknown): string[] {\n    if (!flow || typeof flow !== \"object\") return [];\n    const f = flow as Record<string, unknown>;\n    return FORBIDDEN_FLOW_KEYS.filter((k) => Object.prototype.hasOwnProperty.call(f, k));\n}\n\nexport function assertNoInlineClassDefinition(\n    flow: unknown,\n    requestId: string,\n): FlatRunnerResult | null {\n    const found = findInlineClassDefinitionFields(flow);\n    if (found.length === 0) return null;\n    return flatErr(\n        ERR.INLINE_CLASS_DEFINITION_FORBIDDEN,\n        `Flow body contains inline class-definition field(s): ${found.join(\", \")}. ` +\n        \"Class definitions must be resolved from the registry by class_id.\",\n        {\n            forbidden_fields: found,\n            remediation: \"Remove these fields and reference the class via class_id\",\n            http_status_equivalent: 400,\n        },\n        false,\n        requestId,\n    );\n}\n```\n\n### Defense in Depth\n\nThe flow schema guard (CFV-9) catches any `class_definition*` keys not yet covered by this stricter rule, providing layered protection:\n\n> CFV-10's `class_definition*` keys are blocked specifically by `class_definition_guard.ts`; this guard catches everything else not yet covered by a stricter rule. 资料来源：[src/security/flow_schema_guard.ts:17-20]()\n\n## Step Mode Guard\n\n**File:** `src/security/step_mode_guard.ts`\n\n### Purpose\n\nThe step mode guard validates that each step's `execution_mode` agrees with the fields it contains. MOVA supports multiple execution modes, and each mode has specific field requirements. Mismatches can indicate configuration errors or attempts to bypass intended behavior.\n\n### Execution Mode Requirements\n\n| Mode | Required Field | Forbidden Field |\n|------|---------------|-----------------|\n| `DETERMINISTIC` | — | `model` |\n| `AI_ATOMIC` | `model` | — |\n| `CONTRACT_CALL` | `contract_id` | — |\n| `HUMAN_GATE` | `decision_options` array | — |\n\n### Violation Types\n\n```typescript\ninterface StepModeViolation {\n    kind: string;\n    step_id: string | undefined;\n    execution_mode: string;\n    message: string;\n}\n```\n\n1. **deterministic_with_model** — DETERMINISTIC steps run local JS checks, not LLMs\n2. **ai_atomic_without_model** — AI_ATOMIC requires a model field\n3. **contract_call_without_contract_id** — CONTRACT_CALL requires contract_id\n4. **human_gate_without_decisions** — HUMAN_GATE requires decision_options array\n\n### Implementation\n\n```typescript\nexport function findStepModeViolations(flow: unknown): StepModeViolation[] {\n    const f = flow as Flow;\n    if (!f?.steps) return [];\n    const out: StepModeViolation[] = [];\n\n    for (const [id, step] of Object.entries(f.steps)) {\n        const mode = step.execution_mode ?? \"DETERMINISTIC\";\n\n        if (mode === \"DETERMINISTIC\" && step.model !== undefined) {\n            out.push({\n                kind: \"deterministic_with_model\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is DETERMINISTIC but declares a 'model' field`,\n            });\n        }\n\n        if (mode === \"AI_ATOMIC\" && asStr(step.model) === null) {\n            out.push({\n                kind: \"ai_atomic_without_model\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is AI_ATOMIC but has no 'model' field`,\n            });\n        }\n\n        if (mode === \"CONTRACT_CALL\" && asStr(step.contract_id) === null) {\n            out.push({\n                kind: \"contract_call_without_contract_id\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is CONTRACT_CALL but has no 'contract_id'`,\n            });\n        }\n\n        if (mode === \"HUMAN_GATE\" && !Array.isArray(step.decision_options)) {\n            out.push({\n                kind: \"human_gate_without_decisions\",\n                step_id: id,\n                execution_mode: mode,\n                message: `step '${id}' is HUMAN_GATE but has no 'decision_options' array`,\n            });\n        }\n    }\n    return out;\n}\n```\n\n## Additional Guards\n\n### Gate Guard\n\n**File:** `src/security/gate_guard.ts`\n\nThe gate guard enforces human gate access control, ensuring that human confirmation requires the dedicated gate path. It prevents generic step completion from bypassing human authorization requirements.\n\n### Determinism Guard\n\n**File:** `src/security/determinism_guard.ts`\n\nThe determinism guard ensures deterministic steps produce consistent results and cannot introduce non-deterministic behavior that could compromise reproducibility.\n\n### Graph Guard\n\n**File:** `src/security/graph_guard.ts`\n\nThe graph guard validates the structural integrity of the flow graph, ensuring all step references and dependencies are properly defined and no cycles or invalid references exist.\n\n### System Contract Guard\n\n**File:** `src/security/system_contract_guard.ts`\n\nThe system contract guard monitors system contract usage, preventing unauthorized access to privileged operations.\n\n## Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant MCP as MCP Server\n    participant Guards as Security Guards\n    participant API as MOVA API\n\n    Client->>MCP: mova_contract register(flow)\n    MCP->>Guards: validate(flow)\n    Guards->>Guards: flow_schema_guard\n    Guards->>Guards: class_definition_guard\n    Guards->>Guards: step_mode_guard\n    Guards->>Guards: gate_guard\n    Guards->>Guards: graph_guard\n    Guards->>Guards: determinism_guard\n    Guards->>Guards: system_contract_guard\n    \n    alt All Guards Pass\n        Guards-->>MCP: null (valid)\n        MCP->>API: POST /api/v1/contracts/register\n        API-->>MCP: registration response\n        MCP-->>Client: success\n    else Guard Violation\n        Guards-->>MCP: FlatRunnerResult (error)\n        MCP-->>Client: rejection with details\n    end\n```\n\n## Error Codes\n\n| Code | Guard | Description |\n|------|-------|-------------|\n| `FLOW_SCHEMA_VIOLATION` | flow_schema_guard | Unknown top-level keys |\n| `INLINE_CLASS_DEFINITION_FORBIDDEN` | class_definition_guard | Inline class definition present |\n| `STEP_MODE_FIELD_MISMATCH` | step_mode_guard | Execution mode doesn't match fields |\n| `GATE_ACCESS_DENIED` | gate_guard | Unauthorized gate access attempt |\n| `DETERMINISM_VIOLATION` | determinism_guard | Non-deterministic behavior detected |\n| `GRAPH_STRUCTURE_INVALID` | graph_guard | Invalid flow graph structure |\n| `SYSTEM_CONTRACT_VIOLATION` | system_contract_guard | Unauthorized system contract use |\n\n## Integration Points\n\n### Local Seam Bridge\n\nThe local seam bridge integrates security guards into the transport layer:\n\n> SECURITY (CFV-3): HUMAN_GATE cannot be completed by generic step completion. Human confirmation requires the dedicated gate path (gate_approve / gate_reject). Guard runs BEFORE forwarding so run state is not advanced on rejection. 资料来源：[src/index.ts:1-25]()\n\n### Custom Contract Bridge\n\nSecurity considerations are applied when bridging custom contract runs to ensure audit integrity:\n\n> Safety: Built-in path untouched. No fake audit records introduced. Bridge only activates on 404 in `mova_query`. 资料来源：[tasks/task061.md:1-40]()\n\n## Testing\n\nSecurity guards are validated through:\n\n```bash\n# Run all security checks\nmake check\n\n# Smoke test for custom contract bridge\nnpm run smoke:custom-bridge\n\n# Build validation\nnpm run build\nnpm run test:build\n```\n\n## Best Practices\n\n1. **Never disable guards** — Guards exist to prevent exploitation\n2. **Keep allow-lists updated** — Review `ALLOWED_FLOW_TOP_LEVEL_KEYS` when adding new features\n3. **Report unknown fields** — Fields that legitimately need to pass through should be explicitly allow-listed\n4. **Maintain separation** — Built-in and custom contract paths should have distinct security requirements\n5. **Audit on change** — Any schema change should trigger a security review\n\n---\n\n<a id='page-transport-layer'></a>\n\n## Transport Layer\n\n### 相关页面\n\n相关主题：[System Architecture](#page-architecture), [Core MCP Tools](#page-core-tools), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [src/transports/remote_api.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [dist-test/src/transports/local_seam_bridge.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/local_seam_bridge.js)\n- [dist-test/src/transports/remote_api.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n</details>\n\n# Transport Layer\n\nThe Transport Layer in mova-flat-runner provides the communication infrastructure for executing contract workflows across different execution environments. It abstracts the underlying HTTP communication with the MOVA backend API and provides a local seam bridge for sandboxed contract execution.\n\n## Overview\n\nThe transport layer handles two primary communication patterns:\n\n| Transport Mode | Purpose | Use Case |\n|----------------|---------|----------|\n| **Remote API** | HTTP-based communication with `api.mova-lab.eu` | Production deployments, remote contract execution |\n| **Local Seam Bridge** | In-process contract execution via local sandbox | Development, testing, isolated execution |\n\nThe layer is responsible for:\n- Managing HTTP requests to the MOVA backend\n- Routing contract step execution to appropriate handlers\n- Bridging between local execution context and remote API namespace\n- Sanitizing data shapes for public consumption\n- Handling execution modes (AI_ATOMIC, HUMAN_GATE, DETERMINISTIC, CONTRACT_CALL)\n\n资料来源：[src/transports/local_seam_bridge.ts:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n资料来源：[src/transports/remote_api.ts:1-30](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\n## Architecture\n\n```mermaid\ngraph TD\n    subgraph \"Client Layer\"\n        MCP[MCP Client]\n        CLI[CLI Tools]\n    end\n\n    subgraph \"Transport Layer\"\n        RemoteAPI[Remote API Transport]\n        LocalBridge[Local Seam Bridge]\n    end\n\n    subgraph \"Backend Services\"\n        MOVAAPI[MOVA API<br/>api.mova-lab.eu]\n        LocalSandbox[Local Sandbox]\n    end\n\n    MCP --> |HTTP| RemoteAPI\n    CLI --> |HTTP| RemoteAPI\n    \n    LocalBridge --> |Internal| LocalSandbox\n    RemoteAPI --> |HTTP| MOVAAPI\n\n    RemoteAPI -.-> |fallback| LocalBridge\n```\n\n## Remote API Transport\n\nThe Remote API transport provides HTTP-based communication with the MOVA backend service.\n\n### Core Functions\n\n| Function | Method | Purpose |\n|----------|--------|---------|\n| `movaRequest` | Core | Base HTTP request handler with error wrapping |\n| `movaGet` | GET | Retrieve data from API endpoints |\n| `movaPost` | POST | Submit data to create or trigger actions |\n| `movaPut` | PUT | Update existing resources |\n| `movaDelete` | DELETE | Remove resources |\n\n资料来源：[src/transports/remote_api.ts:50-80](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/remote_api.ts)\n\n### Request Configuration\n\nThe remote API uses a `MovaConfig` object for authentication and endpoint configuration:\n\n```typescript\ninterface MovaConfig {\n  baseUrl: string;       // API base URL (default: api.mova-lab.eu)\n  apiKey: string;        // API authentication key\n  timeout?: number;       // Request timeout in milliseconds\n  headers?: Record<string, string>;\n}\n```\n\n### API Endpoints\n\nThe transport layer integrates with the following MOVA API endpoints:\n\n| Endpoint Pattern | Method | Usage |\n|-----------------|--------|-------|\n| `/api/v1/contracts/{contractId}` | GET | Query contract metadata |\n| `/api/v1/contracts/{contractId}/step` | POST | Execute a contract step |\n| `/api/v1/contracts/{contractId}/steps/{stepId}/output` | GET | Retrieve step output |\n| `/api/v1/contracts/{contractId}/decision` | GET | Get human decision point |\n| `/api/v1/contracts/my` | GET | List user's contracts |\n| `/run/{runId}/status` | GET | Get run execution status |\n| `/run/{contractId}` | POST | Initiate a contract run |\n\n资料来源：[dist-test/src/transports/remote_api.js:1-60](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n\n## Local Seam Bridge\n\nThe Local Seam Bridge provides an internal bridge for sandboxed contract execution when the local seam backend is available.\n\n### Bridge Invoker\n\nThe `createInternalBridgeInvoker()` function creates a bridge invoker that handles step execution within the local environment:\n\n```typescript\nfunction createInternalBridgeInvoker() {\n  return async function bridgeInvoker(request) {\n    bridgeSequence += 1;\n    const suffix = `${request.step.id}:${bridgeSequence}`;\n    \n    const status =\n      request.step.execution_mode === \"HUMAN_GATE\" && request.humanDecision == null\n        ? \"human_gate_required\"\n        : request.terminalOutcome\n          ? \"completed\"\n          : \"advanced\";\n\n    return {\n      ok: true,\n      bridge: {\n        ok: true,\n        bridge_source: \"mova_flat_runner_canonical_bridge\",\n        status,\n        execution_mode: request.step.execution_mode,\n        next_phase: { phase: status === \"human_gate_required\" ? \"WAIT_HUMAN\" : \"EXECUTION\" },\n        // ... additional bridge fields\n      },\n    };\n  };\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:50-90](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n### Execution Modes\n\nThe bridge handles different execution modes defined by the contract:\n\n| Execution Mode | Behavior | Bridge Output |\n|----------------|----------|---------------|\n| `AI_ATOMIC` | LLM-powered atomic execution | Canonical strategy output with full validation metadata |\n| `HUMAN_GATE` | Requires human decision | Returns `human_gate_required` status, awaits confirmation |\n| `DETERMINISTIC` | Local JavaScript execution | Passes through step result |\n| `CONTRACT_CALL` | Calls another contract | Forwards to referenced contract |\n\n资料来源：[dist-test/src/security/step_mode_guard.js:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/security/step_mode_guard.js)\n\n### Status Handling\n\n```mermaid\ngraph TD\n    A[Step Execution Request] --> B{Execution Mode}\n    \n    B -->|AI_ATOMIC| C[Generate Canonical Output]\n    B -->|HUMAN_GATE| D{Human Decision?}\n    B -->|DETERMINISTIC| E[Pass Through Result]\n    B -->|CONTRACT_CALL| F[Forward to Contract]\n    \n    D -->|No| G[Status: human_gate_required<br/>Phase: WAIT_HUMAN]\n    D -->|Yes| H[Status: advanced<br/>Phase: EXECUTION]\n    \n    C --> I[Return Bridged Response]\n    E --> I\n    F --> I\n    G --> I\n    H --> I\n```\n\n## Data Sanitization\n\nThe transport layer includes a `sanitizePublicShape` function to filter sensitive or internal fields from response data:\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  if (Array.isArray(value)) {\n    return value.every((item) => sanitizePublicShape(item));\n  }\n  \n  const FORBIDDEN_KEYS = [\n    \"bridge_anchors\",\n    \"last_terminal_bridge\", \n    \"terminal_commit_count\",\n    \"_state15_bridge\",\n    \"trace\",\n    \"outputs\",\n    \"context\"\n  ];\n\n  for (const [key, child] of Object.entries(value)) {\n    if (FORBIDDEN_KEYS.includes(key)) {\n      return false;\n    }\n    if (!sanitizePublicShape(child)) {\n      return false;\n    }\n  }\n  return true;\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:120-145](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n\n## Package Locator Resolution\n\nThe Local Seam Bridge includes logic to resolve package references for contract execution:\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs) {\n  const packagePath = initialInputs.package_path \n    ?? process.env.MOVA_SANDBOX_PACKAGE_PATH \n    ?? \"D:\\\\Projects_MOVA\\\\mova-intent\\\\contracts\\\\dockerfile-nodejs-v1\";\n    \n  const projectPath = initialInputs.project_path \n    ?? process.env.MOVA_SANDBOX_PROJECT_PATH \n    ?? \"\";\n    \n  if (!projectPath) {\n    throw new Error(\"missing_local_seam_project_path\");\n  }\n  // ... additional resolution logic\n}\n```\n\n资料来源：[dist-test/src/transports/local_seam_bridge.js:80-100](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/local_seam_bridge.js)\n\n## Custom Contract Bridge\n\nFor custom contracts registered outside the standard `/api/v1/contracts` namespace, the transport layer provides a bridge mechanism:\n\n### Bridge Map\n\nThe system maintains an in-memory mapping of custom contracts:\n\n```typescript\nCUSTOM_RUN_BRIDGE: Map<contract_id, {\n  run_id: string,\n  updated_at: string,\n  source_url?: string\n}>\n```\n\n资料来源：[src/index.ts:1-50](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n\n### Custom Query Handling\n\nWhen a contract is not found in the standard namespace, the bridge checks:\n\n1. Local `CUSTOM_RUN_BRIDGE` map for run history\n2. `/api/v1/contracts/my` for contract metadata\n3. `/run/{runId}/status` for execution status\n\n```mermaid\ngraph LR\n    A[mova_query Request] --> B{API 404?}\n    \n    B -->|Yes| C[Check CUSTOM_RUN_BRIDGE]\n    B -->|No| Z[Normal Response]\n    \n    C --> D{Run Found?}\n    D -->|Yes| E[Return Bridged Status]\n    D -->|No| F[Query /contracts/my]\n    \n    F --> G{Record Found?}\n    G -->|Yes| H[Return with Contract Record]\n    G -->|No| I[Return Error]\n```\n\n## Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `MOVA_API_URL` | `https://api.mova-lab.eu` | MOVA API base URL |\n| `MOVA_API_KEY` | - | API authentication key |\n| `MOVA_API_TIMEOUT_MS` | `30000` | Request timeout in milliseconds |\n| `MOVA_HTTP_PORT` | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | - | Token for local HTTP invocation |\n| `MOVA_SANDBOX_PACKAGE_PATH` | - | Package path for local seam |\n| `MOVA_SANDBOX_PROJECT_PATH` | - | Project path for local seam |\n| `MOVA_SCHEMA_PATH` | - | Additional schema lookup path |\n\n资料来源：[README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n\n## Remote Step Execution Flow\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant RemoteAPI\n    participant MOVA as MOVA Backend\n    \n    Client->>RemoteAPI: movaRunStepsRemote(contractId)\n    \n    loop For each step: analyze, verify, decide\n        RemoteAPI->>MOVA: POST /api/v1/contracts/{id}/step\n        MOVA-->>RemoteAPI: Step result\n        \n        alt step === \"analyze\"\n            RemoteAPI->>MOVA: GET /steps/analyze/output\n            MOVA-->>RemoteAPI: Analysis output\n            Note over RemoteAPI: Apply validators\n        end\n        \n        alt status === \"waiting_human\"\n            RemoteAPI->>MOVA: GET /decision\n            MOVA-->>RemoteAPI: Decision point (question, options)\n            Note over RemoteAPI: Return for human input\n        end\n    end\n    \n    RemoteAPI-->>Client: Aggregated results\n```\n\n## Error Handling\n\nThe transport layer wraps errors with structured error codes:\n\n| Error Code | Description |\n|------------|-------------|\n| `API_REQUEST_FAILED` | HTTP request to backend failed |\n| `AUDIT_UNAVAILABLE` | Audit endpoint not accessible |\n| `CONTRACT_NOT_FOUND` | Contract ID not found in any namespace |\n| `LOCAL_VALIDATION_FAILED` | Local input validation failed |\n| `UNKNOWN_CONTRACT_TYPE` | Contract type not in manifest registry |\n\n资料来源：[dist-test/src/transports/remote_api.js:40-80](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/transports/remote_api.js)\n\n## Testing\n\nThe compiled test files verify transport behavior:\n\n- **dist-test/src/transports/remote_api.js** - Tests for HTTP transport functions\n- **dist-test/src/transports/local_seam_bridge.js** - Tests for local bridge execution\n- **dist-test/src/package_support.js** - Tests for package resolution\n\nTo run tests:\n```bash\nnpm run build\nnpm run test:build\nnpm run smoke:custom-bridge\n\n---\n\n<a id='page-validators'></a>\n\n## Domain Validators\n\n### 相关页面\n\n相关主题：[Data Schemas and Types](#page-data-schemas), [Security Guards](#page-security-guards)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation:\n\n- [src/validators/registry.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/registry.ts)\n- [src/validators/aml.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/aml.ts)\n- [src/validators/churn.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/churn.ts)\n- [src/validators/complaint.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/complaint.ts)\n- [src/validators/compliance.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/compliance.ts)\n- [src/validators/contract_gen.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/contract_gen.ts)\n- [src/validators/credit.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/credit.ts)\n- [src/validators/invoice.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/invoice.ts)\n- [src/validators/po.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/po.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/validators/trade.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/trade.ts)\n- [src/validators/content_flywheel.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/content_flywheel.ts)\n</details>\n\n# Domain Validators\n\nDomain Validators are the core validation layer in MOVA Flat Runner's contract execution engine. They provide domain-specific input validation for each workflow type, ensuring data integrity before contract execution proceeds through subsequent steps.\n\n## Overview\n\nDomain Validators serve as a security boundary and data validation checkpoint within the MOVA contract execution model. Every validator function must be registered in the central `VALIDATOR_REGISTRY` before it can be invoked during contract execution.\n\n资料来源：[src/validators/registry.ts:1-28]()\n\n```mermaid\ngraph TD\n    A[Contract Execution] --> B[ValidatorRef from Manifest]\n    B --> C{Registry Lookup}\n    C -->|Found| D[Execute ValidatorFn]\n    C -->|Not Found| E[VALIDATOR_NOT_ALLOWED Error]\n    D --> F[Return Validation Result]\n    E --> G[Log Error to Analysis]\n    F --> H[Proceed to Next Step]\n    G --> H\n```\n\n## Architecture\n\n### Validator Function Type\n\nAll domain validators conform to the `ValidatorFn` interface defined in the types module:\n\n```typescript\ntype ValidatorFn = (inputs: Record<string, unknown>) => {\n    ok: boolean;\n    value: Record<string, unknown>;\n    step_id: string;\n};\n```\n\n资料来源：[dist-test/src/types.d.ts:1-7]()\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `ok` | `boolean` | Indicates whether validation passed |\n| `value` | `Record<string, unknown>` | Validation results and derived fields |\n| `step_id` | `string` | Identifier of the step being validated |\n\n### Registry Structure\n\nThe registry is implemented as a `Map<string, ValidatorFn>` where keys are validator IDs in the format `{domain}.{validator_name}_v{version}`:\n\n```typescript\nexport const VALIDATOR_REGISTRY = new Map<string, ValidatorFn>(\n  all.map(v => [v.id, v.fn])\n);\n```\n\n资料来源：[src/validators/registry.ts:25-27]()\n\n## Registered Validator Domains\n\nThe validator registry aggregates validators from 10 domain-specific modules:\n\n| Domain | Module | Purpose |\n|--------|--------|---------|\n| Invoice | `invoice.ts` | Invoice OCR and extraction validation |\n| Purchase Order | `po.ts` | PO ID and approver validation |\n| Trade | `trade.ts` | Trade finance validation |\n| AML | `aml.ts` | Anti-money laundering screening |\n| Complaint | `complaint.ts` | Customer complaint processing |\n| Compliance | `compliance.ts` | Regulatory framework validation |\n| Credit | `credit.ts` | Credit review validation |\n| Supply Chain | `supply_chain.ts` | Supplier data validation |\n| Churn | `churn.ts` | Customer churn prediction |\n| Contract Gen | `contract_gen.ts` | Contract generation validation |\n\n资料来源：[src/validators/registry.ts:3-13]()\n\n## Validator Invocation Flow\n\nDuring contract execution, validators are invoked through the remote API transport layer when processing the `analyze` step:\n\n```typescript\nconst validatorContext = { ...initialInputs, ...analysis };\nfor (const validator of validators) {\n    const fn = VALIDATOR_REGISTRY.get(validator.validator_id);\n    if (!fn) {\n        analysis[`${validator.step_id}_error`] = `VALIDATOR_NOT_ALLOWED: \"${validator.validator_id}\" not in registry`;\n        continue;\n    }\n    try {\n        const resultValue = fn(validatorContext);\n        Object.assign(analysis, resultValue.value ?? {});\n    } catch (error) {\n        analysis[`${validator.step_id}_error`] = `VALIDATOR_FAILED: ${String(error)}`;\n    }\n}\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:1-20]()\n\n### Error Handling\n\n| Error Type | Constant | Description |\n|------------|----------|-------------|\n| Validator not in registry | `VALIDATOR_NOT_ALLOWED` | Attempted to call unregistered validator |\n| Validator execution failed | `VALIDATOR_FAILED` | Validator threw an exception |\n| Local validation failed | `LOCAL_VALIDATION_FAILED` | Client-side validation error |\n\n资料来源：[dist-test/src/types.d.ts:18-20]()\n\n## Example Validators\n\n### Supply Chain Validator\n\nValidates supplier array input with country code format checking:\n\n```typescript\n{\n  id: \"supply_chain.validate_inputs_v0\",\n  fn: (inputs) => {\n    const suppliers = Array.isArray(inputs.suppliers) \n      ? inputs.suppliers as Record<string, unknown>[] \n      : [];\n    const non_empty    = suppliers.length > 0;\n    const valid_items  = suppliers.filter(s =>\n      s &&\n      typeof s === \"object\" &&\n      String(s[\"id\"]      || \"\").length > 0 &&\n      String(s[\"name\"]    || \"\").length > 0 &&\n      /^[A-Z]{2}$/.test(String(s[\"country\"] || \"\"))\n    );\n    const invalid_count = suppliers.length - valid_items.length;\n    return {\n      ok: true,\n      value: {\n        inputs_valid:          non_empty && invalid_count === 0,\n        supplier_count:        suppliers.length,\n        valid_supplier_count:  valid_items.length,\n        invalid_supplier_count: invalid_count,\n        has_suppliers:         non_empty,\n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[src/validators/supply_chain.ts:1-35]()\n\n### Purchase Order Validator\n\nValidates PO ID and approver employee ID presence:\n\n```typescript\n{\n  id: \"po.validate_inputs_v0\",\n  fn: (inputs) => {\n    const po  = String(inputs.po_id                || \"\");\n    const emp = String(inputs.approver_employee_id || \"\");\n    const po_ok  = po.length  >= 3;\n    const emp_ok = emp.length >= 3;\n    return {\n      ok: true,\n      value: { \n        inputs_valid: po_ok && emp_ok, \n        po_id_present: po_ok, \n        approver_present: emp_ok \n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[src/validators/po.ts:1-20]()\n\n### Compliance Framework Validator\n\nValidates document URL protocol, framework type, and organization name:\n\n```typescript\nconst VALID_FRAMEWORKS = [\"gdpr\", \"pci_dss\", \"iso_27001\", \"soc2\"];\n\n{\n  id: \"compliance.validate_inputs_v0\",\n  fn: (inputs) => {\n    const url = String(inputs.document_url || \"\");\n    const fw = String(inputs.framework || \"\");\n    const url_ok = url.startsWith(\"https://\");\n    const fw_ok = VALID_FRAMEWORKS.includes(fw);\n    const org_ok = String(inputs.org_name || \"\").trim().length >= 2;\n    return {\n      ok: true,\n      value: {\n        inputs_valid: url_ok && fw_ok && org_ok,\n        url_ok,\n        framework_ok: fw_ok,\n        org_ok,\n        document_url: url,\n        framework: fw,\n      },\n      step_id: \"validate_inputs\",\n    };\n  },\n}\n```\n\n资料来源：[dist-test/src/validators/compliance.js:1-30]()\n\n## Adding a New Validator\n\nTo add a new domain validator:\n\n1. Create a new file in `src/validators/` (e.g., `new_domain.ts`)\n2. Export an array conforming to `Array<{ id: string; fn: ValidatorFn }>`\n3. Import and add to the aggregator in `src/validators/registry.ts`\n4. Use the naming convention: `{domain}.{validator_name}_v{version}`\n\n资料来源：[src/validators/registry.ts:1-2]()\n\n### Naming Convention\n\n| Component | Format | Example |\n|-----------|--------|---------|\n| Domain prefix | `{domain}` | `invoice`, `supply_chain` |\n| Validator name | `{validator_name}` | `validate_inputs`, `sanity_check` |\n| Version | `_v{version}` | `_v0`, `_v1` |\n\n## Security Model\n\nThe validator registry enforces a strict allowlist:\n\n- **No dynamic code execution**: Validators must be pre-registered\n- **No external function calls**: Only functions in the registry may execute\n- **No runtime injection**: Validator IDs must match registry entries exactly\n\n```mermaid\nsequenceDiagram\n    participant Contract as Contract Manifest\n    participant Registry as VALIDATOR_REGISTRY\n    participant Executor as Contract Executor\n    \n    Contract->>Executor: ValidatorRef{validator_id}\n    Executor->>Registry: get(validator_id)\n    alt ID exists in registry\n        Registry-->>Executor: ValidatorFn\n        Executor->>Executor: Call fn(inputs)\n        Executor-->>Contract: result.value\n    else ID not in registry\n        Registry-->>Executor: undefined\n        Executor-->>Contract: VALIDATOR_NOT_ALLOWED error\n    end\n```\n\nThis security boundary ensures that contract execution can only call explicitly approved validation logic, preventing arbitrary code execution during workflow runs.\n\n## Validation Result Usage\n\nValidation results populate the `analysis` object in contract state:\n\n| Key Pattern | Source | Description |\n|-------------|--------|-------------|\n| `inputs_valid` | All validators | Boolean pass/fail indicator |\n| `{field}_ok` | Domain validators | Individual field validation status |\n| `{step_id}_error` | Executor | Error messages on failure |\n\nThese values are then available as `validatorContext` for subsequent validators in the same step, enabling cascading validation logic.\n\n---\n\n<a id='page-data-schemas'></a>\n\n## Data Schemas and Types\n\n### 相关页面\n\n相关主题：[Domain Validators](#page-validators), [Core MCP Tools](#page-core-tools)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/schemas.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/types.ts)\n- [src/validation/dataspec.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validation/dataspec.ts)\n- [src/package_support.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/package_support.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n</details>\n\n# Data Schemas and Types\n\nThis document describes the core data schemas, type definitions, and validation mechanisms in the mova-flat-runner MCP server. The system uses TypeScript-first type definitions with JSON Schema validation for package manifests and runtime data validation.\n\n## Overview\n\nThe mova-flat-runner implements a governed AI workflow execution engine with multiple execution modes, contract-based state management, and human-in-the-loop approval gates. The type system is designed to enforce contract integrity across local and remote execution contexts.\n\n```mermaid\ngraph TB\n    subgraph \"Type System Layers\"\n        JS[TypeScript Types]\n        SCH[JSON Schemas]\n        VAL[Validators]\n    end\n    \n    subgraph \"Runtime Contexts\"\n        LOCAL[Local Seam Bridge]\n        REMOTE[Remote API Bridge]\n    end\n    \n    subgraph \"Execution Modes\"\n        AI[AI_ATOMIC]\n        DET[DETERMINISTIC]\n        HUM[HUMAN_GATE]\n        CTR[CONTRACT_CALL]\n    end\n    \n    JS --> SCH\n    JS --> VAL\n    SCH --> LOCAL\n    SCH --> REMOTE\n```\n\n## Core Type Definitions\n\n### MovaConfig\n\nConfiguration object for MOVA API connectivity. Required for all MCP tool executions.\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `apiUrl` | `string` | Yes | Base URL for MOVA API (default: `https://api.mova-lab.eu`) |\n| `apiKey` | `string` | Yes | API authentication key |\n| `llmKey` | `string` | No | OpenRouter API key for LLM analysis steps |\n| `llmModel` | `string` | No | OpenRouter model ID (default: `openai/gpt-4o-mini`) |\n| `timeoutMs` | `number` | No | Request timeout in milliseconds |\n| `invokeToken` | `string` | No | Local HTTP mode invocation token |\n\n资料来源：[src/index.ts:MovaConfig]()\n\n### FlatRunnerResult\n\nStandard response envelope for all MCP tool operations.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `ok` | `boolean` | Success indicator |\n| `error_code` | `string` | Error code on failure |\n| `error_message` | `string` | Human-readable error description |\n| `http_status` | `number` | HTTP status equivalent |\n\n```typescript\ninterface FlatRunnerResult {\n  ok: boolean;\n  error_code?: string;\n  error_message?: string;\n  http_status?: number;\n}\n```\n\n资料来源：[src/index.ts:FlatRunnerResult]()\n\n### ValidatorFn\n\nFunction signature for custom contract validators.\n\n```typescript\ntype ValidatorFn = (context: Record<string, unknown>) => {\n  ok: boolean;\n  value?: Record<string, unknown>;\n  step_id?: string;\n};\n```\n\n资料来源：[src/validators/supply_chain.ts:ValidatorFn]()\n\n## Execution Modes\n\nThe system defines four distinct execution modes for contract steps:\n\n| Mode | Description | Required Fields | Validation |\n|------|-------------|-----------------|------------|\n| `AI_ATOMIC` | LLM-powered single-step execution | `model` | Step must declare a model field |\n| `DETERMINISTIC` | Local JavaScript execution | None | Cannot have model field |\n| `HUMAN_GATE` | Human approval required | `decision_options` | Must have decision_options array |\n| `CONTRACT_CALL` | Cross-contract invocation | `contract_id` | Must specify target contract |\n\n```mermaid\nstateDiagram-v2\n    [*] --> DETERMINISTIC: Local check\n    [*] --> AI_ATOMIC: LLM analysis\n    [*] --> HUMAN_GATE: Approval required\n    [*] --> CONTRACT_CALL: Cross-contract\n\n    DETERMINISTIC --> [*]: Complete\n    AI_ATOMIC --> [*]: Complete\n    HUMAN_GATE --> APPROVED: Human approves\n    HUMAN_GATE --> REJECTED: Human rejects\n    CONTRACT_CALL --> [*]: Complete\n```\n\n资料来源：[src/security/step_mode_guard.ts:StepExecutionMode]()\n\n## Step Mode Validation\n\nThe `step_mode_guard` module enforces execution mode consistency through the `assertStepModesValid` function:\n\n```typescript\nexport function assertStepModesValid(\n  flow: unknown,\n  requestId: string,\n): FlatRunnerResult | null {\n  const violations = findStepModeViolations(flow);\n  if (violations.length === 0) return null;\n  return flatErr(\n    ERR.STEP_MODE_FIELD_MISMATCH,\n    `Step execution_mode does not agree with content fields`,\n    { violations, http_status_equivalent: 400 }\n  );\n}\n```\n\n**Violation Types:**\n\n| Kind | Condition |\n|------|-----------|\n| `ai_atomic_without_model` | AI_ATOMIC mode without `model` field |\n| `deterministic_with_model` | DETERMINISTIC mode with `model` field declared |\n| `contract_call_without_contract_id` | CONTRACT_CALL without target `contract_id` |\n| `human_gate_without_decisions` | HUMAN_GATE without `decision_options` array |\n\n资料来源：[src/security/step_mode_guard.ts:findStepModeViolations]()\n\n## Package Manifest Schema\n\n### Global Package Shape\n\nThe `validatePackageGlobalShape` function enforces structure for contract package manifests:\n\n```typescript\nexport function validatePackageGlobalShape(value: unknown): string | null {\n  if (!isObject(value)) return \"global file must be a JSON object\";\n  const allowedKeys = new Set([\n    \"schema_id\", \"global_id\", \"version\", \"scope\",\n    \"extends\", \"semantic_roles\", \"non_authority_rules\"\n  ]);\n  // ... validation logic\n}\n```\n\n**Required Fields:**\n\n| Field | Type | Constraint |\n|-------|------|------------|\n| `schema_id` | `string` | Non-empty |\n| `global_id` | `string` | Non-empty |\n| `version` | `string` | Non-empty |\n| `scope` | `string` | Must be `\"contract_package\"` |\n| `semantic_roles` | `array` | Non-empty array of role objects |\n| `non_authority_rules` | `array` | Non-empty array |\n\n资料来源：[src/package_support.ts:validatePackageGlobalShape]()\n\n### Semantic Role Structure\n\n```typescript\ninterface SemanticRole {\n  id: string;\n  role: string;\n  authority: string;\n  maturity: string;\n  applies_to?: string[];\n  allowed_use?: string[];\n  forbidden_use?: string[];\n  notes?: string;\n}\n```\n\n**Allowed Keys:** `id`, `role`, `authority`, `maturity`, `applies_to`, `allowed_use`, `forbidden_use`, `notes`\n\n资料来源：[src/package_support.ts:roleKeys]()\n\n## Output Schema Resolution\n\nThe `resolveOutputSchema` function locates JSON schemas for contract step outputs:\n\n```typescript\nasync function resolveOutputSchema(\n  schemaRef: string,\n  flowDir: string\n): Promise<Record<string, unknown> | null> {\n  const candidates = [\n    path.join(flowDir, \"_schemas\", `${schemaRef}.json`),\n    path.join(flowDir, \"..\", \"_data-schemas\", `${schemaRef}.json`),\n    path.join(flowDir, \"..\", \"..\", \"_data-schemas\", `${schemaRef}.json`),\n    ...(process.env.MOVA_SCHEMA_PATH \n      ? [path.join(process.env.MOVA_SCHEMA_PATH, `${schemaRef}.json`)]\n      : []\n    ),\n  ];\n  // ... search logic\n}\n```\n\n**Search Order (priority):**\n1. `{flowDir}/_schemas/{schemaRef}.json`\n2. `{flowDir}/../_data-schemas/{schemaRef}.json`\n3. `{flowDir}/../../_data-schemas/{schemaRef}.json`\n4. `$MOVA_SCHEMA_PATH/{schemaRef}.json` (if set)\n\n资料来源：[src/package_support.ts:resolveOutputSchema]()\n\n## Local Seam Bridge Types\n\n### BridgeRequest\n\n```typescript\ninterface BridgeRequest {\n  contractRef: string;\n  packagePath: string;\n  step: {\n    id: string;\n    execution_mode: StepExecutionMode;\n  };\n  outputSchemaPath?: string;\n  taskType?: string;\n  stepResult?: unknown;\n  terminalOutcome?: string;\n  humanDecision?: string;\n  routeKey?: string;\n}\n```\n\n### BridgeResponse\n\n```typescript\ninterface BridgeResponse {\n  ok: boolean;\n  bridge: {\n    ok: boolean;\n    bridge_source: string;\n    status: \"completed\" | \"advanced\" | \"human_gate_required\";\n    contract_ref: string;\n    current_step_id: string;\n    execution_mode: StepExecutionMode;\n    produced_output: unknown;\n    proof_ref: string;\n    state_ref: string;\n    next_state_ref: string;\n    decision_kind: { kind: \"Pass\" | \"Fail\" };\n    commit_effect: { kind: \"Apply\" | \"Skip\" };\n    next_phase: { phase: \"EXECUTION\" | \"WAIT_HUMAN\" };\n  };\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:BridgeRequest]()\n\n## Contract Manifest\n\nThe `CONTRACT_MANIFESTS` registry defines built-in contract types:\n\n```typescript\ninterface ContractManifest {\n  contract_type: string;\n  title: string;\n  version: string;\n  execution_mode: StepExecutionMode;\n  template_id?: string;\n  policy_id?: string;\n  dataspec: {\n    inputs: Array<{\n      key: string;\n      label?: string;\n      type: string;\n      required?: boolean;\n    }>;\n  };\n  decision_options?: Array<{\n    id: string;\n    label: string;\n    description?: string;\n  }>;\n}\n```\n\n资料来源：[src/index.ts:CONTRACT_MANIFESTS]()\n\n## Validation Utilities\n\n### Required String Validation\n\n```typescript\nfunction validateRequiredString(\n  obj: Record<string, unknown>,\n  key: string,\n  scope: string\n): string | null {\n  if (typeof obj[key] !== \"string\" || (obj[key] as string).trim().length === 0) {\n    return `${scope} is missing required string field \"${key}\"`;\n  }\n  return null;\n}\n```\n\n### Public Shape Sanitization\n\nThe `sanitizePublicShape` function filters internal bridge fields from public responses:\n\n```typescript\nfunction sanitizePublicShape(value: unknown): boolean {\n  const BLOCKED_KEYS = [\n    \"bridge_anchors\",\n    \"last_terminal_bridge\",\n    \"terminal_commit_count\",\n    \"_state15_bridge\",\n    \"trace\",\n    \"outputs\",\n    \"context\"\n  ];\n  // Recursively validates and filters\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:sanitizePublicShape]()\n\n## MCP Server Configuration Schema\n\nDefined in `server.json` per Model Context Protocol specification:\n\n```json\n{\n  \"$schema\": \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\",\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\"\n}\n```\n\n**Environment Variables:**\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `MOVA_API_KEY` | Yes | API key for MOVA backend |\n| `LLM_KEY` | Yes | OpenRouter API key |\n| `LLM_MODEL` | No | OpenRouter model ID |\n| `MOVA_API_URL` | No | Override default API URL |\n\n资料来源：[server.json:environmentVariables]()\n\n## Error Types\n\n| Error Code | HTTP Status | Description |\n|------------|-------------|-------------|\n| `UNKNOWN_CONTRACT_TYPE` | 404 | Contract type not found in manifests |\n| `LOCAL_VALIDATION_FAILED` | 400 | Input validation failed |\n| `STEP_MODE_FIELD_MISMATCH` | 400 | Execution mode conflicts with fields |\n| `MOVA_API_ERROR` | 502 | Upstream API failure |\n| `MOVA_API_404` | 404 | Resource not found on backend |\n\n资料来源：[src/index.ts:ERR]()\n\n## Type Exports Summary\n\n| File | Primary Exports |\n|------|-----------------|\n| `src/types.ts` | Core type interfaces (MovaConfig, FlatRunnerResult) |\n| `src/schemas.ts` | JSON Schema definitions for validation |\n| `src/validation/dataspec.ts` | Data specification validators |\n| `src/package_support.ts` | Package manifest validation |\n| `src/security/step_mode_guard.ts` | Execution mode validation |\n\n资料来源：[src/types.ts](), [src/schemas.ts](), [src/validation/dataspec.ts]()\n\n---\n\n<a id='page-deployment'></a>\n\n## Deployment and Operations\n\n### 相关页面\n\n相关主题：[Installation and Setup](#page-installation-setup), [Transport Layer](#page-transport-layer), [Extensibility and Customization](#page-extensibility)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/mova-compact/mova-flat-runner/blob/main/README.md)\n- [package.json](https://github.com/mova-compact/mova-flat-runner/blob/main/package.json)\n- [server.json](https://github.com/mova-compact/mova-flat-runner/blob/main/server.json)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n</details>\n\n# Deployment and Operations\n\n## Overview\n\nThe MOVA Flat Runner is distributed as an MCP (Model Context Protocol) server package (`@leryk1981/mova-flat-runner`) that provides governed AI workflow capabilities including invoice OCR, AML triage, credit review, and custom contracts with human approval gates and audit trails.\n\nThis section covers the deployment architecture, build system, runtime configuration, publishing workflow, and operational considerations for running the MOVA Flat Runner in production and development environments.\n\n## Architecture Overview\n\n```mermaid\ngraph TD\n    subgraph \"Client Layer\"\n        Claude[\"Claude Desktop\"]\n        Codex[\"Codex IDE\"]\n    end\n    \n    subgraph \"MCP Transport\"\n        STDIO[\"STDIO Transport\"]\n        HTTP[\"Local HTTP Mode\"]\n    end\n    \n    subgraph \"MOVA Flat Runner\"\n        Index[\"src/index.ts\"]\n        API[\"HTTP Handlers\"]\n        Auth[\"Authentication\"]\n        Service[\"Business Logic\"]\n    end\n    \n    subgraph \"External Services\"\n        MOVA_API[\"MOVA API\"]\n        LLM[\"LLM Provider\"]\n    end\n    \n    Claude --> STDIO\n    Codex --> HTTP\n    STDIO --> Index\n    HTTP --> Index\n    Index --> API\n    Index --> Auth\n    Index --> Service\n    Service --> MOVA_API\n    Service --> LLM\n```\n\n## Build System\n\n### TypeScript Configuration\n\nThe project uses TypeScript with separate configurations for production and testing builds.\n\n**Production Build (`tsconfig.json`)**\n\n| Setting | Value | Purpose |\n|---------|-------|---------|\n| `target` | `ES2022` | ECMAScript target version |\n| `module` | `ES2022` / `NodeNext` | ESM module system |\n| `outDir` | `dist` | Compiled output directory |\n| `rootDir` | `src` | Source root directory |\n| `strict` | `true` | Enable strict type checking |\n\n**Test Build (`tsconfig.test.json`)**\n\n| Setting | Value | Purpose |\n|---------|-------|---------|\n| `extends` | `./tsconfig.json` | Inherits base config |\n| `outDir` | `dist-test` | Separate test output directory |\n| `rootDir` | `src` | Source root directory |\n\n### Build Pipeline\n\n```mermaid\ngraph LR\n    A[\"src/*.ts\"] --> B[\"tsc compiler\"]\n    B --> C[\"dist/index.js\"]\n    C --> D[\"shebang injection\"]\n    D --> E[\"chmod +x\"]\n    \n    F[\"src/*.ts\"] --> G[\"tsc (test config)\"]\n    G --> H[\"dist-test/\"]\n```\n\n### npm Scripts\n\n| Script | Command | Purpose |\n|--------|---------|---------|\n| `build` | `tsc && node -e \"...\"` | Compile TypeScript and make executable |\n| `check` | `make check` | Run lint, unit tests, and integration tests |\n| `test:build` | `tsc -p tsconfig.test.json` | Build test artifacts |\n\n资料来源：[package.json:18-24]()\n\n## MCP Server Configuration\n\n### Server Metadata\n\n```json\n{\n  \"name\": \"io.github.mova-compact/mova-flat-runner\",\n  \"version\": \"2.0.6\",\n  \"description\": \"Governed AI workflows with human approval gates and audit trails\",\n  \"repository\": {\n    \"url\": \"https://github.com/mova-compact/mova-flat-runner\",\n    \"source\": \"github\"\n  }\n}\n```\n\n### Runtime Hints\n\n| Property | Value | Notes |\n|----------|-------|-------|\n| `runtimeHint` | `node` | Requires Node.js runtime |\n| `transport` | `stdio` | Primary transport protocol |\n\n资料来源：[server.json:1-15]()\n\n## Environment Variables\n\n### Required Variables\n\n| Variable | Description | Example |\n|----------|-------------|---------|\n| `MOVA_API_KEY` | MOVA API authentication key | `__SET_MOVA_API_KEY__` |\n| `LLM_KEY` | OpenRouter API key for LLM analysis | `__SET_LLM_KEY__` |\n\n### Optional Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `MOVA_API_URL` | `https://api.mova-lab.eu` | MOVA API base URL |\n| `LLM_MODEL` | `openai/gpt-4o-mini` | OpenRouter model ID |\n| `MOVA_API_TIMEOUT_MS` | `30000` | API request timeout |\n| `MOVA_HTTP_PORT` | `3796` | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | — | Token for local HTTP invocation |\n\n资料来源：[README.md:40-57]()\n\n## Publishing and Distribution\n\n### Publishing Workflow\n\nThe project includes a dedicated CLI tool for publishing servers to the MCP registry.\n\n```bash\n# Build the publisher CLI\nmake publisher\n\n# Publish a server\n./bin/mcp-publisher --help\n```\n\n### npm Distribution\n\nThe package is published to npm as `@leryk1981/mova-flat-runner`:\n\n| Property | Value |\n|----------|-------|\n| Package Name | `@leryk1981/mova-flat-runner` |\n| Current Version | `3.3.4` |\n| Binary | `mova-mcp` |\n| Entry Point | `dist/index.js` |\n\n资料来源：[package.json:3-6]()\n\n### Client Configuration Examples\n\n**Claude Desktop (JSON)**\n\n```json\n{\n  \"mcpServers\": {\n    \"mova\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"],\n      \"env\": {\n        \"MOVA_API_URL\": \"https://api.mova-lab.eu\",\n        \"MOVA_API_KEY\": \"__SET_MOVA_API_KEY__\",\n        \"LLM_KEY\": \"__SET_LLM_KEY__\",\n        \"LLM_MODEL\": \"openai/gpt-4o-mini\"\n      }\n    }\n  }\n}\n```\n\n**Codex (TOML)**\n\n```toml\n[mcp_servers.mova]\ncommand = \"npx\"\nargs = [\"-y\", \"@leryk1981/mova-flat-runner@3.3.3\"]\nstartup_timeout_sec = 90.0\n\n[mcp_servers.mova.env]\nMOVA_API_URL = \"https://api.mova-lab.eu\"\nMOVA_API_KEY = \"__SET_MOVA_API_KEY__\"\nLLM_KEY = \"__SET_LLM_KEY__\"\nLLM_MODEL = \"openai/gpt-4o-mini\"\n```\n\n资料来源：[README.md:63-100]()\n\n## Deployment Configuration\n\n### Project Structure\n\n```\nmova-flat-runner/\n├── cmd/                     # Application entry points\n│   └── publisher/           # Server publishing tool\n├── deploy/                  # Deployment configuration (Pulumi)\n├── internal/                # Private application code\n│   ├── api/                 # HTTP handlers and routing\n│   ├── auth/                # Authentication (GitHub OAuth, JWT)\n│   ├── config/              # Configuration management\n│   ├── database/            # Data persistence (PostgreSQL)\n│   ├── service/             # Business logic\n│   ├── telemetry/           # Metrics and monitoring\n│   └── validators/          # Input validation\n├── pkg/                     # Public packages\n└── tools/                   # Operational tools\n```\n\n### Pulumi Deployment\n\nInfrastructure is managed via Pulumi in the `deploy/` directory. This enables repeatable, version-controlled infrastructure deployments.\n\n资料来源：[README.md:12-29]()\n\n## Health Monitoring\n\n### Health Check Endpoint\n\n```bash\ncurl -sS https://api.mova-lab.eu/health\n```\n\n### Available Tools for Monitoring\n\n| Tool | Purpose |\n|------|---------|\n| `mova_health` | Server health status |\n| `mova_registry` | MCP registry information |\n| `mova_run` | Contract execution |\n| `mova_query` | Query contract status |\n| `mova_decide` | Human decision handling |\n| `mova_connector` | External system integration |\n| `mova_contract` | Contract management |\n\n资料来源：[README.md:58-60]()\n\n## Local HTTP Mode Operations\n\n### Overview\n\nThe flat runner supports an optional local HTTP transport mode for environments where STDIO is not suitable.\n\n```mermaid\ngraph TD\n    Client[\"MCP Client\"] --> |HTTP Request| LocalHTTP[\"Local HTTP Bridge\"]\n    LocalHTTP --> |STDIO| MOVA_MCP[\"MOVA MCP Server\"]\n    MOVA_MCP --> |Response| LocalHTTP\n    LocalHTTP --> |HTTP Response| Client\n    \n    subgraph \"Local Environment\"\n        LocalHTTP\n        MOVA_MCP\n    end\n```\n\n### Configuration\n\n```env\nMOVA_HTTP_PORT=3796\nMOVA_INVOKE_TOKEN=__SET_LOCAL_INVOKE_TOKEN__\nMOVA_API_TIMEOUT_MS=30000\n```\n\n### Security Considerations\n\n- `MOVA_INVOKE_TOKEN` must be set to authorize local HTTP requests\n- API timeouts prevent hanging requests (default: 30 seconds)\n- Health checks should be performed before heavy operations\n\n资料来源：[README.md:50-55]()\n\n## Development Operations\n\n### Makefile Targets\n\n| Target | Purpose |\n|--------|---------|\n| `make check` | Run lint, unit tests, integration tests |\n| `make help` | Display available commands |\n| `make publisher` | Build the MCP publisher CLI |\n\n### Validation Workflow\n\n```mermaid\ngraph LR\n    A[\"npm run build\"] --> B[\"npm run test:build\"]\n    B --> C[\"npm run smoke:*\"]\n    C --> D[\"Validation Complete\"]\n```\n\n### Smoke Testing\n\nCustom bridge validation:\n\n```bash\nnpm run smoke:custom-bridge\n```\n\nThis validates the custom contract query bridge for handling `mova_query` requests when the backend namespace is absent.\n\n资料来源：[tasks/task061.md:1-50]()\n\n## Operational Data Flows\n\n### Local Seam Bridge Execution\n\n```mermaid\nsequenceDiagram\n    participant MCP as MCP Client\n    participant Bridge as Local Seam Bridge\n    participant Machine as State Machine\n    participant FS as File System\n    \n    MCP->>Bridge: Execute step with state\n    Bridge->>Machine: Load machine module\n    Machine->>FS: Read state file\n    FS-->>Machine: State data\n    Machine->>Machine: Execute step logic\n    Machine->>FS: Write updated state\n    Bridge->>MCP: Return result with proofs\n```\n\n### Custom Contract Bridge\n\nFor custom contract IDs (prefixed with `local-*` or `remote-*`), the system maintains an in-memory bridge map:\n\n```typescript\nCUSTOM_RUN_BRIDGE: Map<contract_id, {run_id, updated_at, source_url?}>\n```\n\n资料来源：[src/index.ts:1-100]()\n\n## Security Notes\n\n### Environment Variable Security\n\n| Practice | Requirement |\n|----------|-------------|\n| Placeholders in docs | Use `__SET_*__` format |\n| Real secrets | Never commit to repository |\n| API keys | Use `MOVA_API_KEY`, `LLM_KEY` |\n\n> **Warning**: Do not commit real `MOVA_API_KEY`, `LLM_KEY`, or `MOVA_INVOKE_TOKEN` to version control.\n\n资料来源：[README.md:37-39]()\n\n### Step Mode Validation\n\nThe system validates step execution modes at runtime:\n\n| Mode | Validation Rule |\n|------|-----------------|\n| `DETERMINISTIC` | Cannot have `model` field |\n| `AI_ATOMIC` | Must have `model` field |\n| `CONTRACT_CALL` | Must have `contract_id` |\n| `HUMAN_GATE` | Must have `decision_options` array |\n\n资料来源：[dist-test/src/security/step_mode_guard.js:1-50]()\n\n## Deployment Environments\n\n### Build Variants\n\n| Branch | Purpose | Build Output |\n|--------|---------|--------------|\n| `main` | Production builds | `dist/` |\n| `main-<date>-<sha>` | Specific commit builds | `dist/` |\n\n### Continuous Integration\n\n```\nmain branch → Continuous build → Latest stable release\n```\n\n资料来源：[README.md:1-5]()\n\n## Troubleshooting\n\n| Issue | Resolution |\n|-------|------------|\n| Build fails | Run `npm run build` |\n| Test failures | Run `make check` |\n| MCP connection issues | Verify `MOVA_API_KEY` and `LLM_KEY` |\n| Custom contract 404 | Use `mova_contract` for custom IDs |\n| Human gate timeout | Check `MOVA_API_TIMEOUT_MS` setting |\n\n## Related Documentation\n\n- [Quickstart Guide](./docs/modelcontextprotocol-io/quickstart.mdx)\n- [Live API Docs](https://registry.modelcontextprotocol.io/docs)\n- [Ecosystem Vision](./docs/design/ecosystem-vision.md)\n\n---\n\n<a id='page-extensibility'></a>\n\n## Extensibility and Customization\n\n### 相关页面\n\n相关主题：[Domain Validators](#page-validators), [Security Guards](#page-security-guards), [Deployment and Operations](#page-deployment)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/validators/registry.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/registry.ts)\n- [src/validators/supply_chain.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/validators/supply_chain.ts)\n- [src/index.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/index.ts)\n- [src/transports/local_seam_bridge.ts](https://github.com/mova-compact/mova-flat-runner/blob/main/src/transports/local_seam_bridge.ts)\n- [dist-test/src/package_support.js](https://github.com/mova-compact/mova-flat-runner/blob/main/dist-test/src/package_support.js)\n</details>\n\n# Extensibility and Customization\n\nThe mova-flat-runner provides multiple layers of extensibility, allowing operators to add custom validators, define new contract types, extend execution modes, and integrate with external systems. This document describes the core extension points and customization mechanisms available in the MCP server.\n\n## 1. Validator Registry System\n\n### 1.1 Architecture Overview\n\nThe validator registry is the primary extension point for business logic validation. It implements a **whitelist-based security model** where only explicitly registered validator functions may be invoked during contract execution. Dynamic code execution is prohibited.\n\n```mermaid\ngraph TD\n    A[Contract Execution] --> B{ValidatorRef found?}\n    B -->|Yes| C[Lookup in VALIDATOR_REGISTRY]\n    B -->|No| D[Return VALIDATOR_NOT_ALLOWED error]\n    C --> E{Validator registered?}\n    E -->|Yes| F[Execute ValidatorFn]\n    E -->|No| D\n    F --> G[Return validation result]\n    D --> H[Audit log: validator blocked]\n```\n\n### 1.2 Registry Implementation\n\nThe `VALIDATOR_REGISTRY` is a `Map<string, ValidatorFn>` that maps each validator's unique identifier to its implementation function. All validators must conform to the `ValidatorFn` type signature.\n\n**Type Signature:**\n```typescript\ntype ValidatorFn = (inputs: Record<string, unknown>) => {\n    ok: boolean;\n    value: Record<string, unknown>;\n    step_id: string;\n};\n```\n\n### 1.3 Registered Validator Modules\n\n| Module | Source File | Validators |\n|--------|-------------|------------|\n| Invoice | `invoice.ts` | invoice validation validators |\n| Purchase Order | `po.ts` | PO validation validators |\n| Trade | `trade.ts` | trade validation validators |\n| AML | `aml.ts` | AML triage validators |\n| Complaint | `complaint.ts` | complaint handling validators |\n| Compliance | `compliance.ts` | compliance check validators |\n| Credit | `credit.ts` | credit review validators |\n| Supply Chain | `supply_chain.ts` | supplier validation validators |\n| Churn | `churn.ts` | churn prediction validators |\n| Contract Gen | `contract_gen.ts` | contract generation validators |\n\n资料来源：[src/validators/registry.ts:1-28]()\n\n### 1.4 Adding a New Validator\n\nTo add a new validator:\n\n1. **Implement the validator function** in a contract-specific file following the `ValidatorFn` signature\n2. **Export it** as part of a validator array with a unique `id`\n3. **Register it** in `src/validators/registry.ts`\n\n**Example from supply_chain.ts:**\n```typescript\nexport const supplyChainValidators: Array<{ id: string; fn: ValidatorFn }> = [\n  {\n    id: \"supply_chain.validate_inputs_v0\",\n    fn: (inputs) => {\n      const suppliers = Array.isArray(inputs.suppliers) ? inputs.suppliers : [];\n      const valid_items = suppliers.filter(s =>\n        s && typeof s === \"object\" &&\n        String(s[\"id\"] || \"\").length > 0 &&\n        /^[A-Z]{2}$/.test(String(s[\"country\"] || \"\"))\n      );\n      return {\n        ok: true,\n        value: {\n          inputs_valid: valid_items.length === suppliers.length,\n          supplier_count: suppliers.length,\n        },\n        step_id: \"validate_inputs\",\n      };\n    },\n  },\n];\n```\n\n资料来源：[src/validators/supply_chain.ts:1-35]()\n\n### 1.5 Security Model\n\nThe registry enforces these security constraints:\n\n| Constraint | Description |\n|------------|-------------|\n| Whitelist-only | Only functions in the registry may execute |\n| No dynamic code | Arbitrary code execution is forbidden |\n| Type enforcement | All validators must return `{ok, value, step_id}` |\n| Step isolation | Validators operate on sanitized input contexts |\n\nDuring contract execution, the runner checks each `ValidatorRef` against the registry before invocation:\n\n```typescript\nconst fn = VALIDATOR_REGISTRY.get(validator.validator_id);\nif (!fn) {\n    analysis[`${validator.step_id}_error`] = `VALIDATOR_NOT_ALLOWED: \"${validator.validator_id}\" not in registry`;\n    continue;\n}\n```\n\n资料来源：[dist-test/src/transports/remote_api.js:1-25]()\n\n## 2. Contract Manifest System\n\n### 2.1 Manifest Structure\n\nContract manifests define the metadata, inputs, and behavior of each contract type. Built-in manifests are stored in `CONTRACT_MANIFESTS`:\n\n```typescript\ntype ContractManifest = {\n    contract_type: string;\n    title: string;\n    version: string;\n    execution_mode: \"AI_ATOMIC\" | \"HUMAN_GATE\" | \"LOCAL_SEAM\";\n    template_id: string;\n    policy_id: string;\n    dataspec: { inputs: InputSpec[] };\n    decision_options?: DecisionOption[];\n};\n```\n\n### 2.2 Manifest Registry Resources\n\nThe MCP server exposes manifests via the `mova://` URI scheme:\n\n| Resource URI | Description |\n|--------------|-------------|\n| `mova://registry` | Lists all available contract types |\n| `mova://schemas/envelopes` | Returns envelope schema definition |\n| `mova://contracts/{type}/manifest` | Returns specific contract manifest |\n\n```typescript\nfunction readResource(uri: string): unknown {\n  if (uri === \"mova://registry\") {\n    return {\n      schema_version: \"1.0\",\n      contracts: Object.values(CONTRACT_MANIFESTS).map(m => ({\n        contract_type: m.contract_type,\n        title: m.title,\n        version: m.version,\n        manifest_resource: `mova://contracts/${m.contract_type}/manifest`,\n      })),\n    };\n  }\n  // ...\n}\n```\n\n资料来源：[src/index.ts:300-350]()\n\n## 3. Custom Contract Bridge\n\n### 3.1 The Namespace Gap Problem\n\nCustom contracts registered via `mova_contract register` use `local-*` or `remote-*` ID prefixes and execute in the `/run/*` namespace. However, `mova_query` operations query the `/api/v1/contracts/*` namespace, resulting in 404 errors for custom contracts.\n\n### 3.2 Bridge Implementation\n\nThe custom contract bridge provides a mitigation layer:\n\n```mermaid\ngraph LR\n    A[register] --> B[rememberCustomRun]\n    B --> C[CUSTOM_RUN_BRIDGE Map]\n    C --> D[mova_query status]\n    D --> E{404 from API?}\n    E -->|Yes| F[getMyContractRecord]\n    F --> G{Bridge entry found?}\n    G -->|Yes| H[Return bridged status]\n    G -->|No| I[Return error]\n```\n\n### 3.3 Bridge Components\n\n| Component | Type | Purpose |\n|-----------|------|---------|\n| `CUSTOM_RUN_BRIDGE` | `Map<contract_id, {run_id, updated_at, source_url?}>` | In-memory ID mapping |\n| `rememberCustomRun()` | Function | Captures and persists contract→run mapping |\n| `getMyContractRecord()` | Function | Probes `/api/v1/contracts/my` for metadata |\n\n**Memory Bridge Map:**\n```typescript\nconst CUSTOM_RUN_BRIDGE = new Map<string, CustomRunRef>();\n\nfunction rememberCustomRun(contractId: string, runId: string, sourceUrl?: string): void {\n    if (typeof contractId !== \"string\" || typeof runId !== \"string\") return;\n    const ref = { run_id: runId, updated_at: new Date().toISOString() };\n    if (sourceUrl) ref.source_url = sourceUrl;\n    CUSTOM_RUN_BRIDGE.set(contractId, ref);\n}\n```\n\n资料来源：[src/index.ts:400-420]()\n\n### 3.4 Bridge Response Modes\n\n| View Mode | Behavior |\n|-----------|----------|\n| `status` | Returns structured bridged status with `bridge_mode=custom_contract_run_namespace_bridge_v1` |\n| `audit` | Returns `AUDIT_UNAVAILABLE` envelope (honest unavailability) |\n| `audit_compact` | Returns `{ok=false, status=424}` with JSON journal explaining bridge |\n\n资料来源：[tasks/task061.md:1-60]()\n\n## 4. Local Seam Execution Mode\n\n### 4.1 Overview\n\nThe `LOCAL_SEAM` execution mode allows contracts to run entirely within the MCP server process, bypassing the remote MOVA API. This is critical for offline development and testing scenarios.\n\n### 4.2 Execution Flow\n\n```mermaid\ngraph TD\n    A[mova_run contract_type] --> B{Is LOCAL_SEAM?}\n    B -->|No| C[Remote API execution]\n    B -->|Yes| D[Resolve local locator]\n    D --> E[Load sandbox package]\n    E --> F[Execute steps locally]\n    F --> G{Step type?}\n    G -->|AI_ATOMIC| H[LLM invocation]\n    G -->|HUMAN_GATE| I[Wait for gate decision]\n    G -->|Standard| J[Apply step logic]\n    H --> K[Validate output schema]\n    I --> L[Bridge to human approval]\n    J --> K\n    K --> M{More steps?}\n    M -->|Yes| F\n    M -->|No| N[Return FlatRunnerResult]\n```\n\n### 4.3 Local Seam Locator Resolution\n\n```typescript\nasync function resolveLocalSeamLocator(initialInputs: Record<string, unknown>): Promise<SeamLocator> {\n    const packagePath = initialInputs.package_path \n        ?? process.env.MOVA_SANDBOX_PACKAGE_PATH \n        ?? \"default-contract-path\";\n    const projectPath = initialInputs.project_path \n        ?? process.env.MOVA_SANDBOX_PROJECT_PATH \n        ?? \"\";\n    // ...\n}\n```\n\n资料来源：[src/transports/local_seam_bridge.ts:50-80]()\n\n### 4.4 Sandbox Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MOVA_SANDBOX_PACKAGE_PATH` | Path to contract package | Project-specific |\n| `MOVA_SANDBOX_PROJECT_PATH` | Path to project directory | Required |\n| `MOVA_SANDBOX_STATE_FILE` | State persistence file | System temp |\n\n## 5. Package Global Support\n\n### 5.1 Package Manifest Validation\n\nCustom contract packages must include a `global` file conforming to the `contract_package` scope. The validation enforces strict schema requirements:\n\n**Required Fields:**\n\n| Field | Type | Constraint |\n|-------|------|------------|\n| `global_id` | string | Non-empty |\n| `version` | string | Non-empty |\n| `scope` | string | Must be `contract_package` |\n| `extends` | array | Optional, must be array if present |\n| `semantic_roles` | array | Non-empty, objects with allowed keys |\n| `non_authority_rules` | array | Non-empty |\n\n**Validation Rules for semantic_roles:**\n```javascript\nconst roleKeys = new Set([\n    \"id\", \"role\", \"authority\", \"maturity\", \n    \"applies_to\", \"allowed_use\", \"forbidden_use\", \"notes\"\n]);\nfor (const key of Object.keys(role)) {\n    if (!roleKeys.has(key))\n        return `global semantic_roles[${index}] contains unsupported field \"${key}\"`;\n}\n```\n\n资料来源：[dist-test/src/package_support.js:1-30]()\n\n### 5.2 Global File Schema\n\n```typescript\ninterface PackageGlobal {\n    global_id: string;\n    version: string;\n    scope: \"contract_package\";\n    extends?: string[];\n    semantic_roles: Array<{\n        id: string;\n        role: string;\n        authority: string;\n        maturity: string;\n        applies_to?: string;\n        allowed_use?: string[];\n        forbidden_use?: string[];\n        notes?: string;\n    }>;\n    non_authority_rules: string[];\n}\n```\n\n## 6. MCP Tool Extensibility\n\n### 6.1 Available Tools\n\n| Tool | Purpose | Extensibility |\n|------|---------|---------------|\n| `mova_health` | Health check | Fixed |\n| `mova_registry` | List contract types | Fixed |\n| `mova_run` | Execute built-in contracts | Extend via CONTRACT_MANIFESTS |\n| `mova_query` | Query contract status/audit | Bridge extensible |\n| `mova_decide` | Submit human decisions | Fixed |\n| `mova_connector` | Connect to external systems | Fixed |\n| `mova_contract` | Custom contract operations | Core extensibility interface |\n\n### 6.2 Tool Executor Pattern\n\nTools are registered in a switch-based executor that maps tool names to handler functions:\n\n```typescript\nasync function executeTool(name: string, args: Args): Promise<string> {\n  const requestId = shortId();\n  switch (name) {\n    case \"mova_run\": {\n      const manifest = CONTRACT_MANIFESTS[contractType];\n      if (!manifest) {\n        return JSON.stringify(flatErr(\n          ERR.UNKNOWN_CONTRACT_TYPE,\n          `Unknown contract_type \"${contractType}\". For custom contracts use mova_contract action=run.`,\n          { available: Object.keys(CONTRACT_MANIFESTS) },\n          false, requestId\n        ));\n      }\n      // ...\n    }\n  }\n}\n```\n\n资料来源：[src/index.ts:450-480]()\n\n## 7. Configuration Extension Points\n\n### 7.1 Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `MOVA_API_URL` | Yes | MOVA API base URL |\n| `MOVA_API_KEY` | Yes | API authentication key |\n| `LLM_KEY` | Conditional | OpenRouter API key for LLM steps |\n| `LLM_MODEL` | No | Model identifier, default: `openai/gpt-4o-mini` |\n| `MOVA_API_TIMEOUT_MS` | No | HTTP timeout in milliseconds |\n| `MOVA_HTTP_PORT` | No | Local HTTP mode port |\n| `MOVA_INVOKE_TOKEN` | No | Local invoke authentication |\n\n### 7.2 Config Merging\n\nThe configuration system supports runtime overrides through environment variables, with precedence: CLI args > env vars > defaults.\n\n## 8. Extension Summary\n\n```mermaid\ngraph TD\n    subgraph Extension Points\n        A[Validator Registry]\n        B[Contract Manifests]\n        C[Package Global]\n        D[Local Seam Mode]\n    end\n    \n    subgraph Security Layer\n        E[Whitelist Enforcement]\n        F[Type Validation]\n        G[Schema Validation]\n    end\n    \n    subgraph MCP Tools\n        H[mova_contract]\n        I[mova_run]\n        J[mova_query]\n    end\n    \n    A --> E\n    B --> G\n    C --> G\n    D --> F\n    H --> A\n    H --> B\n    I --> A\n    J --> C\n    J --> D\n```\n\nThe mova-flat-runner's extensibility model is designed for **operator-controlled customization** while maintaining strict security boundaries. Validators, contracts, and execution modes can be extended without modifying core server code, enabling safe customization in regulated environments.\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：mova-compact/mova-flat-runner\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。\n\n## 1. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt\n\n## 2. 配置坑 · 来源证据：v3.0.0 — Step Enforcement Runtime\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：v3.0.0 — Step Enforcement Runtime\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_10b68dae59184a36b21a563722829aed | https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown\n\n<!-- canonical_name: mova-compact/mova-flat-runner; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：mova-compact/mova-flat-runner\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。\n\n## 1. 配置坑 · 可能修改宿主 AI 配置\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。\n- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。\n- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。\n- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。\n- 证据：capability.host_targets | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | host_targets=mcp_host, claude, chatgpt\n\n## 2. 配置坑 · 来源证据：v3.0.0 — Step Enforcement Runtime\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：v3.0.0 — Step Enforcement Runtime\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_10b68dae59184a36b21a563722829aed | https://github.com/mova-compact/mova-flat-runner/releases/tag/v3.0.0 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 3. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | README/documentation is current enough for a first validation pass.\n\n## 4. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | last_activity_observed missing\n\n## 5. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 6. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | no_demo; severity=medium\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1212840167 | https://github.com/mova-compact/mova-flat-runner | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# mova-flat-runner - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 mova-flat-runner 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client / claude / chatgpt\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: MCP Registry 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-project-overview：Project Overview。围绕“Project Overview”模拟一次用户任务，不展示安装或运行结果。\n2. page-core-tools：Core MCP Tools。围绕“Core MCP Tools”模拟一次用户任务，不展示安装或运行结果。\n3. page-installation-setup：Installation and Setup。围绕“Installation and Setup”模拟一次用户任务，不展示安装或运行结果。\n4. page-architecture：System Architecture。围绕“System Architecture”模拟一次用户任务，不展示安装或运行结果。\n5. page-security-guards：Security Guards。围绕“Security Guards”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-project-overview\n输入：用户提供的“Project Overview”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-core-tools\n输入：用户提供的“Core MCP Tools”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-installation-setup\n输入：用户提供的“Installation and Setup”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-architecture\n输入：用户提供的“System Architecture”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-security-guards\n输入：用户提供的“Security Guards”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-project-overview：Step 1 必须围绕“Project Overview”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-core-tools：Step 2 必须围绕“Core MCP Tools”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-installation-setup：Step 3 必须围绕“Installation and Setup”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-architecture：Step 4 必须围绕“System Architecture”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-security-guards：Step 5 必须围绕“Security Guards”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/mova-compact/mova-flat-runner\n- https://github.com/mova-compact/mova-flat-runner#readme\n- README.md\n- package.json\n- src/index.ts\n- src/types.ts\n- src/client.ts\n- src/schemas.ts\n- smithery.yaml\n- server.json\n- src/package_support.ts\n- src/transports/local_seam_bridge.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 mova-flat-runner 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：mova-compact/mova-flat-runner\n\n## 官方安装入口\n\n### Node.js / npx · 官方安装入口\n\n```bash\nnpx -y @leryk1981/mova-flat-runner@3.3.3\n```\n\n来源：https://github.com/mova-compact/mova-flat-runner#readme\n\n## 来源\n\n- repo: https://github.com/mova-compact/mova-flat-runner\n- docs: https://github.com/mova-compact/mova-flat-runner#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_b9c2ece545924497a3a7cc01468e2261"
}
