# AGENTS.md

本文件是 Moss 仓库对所有 coding agent 的项目指令（被 git 跟踪、可审查）。

## 仓库身份

Moss 是一个精简的跨平台 coding agent harness：TypeScript / ESM 单包仓库（根 `package.json`，
包名 `moss`，bin 为 `dist/cli.js`），Node ≥ 22.16.0，运行于 Linux / macOS / Windows。

核心能力（也是唯一应当存在的范围）：agent loop、工具框架（`src/tools/`）、上下文管理
（`src/context/`）、provider（`src/provider/`）、安全（`src/safety/`）、会话
（`src/core/session/`）、子代理（`src/core/subagent/`）与 CLI（`src/cli/`、`src/cli-main.ts`）、
设备抽象（`src/device/` + `src/contracts/device.ts` + `src/tools/device-tools.ts`，SSH 连 RDK /
Linux 真机，目标是机器人闭环 Goal→…→Deploy→Verify→Repair→Physical Acceptance）。
共享契约在 `src/contracts/`。

范围变更（2026-09-30 v0.14–v0.20 路线图冻结决策，见
`docs/superpowers/plans/2026-09-30-moss-v014-v020-roadmap.md`；同日机器人闭环总指令为
更高优先级的产品方向，两线共存）：

- **解冻**：MCP 客户端（仅客户端；stdio + streamable HTTP 双传输、工具懒加载、
  `src/core/mcp/`，v0.16）与轻量 skills（SKILL.md 渐进披露、`src/core/skills/`，v0.16）。
- **翻案**：v0.17 起引入可选全屏 TUI（ink，严格圈禁 `src/cli/tui/` 动态 import，
  无 TTY 或 `--no-tty` 回退 readline REPL；REPL 永久保留）。
- **维持冻结**：memory（跨会话自动记忆）/ mesh / observability / orchestration /
  web-ui / 插件市场。不要重新引入这些子系统。

## 代码规范（必须遵守）

- Prettier 负责格式；TypeScript/JavaScript/MJS 文件名用 kebab-case；Node 内置模块用
  `node:` 前缀；仅类型导入用 `import type`；ESM 相对导入带 `.js` 后缀。
- 禁止 `any`；不要留下未处理的 Promise；跨工具 / provider / CLI 边界的错误转换为
  `MossError`（`src/errors.ts`）并保留原始 cause；禁止 `catch (err: any)`。
- 所有子进程必须经 `src/utils/run-process.ts`（`runProcess` / `spawnProcess` /
  `runProcessSync`），工具执行路径禁用 `execFileSync` / `execSync`。
- 新工具必须声明 side-effect 元数据（readonly vs mutating 驱动审批）。
- 非流式 LLM provider 必须声明 `capabilities: { streaming: false }`。
- 面向用户的成功消息必须来自真实结果（probe / exit code / post-condition），不得是固定字符串。
- 凭据只从 `.env` 或环境变量读；不硬编码、不写日志、不传给外部服务。

## 常用命令

| 命令                                                                             | 用途                                                                                                                                                                 |
| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `npm run build`                                                                  | 清理并构建到 `dist/`                                                                                                                                                 |
| `npm run typecheck`                                                              | 全量类型检查                                                                                                                                                         |
| `npm run lint` / `lint:fix`                                                      | ESLint（0 warning）                                                                                                                                                  |
| `npm run test`                                                                   | 构建 + 运行 `test/*.spec.mjs`（面向 `dist/`）                                                                                                                        |
| `npm run test:filter -- --filter <name>`                                         | 只跑匹配的 spec（至少匹配 1 个，否则失败）                                                                                                                           |
| `npm run smoke`                                                                  | CLI 冒烟（版本 / 帮助 / PTY 启动）                                                                                                                                   |
| `npm run check`                                                                  | format:check + lint + typecheck                                                                                                                                      |
| `npm run verify`                                                                 | check + test + smoke，交付前必须绿                                                                                                                                   |
| `npm run bench [-- --task <id> --samples <n>]`                                   | agent 能力基准（`bench/tasks/`，DeepSeek 基准模型，结果落 `bench/results/`，不入库）                                                                                 |
| `npm run bench:ab -- <engine>`                                                   | hard 层 A/B 对照（`best-of-n` / `reasoning-high` / `model-routing`，`--samples <n>` 可调），输出默认开/关建议                                                        |
| `npm run bench:noise -- <label1> <label2> [...]`                                 | 同 SHA 重复跑聚合成噪声带（`bench/results/noise-band.json`）                                                                                                         |
| `npm run bench:swe -- [--samples N --concurrency K --label L --filter s --eval]` | SWE-bench Verified 100 实例锁子集（`bench/boards/swebench-instances.json`）：容器内 moss headless 产 patch + 官方 swebench harness 判分；密钥经 `MOSS_BENCH_API_KEY` |

## SDK 公共面与 semver（v0.13 起）

`src/index.ts` 的导出面（`dist/index.js` / `dist/index.d.ts`）是受 semver 保护的产品契约，由
`test/sdk-contract.spec.mjs` 快照锁定：

- **minor**：新增导出、既有导出行为向后兼容扩展 → 必须同步更新快照（重跑
  `node scratch/gen-sdk-contract-spec.mjs`）。
- **major（0.x 期间 = 明确的破坏性变更说明）**：删除 / 重命名导出、参数或行为破坏。
- 故意改公共面时快照更新与代码改动同一个 commit；spec 变红说明改动未被视为契约决策。
- `examples/` 下三个嵌入示例是契约的活文档，发版前必须实跑通过。
- **发布口径（2026-10-01 起）**：见 [`docs/release-policy.md`](docs/release-policy.md)——main 是滚动线，
  版本号表示**当前能力级别**；tag 只在 `npm run verify` 全绿 + `examples/` 实跑通过后打，
  tag 说明必须写清"跑了什么、没跑什么"；**不为从未验收的中间版本补打 tag**（v0.14.0–v0.20.0 永久不补）。

## 支持矩阵

| 维度     | 支持                                                                                                                                                                                                         | 验证方式                                 |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| Node     | ≥ 22.16.0（CI 钉 22.16.0 与 24 双档）                                                                                                                                                                        | CI `Test` 矩阵                           |
| 平台     | Linux / macOS / Windows（Windows 无 PTY smoke，其余全量）                                                                                                                                                    | CI `Test` 矩阵                           |
| provider | deepseek / qwen / openai / anthropic / openai-compatible                                                                                                                                                     | 单测 + 冒烟；真实 key 回归按需人工       |
| 交互面   | TTY：全屏 TUI（ink，v0.21 起 Mission Control：Task Navigator / Execution Canvas / Contextual Device / Composer，transcript 降级为 execution detail）；非 TTY / `MOSS_NO_TUI=1` / Windows：readline REPL 回退 | TUI spec 家族 + PTY smoke（macOS/Linux） |

不在表内的组合（其他 Node 大版本、其他 provider 协议）未验证，不支持。

## 结构导航

| 想改什么                                               | 去哪                                                                  |
| ------------------------------------------------------ | --------------------------------------------------------------------- |
| Agent loop / 轮次控制 / nudge                          | `src/core/loop/`                                                      |
| 达标驱动自主执行（/goal 验收门）                       | `src/core/loop/goal-loop.ts`                                          |
| MossAgent / 配置 / 事件                                | `src/core/agent/`                                                     |
| 工具注册与执行管线                                     | `src/tools/builtin.ts`、`src/core/tools/`                             |
| 内置工具实现                                           | `src/tools/*.ts`                                                      |
| 设备契约 / SSH 连接 / 观测解析                         | `src/contracts/device.ts`、`src/device/`、`src/tools/device-tools.ts` |
| 上下文 / 压缩 / token                                  | `src/context/`                                                        |
| LLM provider                                           | `src/provider/`                                                       |
| CLI / REPL / 命令                                      | `src/cli/`、`src/cli-main.ts`                                         |
| 全屏 TUI（v0.21 起 Mission Control 重做，动态 import） | `src/cli/tui/`（app/layout/panels/overlays 纯投影 + ink 外壳）        |
| MCP 客户端（v0.16 起）                                 | `src/core/mcp/`                                                       |
| 轻量 skills（v0.16 起）                                | `src/core/skills/`                                                    |
| 统一 Task Runtime 协议（状态机/事件/快照）             | `src/contracts/task-runtime.ts`                                       |
| 统一 Task Runtime 引擎/存储/裁决/能力发现              | `src/core/task/`（engine、store、verdict、capability、agent-turn）    |
| TUI 任务投影层（Mission Control 读路径）               | `src/core/task-runtime/`（artifacts + runtime 视图模型）              |
| 契约（prompt、soul、async-task）                       | `src/contracts/`                                                      |
| 错误 / 日志                                            | `src/errors.ts`、`src/logger.ts`                                      |

**分层规则**：依赖只能指向内层（contracts → errors/logger/utils/safety → provider/context/device → core → tools → cli）。ESLint `moss/boundary-*` 规则（`eslint.config.mjs`）强制执行——新增 import 前先看边界规则，不要申请豁免除非是新的合法端口。

## 设备子系统（robotics closed loop P0）

- 设备目标从 `MOSS_DEVICE_HOST/PORT/USER/KIND` + `MOSS_DEVICE_PASSWORD`（或 `MOSS_DEVICE_KEY`）解析，
  凭据只在 env/.env，绝不写入 DeviceTarget / 日志 / 子进程环境（`safeChildEnv` 会剥离）。
- `device_info/processes/resources/temperature/file_read/file_list` 为 readonly（可并行、自动重试）；
  `device_exec/device_file_write` 为 `device_mutation`，走审批。工具名已被 subagent scope、
  截断预算、loop-guard 等按保留名引用，改名等于破坏契约。
- 单测用 `test/helpers/in-process-ssh-device.mjs`（进程内 ssh2 服务器，真协议握手）；
  mock 只准用于单测，能力证明必须打真实设备（参照 `scratch/real-device-verify.mjs` 的做法）。

## 任务契约 / 证据 / 验收（robotics closed loop P0-1/2/8 + Task OS）

- 闭环的"完成"判定链：`task_define`（Goal + 可机检 acceptance criteria）→ `device_deploy` /
  `device_exec` / `run_tests` 执行 → `record_evidence`（Expected/Observed/Result 结构化证据）→
  `task_acceptance`（按 metric 匹配最新 evidence 评估；缺证据 = 未完成，latest-wins 支持修复后复测）。
- 工件持久化在工作区 `.moss/`：`tasks.jsonl`、`evidence.jsonl`、`deployments.jsonl`、
  `acceptance.jsonl`，加 Task OS 的 `task-events.jsonl`（生命周期时间线）、
  `task-failures.jsonl`、`task-repairs.jsonl`——这是任务可复现、可追踪、可分析的数据基础。
- **统一 Task Runtime（2026-09-30 Task OS 起）**：一切"完成机制"合一于一个事件驱动状态机
  （`contracts/task-runtime.ts`：draft→…→verifying→diagnosing→repairing→reverifying→accepted/failed；
  非法转移抛 `EXECUTION_STATE_INVALID`，PASS 只能来自 verdict provider，模型散文永远不是事件）。
  - 引擎 `core/task/task-engine.ts`：runTask/resumeTask 驱动 plan→execute→verify→repair→accept；
    goal-loop 与 robotics 验收统一为 VerdictProvider（命令裁决 > 契约裁决，`core/task/verdict.ts`）。
  - `task_define` 新建任务即入状态机（task*created→plan_ready）；`task_acceptance` 落
    verification_started/acceptance*\* 事件；`record_failure`/`record_repair`/`task_plan_update`
    是一等公民工具；`record_evidence`/`device_deploy` 落 info 事件到 timeline。
  - 四入口同一行为：`moss task run/resume/status/timeline`（headless，exit 0 仅当 accepted）、
    REPL `/task`、SDK（`runTask` 等，semver 保护）、TUI（读同一份 `.moss/` 工件）。
  - `runtime_state` 类工具不进审批（moss 自身 `.moss/` 记账）；危险类不变。
  - LoopScheduler `onAcceptanceVerdict` 把 /goal 与 MOSS_GOAL_VERIFY_LOOP 的裁决镜像进统一 runtime。
  - 能力发现：`core/task/capability.ts` 按 goal 匹配 skills/内置工具/MCP，注入 planning 上下文。
- Agent 不得以散文宣布任务成功；成功 = acceptance PASS + 背后 evidence。verify 子代理 scope 已带
  `record_evidence` / `task_acceptance`。
- 完成门（acceptance completion gate）在 MossAgent 内置：本 run 定义过 task_define 而无验收裁决时，
  终稿会被拦截一次并注入修正（跑 task_acceptance / 修复 / 诚实报 FAIL），之后放行——不无限劫持。
  runtime 已裁决过（engine 或上一 run 落过 accepted）时直接放行。
- Robotics benchmark：`bench/tasks/device-*` 设备任务用 `requiresEnv`（无 MOSS_DEVICE_HOST 时跳过不判负）
  与 `passEnv`（凭据从父进程透传，不进仓库）；真实样本：device-observe-evidence 与
  device-deploy-verify（tier:hard）均已 1/1 PASS（deepseek-flash 驱动真机全链）。
- Task OS benchmark：`bench/tasks/task-os-{a-coding,b-device,c-failure-repair}`；C 类是"故障→诊断→
  修复→复验→验收"全链证明（oracle 必须先 FAIL 再修复）；产品指标聚合
  `node scripts/task-os-metrics.mjs [run-dir...]`。

## 测试约定

- 测试在 `test/*.spec.mjs`，import 构建产物 `dist/`，由 `scripts/run-package-tests.mjs` 顺序执行。
- 新增 spec 文件名包含被测模块名，保证 `--filter` 可命中。
- Bug 修复需要"修复前失败、修复后通过"的回归测试。
- 动态 ESM import 一律 `pathToFileURL(...).href`（Windows 兼容）。

## 纪律

- 改代码前先做结构导航（符号/调用关系），读真实源码确认，不从文件名猜行为。
- 只做必须做的改动，匹配现有风格；修一个 bug 时 grep 同类形状。
- 行为验证优先于静态检查：逻辑改动后实际运行 CLI 验证一次。
- 报告真实命令与结果；没有观察到 post-condition 就不报成功。
