myxce/docs/left_scheduler_work.md

224 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Scheduler 剩余工作清单(left_scheduler_work)
- 状态:持续更新
- 日期:2026-08-13
- 来源:项目自带 MD 设计文档分析(.kiro/steering、.kiro/specs、docs/、CLAUDE.md)
本文汇总 scheduler 相关的一切剩余/未完成/已知损坏的工作,按优先级排序。每项标注来源文档与状态。
---
## 一、最紧急:当前影响集群的 bug
### 1. bug-1494 — 作业全部 PEND 不调度【已修复,2026-08-11】
- **状态**:已解决(两个子问题均已修复并集群验证)。
- **来源**:`CLAUDE.md`、`docs/Scheduler-Agent-设计文档.md` §10.2b
- **子问题一(已修复,commit 6928f74,bug-1510)**:scheduler 在 worker 未就绪(down/joining)时派发,controller 拒绝(`dispatch_a_job_ worker t1 status=0x10000 ep nil`)并回 `jobDispatchFail` 通知,但 scheduler 的 `sched_handle_notify` 无此 case(丢弃)→ 作业保持 RUN 视图永不重选 → 永久 PEND(worker 恢复也不派发)。**修复**:handler.c 加 `jobDispatchFail` case + `sched_requeue_pend_job()`(重置 PEND + 重新入 fcfs pendJobs)。
- **子问题二(已修复,commit 1a2bd3f)**:controller 重启 / worker 死亡后,scheduler 资源视图 slots=0 → 无法派发。**根因**:worker 死亡时 `mark_worker_unavail` 正确清零 slots=0;worker 重新 join(slots=8)时 controller 推送新 worker,但 scheduler 的 `sched_update_workers` → `sched_add_worker` 用 `key_add` 遇 EEXIST **丢弃新 worker**,scheduler 永久保留旧的 slots=0 → PEND 作业永不派发。**修复**:`sched_update_workers` 对已存在 worker **就地更新**(交换新 resvals/resInUse/status,释放旧对象),并 NULL-guard make_sched_worker。**集群验证**:scheduler 在 worker 死亡时启动(slots=0)→ worker 重新 join(slots=8)→ 之前卡住的 PEND 作业全部派发完成,无 ASAN。
- **子问题三(已修复,commit e4aaef4,bug-1512,2026-08-13)**:多 worker(t1/t2/t3)下作业重复派发/过派发,分布严重不均。**根因**:controller `handle_jobdispatch` 对**成功**派发也发 `jobDispatchFail` 通知(code=0 是成功 ack,else 分支 `notify_dispatch(jobid, 0)`);scheduler `sched_handle_notify` 无 code 判断(bug-1510 修复引入),把成功 ack 也当失败 → 每个成功派发的作业立即 re-PEND → 下次 session 重选 → 再派发,原实例继续跑 → 重复实例(3 worker 上 24 个作业跑出 38 个实例,堆积在 t1)。**修复**:`fail->code >= 0` 当成功 ack no-op 消费(作业已在 commit 标记 RUN),仅 `code < 0` 才 `sched_requeue_pend_job`。**集群验证**(新 scheduler 部署 t1):24 个 sleep-300 作业均匀 **8/8/8** 分布、零重复、全部 DONE;dispatchFail 日志 38→0;新单测 `test_handle_dispatch_fail_requeues_only_on_negative_code` + 原 15 测试全过。
- **关联**:scheduler 运行时重连(component-failover-adoption)仍为独立待办——scheduler 本身不会在 controller 重启后自动重连,需手动重启(但重连后 slots 恢复正常)。`sched_try_alloc_on_hosts` 只试 worker group member 0(resource.c FIXME)在 worker 名互异时休眠,同名冗余 worker 场景仍需处理。
- **临时恢复**:不再需要(worker 重新 join 即可恢复 slots)。
### 2. bug-1490 — apiserver control HTTP 500【已修复,2026-08-07】
- **状态**:已修复
- **来源**:`CLAUDE.md`、`Scheduler-Agent-设计文档.md` §10.2b
- **根因(两个叠加缺陷)**:
1. **array_idx 类型断言 panic → HTTP 500**:`validateJobControl`/`foundJob` 用 `jobinfo.Data["array_idx"].(int64)`,但 `StoreToOrderMaps` 产出的是 `int`(`JobInfo.ArrayIdx` 声明为 `int`)→ panic → Gin Recovery → HTTP 500 → 请求到不了 controller。
2. **jobctrl 联合判别符错误 → -EINVAL**:`backend.ControlJob` 把 `xce_jobctrl_t.action` 设成 `models.JOB_*`(1/2/3/8),但该字段是 capnp `JobControl` union 判别符(`JobControl_u_siginfo=0`/`JobControl_u_ckptoption=1`)→ controller `job_ctrl()` 走错分支(default)→ 每个动作都 -EINVAL。
- **修复**:`normalizeJobInt64`/`jobArrayIdx` 辅助函数 + `jobCtrlDiscriminant` 映射。单测 5 个(controllers 3 + backend 1 + 顺带修了 pre-existing 的 backend cgo 测试编译)。集群 E2E 验证:hold→PSUSP、release→PEND、cancel→EXIT,无 500 无 -EINVAL,全部 daemon 健康。
- **顺带修复**:`resolveExecUser` 被放在 `//go:build cgo` 的 convert.go 里导致 `make test`(CGO_ENABLED=0)下 backend 包编译失败——移到纯 Go 的 convert_pure.go。
### 3. bug-1489 / bug-1491 — 已修复(上下文)
- bug-1491 OrderMap 列格式解析修复(2026-08-01,httpclient.go)
- bug-1489 whitelist 缺 `/xce/v1/apikeys` 修复(2026-08-01,middleware/whitelist.go)
---
## 二、scheduler-controller-msg-gap:已实现但有已知缺陷
spec 声称 36/36 任务完成,但 re-audit(research.md)发现缺陷。来源:`.kiro/specs/scheduler-controller-msg-gap/research.md`。
| 项 | 严重度 | 描述 |
|----|--------|------|
| **G-8** | HIGH | `sched_update_existing_job` 是死代码。notify 驱动的作业更新走 bulk `sched_update_jobs()` 的 CREATE 路径(make_sched_job 新建),损坏/复制作业状态。**很可能与 bug-1494 相关**。Req 3 UB-3.1/3.2 未满足。 |
| **G-3** | MED | 5 个新 op 的 payload(UPDATE_QUEUE/UPDATE_RESOURCES/UPDATE_RESVALS_FULL/UPDATE_RESVALS/JOB_RUSAGE)在 `sched_pend_update_killer` 里 `break;` 从不释放——长驻 daemon 慢速泄漏。 |
| **G-5** | MED | `xce_sched_job_t` 无 rusage 字段。JOB_RUSAGE case 只调插件 hook 就丢 payload。UB-6.1 未满足。 |
| **G-4** | LOW | 即使修好 G-8 让 `sched_update_existing_job` 可达,它也只在作业上应用 state——priority/queue/resreq 未应用。 |
| **G-6** | TODO | 任务 9.2/9.3/9.4/9.6/9.7 勾了 `[x]` 但测试缺失/部分;9.5 测的是本地 stub 非真 schedobj.c。 |
| **G-7** | TODO | 文档漂移:design 说 `xce_sched_op_name` 在 lib/helper,实际是 scheduler.c 里 static `sched_op_name`。 |
| **R-3** | 休眠 | Req 1 处理器前瞻实现,但 controller 当前不推送 Data_data_resources/resvals 表给 scheduler——生产未触发。 |
---
## 三、核心调度引擎重构(scheduler-framework 家族:spec 有、零实现)
来源:`.kiro/specs/scheduler-framework/`、`scheduler-core/`、`scheduler-allocation/`、`scheduler-preemption/`(均只有 requirements/brief,无 design/tasks)。roadmap 显示 "Next: /kiro-spec-requirements scheduler-framework"。
### scheduler-core(Phase 1-3)
| 项 | 描述 |
|----|------|
| 可插拔 picker 接口 | 替代硬编码 `"xce_sched_fcfs"` 字符串,`job_pick_plugin` 字段 + config 加载 + 每 queue 覆盖。核心循环调 `picker->next_job()`。 |
| `builtin_fcfs` 默认实现 | MUST/SHOULD hook 全实现,私有 ordq_t 状态,排序同现状(跨 queue priority desc,队内 priority desc + queue_time asc)。 |
| 无回归保证 | HA soak 必须验证作业挑选顺序零偏差。 |
| core/driver 分离 | 提取 `xce_sched_core_t`,无 mode flag,虚拟时钟 `xce_core_now()`,决策回调。Phase 2。 |
| 模拟模式 | JSONL/.replay 重放 + 虚拟时钟 + snapshot/restore + 确定性重放 + `xceadmin scheduler record` + `--sim/--sim-verify/--interactive`。Phase 3。 |
| 等价保证 | "记录实跑 → 模拟重放 → 决策字节级一致"(AC 7.1)。 |
### scheduler-allocation
| 项 | 描述 |
|----|------|
| 惰性 plan 迭代器 | `xce_alloc_plan_iter_t`:init(resreq)/next()->plan/fini(),cancel-safe。 |
| 惰性 host 迭代器 | `xce_host_iter_t`:init(plan, workers)/next()->worker,复用现有 select 表达式求值器。 |
| parjob 组合分配 | 替换 stub `return 0`:1host×N、2hosts×ceil(N/2)、…、Nhosts×1。 |
| 会话级 resreq 缓存 | keyed on {minTasks,maxTasks,select_node_id,rusage_hash,user,queue,project},作业 ingest 时预计算。 |
| seqjob 重包 | 1host/1slot 走同一迭代器接口,验证抽象。 |
### scheduler-preemption
| 项 | 描述 |
|----|------|
| `XCE_DECISION_PREEMPT` | decision.h 新 opcode + `xce_preempt_decision_t`(victim_jobids, SIGSTP, preempting_jobid)。 |
| victim 选择策略 | 默认 `"lowest_priority_first"`,LSF 式跨 queue(preemptible_queues),最小足够 victim 集,安全护栏(不抢占同/高优先级、非抢占 queue)。 |
| SIGSTP 管线 | scheduler→controller→worker→SIGSTP 进程组,作业→JOB_SUSPENDED,复用 HOOK_DETAIL_JOB_STOP。每 queue `preemptible/preempt_policy/preemptible_queues` 字段。 |
| 核心循环集成 | 分配失败后、pending 前:can_preempt → 选 victim → 发 PREEMPT → preempting 作业下一轮再派(异步抢占)。 |
| 后续推迟项 | SIGKILL+requeue 升级、JOB_SUSPENDED resume 机制。 |
---
## 四、故障转移 / 重连
### component-failover-adoption(14 任务:部分完成,2026-08-14)
- **来源**:`.kiro/specs/component-failover-adoption/`
- **关键结论**:requirements.md Background 明确 "**scheduler 没有任何运行时重连/rejoin 逻辑**——连的 controller 死后,scheduler 无法切换到其他候选"。
- **✅ 已完成并集群验证(commit 2165b1a + 2bbe894)**:
- **worker 无限重试**(controller_connector.c `checking_connection`):去掉 5 次上限,无限重试直到重连(连接器线程专用,不阻塞硬件/进程监控线程)。实测:杀 controller 后 3 worker 全部存活并持续重试,controller 回来后自动 rejoin。**永久故障**:持续重试不放弃(正确);**HA**:`xcecd_join_cluster` 已按 --peers 候选列表迭代(best-effort)。
- **apiserver rejoin**(clib.go `StartHeartbeat` + `xce_backend_rejoin`):心跳从失败转成功时显式 rejoin(HostRole_apiserver),恢复 push 通知。实测:controller 重启后日志 `backend re-joined controller after reconnect`。
- **apiserver fail-fast 电路熔断(Req 4,commit 2bbe894)**:health.go 原子熔断 + `callBackend` 包 4 个写调用。degraded 时立即返回 `backend controller unavailable`,不调 lib;传输错误或 XCE NOMASTER/REDIRECT/NOT_READY/STANDBY 触发熔断;语义错误不触发。实测:杀 controller 后第 2 次提交 ~11ms 返回 fail-fast。7 单测。
- **✅ apiserver 自动恢复已修复(2026-08-14)**——两个根因:
1. **熔断恢复与心跳解耦**:breaker 可被 backend 写失败(如选举期 E_XCE_STANDBY -10014)触发,但 `StartHeartbeat` 只按「心跳失败→成功」转移恢复,`prevFailed` 为 false 时永不恢复 → 一直 degraded 直到手动重启。修复:`needsRejoinAfterHeartbeat` 在 `prevFailed.Swap(false) || IsDegraded()` 时恢复(heartbeat.go + 5 个单测)。
2. **transport reconnect 靠 lib 状态启发式不可靠**:30s 心跳的 fire-and-forget 只在 `ctx->state==ERR` 时重连;controller 重启的选举期超出 FAILOVER_CALL 重试预算后,ctx 停在 RUN 的半开连接,永不重连。修复:lib 新增 `xcecli_force_reconnect`(无视状态强制 rotate+recover),apiserver 加 2s `recoveryLoop`(degraded 时强制重连+rejoin)。实测:controller 完整死亡+重启后 apiserver 自动 `backend re-joined controller after reconnect`,无需手动重启,提交恢复。
- **✅ scheduler reconnect 已修复(2026-08-14 根因定位 + 集群验证)**:
- **关键结论**:所谓 "libxce reconnect heap corruption" **不是 lib 竞态**——是 scheduler rejoin 状态重同步的 3 个真实 bug(均在 config/dataset 重推路径)。
- **根因 1(group.c:234/247)**:`makeGroup` 刷新已有 group 的成员时 `FREEUP(m->u.name)` **raw-free 了共享 interned xstring**(`make_g_member` 用 `makeString` 建的是全局引用计数共享串,多个 group 共享同一指针)。正确释放是 `dereference()`(`group_killer` 就这么做)。ASAN 报 `bad-free`/`free(): invalid pointer` 即源于此。
- **根因 2(limit.c:76)**:`limit_update_config` 在 `key_add` 返回 -EEXIST(rejoin 重推,limit 名已存在)后调用 `kill_limit(limit)`,但 `xkvmgr_add` 的 vclear 已用 kvmgr datakiller(=kill_limit)释放该 limit → **double-free/UAF**(ASAN:56 字节 limit 的 READ of size 8)。修复:EEXIST 时 skip(re-push 幂等)。
- **根因 3(handler.c + scheduler.c)**:config push 在 vcpu 线程**内联**执行 `sched_init_config`(加 queues/plugin 队列),而 job 更新走 pend_updates 由主循环处理——**rejoin 重推时两者并发**,`fcfs_update_job` 的 `j->queue->name` 可能在 config 建好队列前取到 NULL → 主线程 SIGSEGV。修复:config push **改走 pend_updates**(`XCE_SCHED_OP_UPDATE_CONFIG`),`sched_update` 里 **config 请求先处理**(staging 队列)再处理 job/worker 更新,串行化顺序。
- **验证**:295 个 lib 单测全过(ASAN,含 2 个新 group 刷新回归测试);集群上 scheduler 连续 3 次 controller 重启全部存活并 `rejoin ok`;完整作业生命周期 `sleep 30` 提交→派发到 t1→**DONE**。
- **附带修复**:`libxce_deps` 缺 `librtti_dep`(group.c 编译不过)、`scheduler_deps` 缺 `ssl_dep`/`c_capnproto_dep`、unity include 只给 `<unity.h>` 路径——均已在 meson.build 修复。
- **apiserver 恢复缺口仍在(task #12)**:controller 完整死亡+重启后 apiserver 心跳恢复不可靠,电路熔断保持 degraded,需手动重启 apiserver(本次验证即遇到:job 提交报 `backend controller unavailable (reconnecting)`,重启 apiserver 后恢复)。
- 剩余任务(多 controller E2E + apiserver 自动恢复等)见 spec。
### P2.5
- **来源**:`product.md:35`、`docs/superpowers/plans/2026-05-07-p25-discovery.md`
- product.md 标 P2.5 "In progress";P2.5-6 描述 scheduler `--peers`/`--ca-cert` CLI 更新;P2.5-7(CGo bridge)推迟。是否全完成文档不确定。
- **注意**:P2.5 与 component-failover-adoption 用了两套技术路径(xce_connect_cluster 裸 endpoint vs xcecli_ctx_t/XCECLI_FAILOVER_CALL),文档未调和。
---
## 五、scheduler agent / MCP server(Phase 2-4)
来源:`docs/Scheduler-Agent-设计文档.md`
| 项 | 状态 | 描述 |
|----|------|------|
| Phase 2:SSE 事件流 | 计划 | apiserver SSE endpoint + EventBroker,schedulerclient `WatchJobs()`,mcp-server 接入。ADR-004 设计完成待实施。估 2-3 天。 |
| Phase 3:LSF adapter | 计划 | CLI 解析优先,Python Sidecar 后续。估 +1 月。 |
| Phase 4:Slurm + K8s | 计划 | slurmrestd + CLI fallback;client-go。估 +1 月。 |
| modify 工具 | 推迟 | apiserver 当前无 modify 端点(control 仅 kill/stop/resume/checkpoint),需新增后端端点。 |
| 未决决策 | 未解决 | LLM 模型选型(Claude API/自建/混合);多集群 URM 源识别;air-gapped LLM 访问。 |
---
## 六、roadmap / 加固项
| 项 | 状态 | 描述 |
|----|------|------|
| 调度决策过 commit barrier | 计划 | DISPATCH/PEND/PREEMPT 需过 majority commit barrier。多文档提及为独立加固项,从 scheduler-framework scope 推迟。 |
| worker-rejoin-resync | backlog | worker 重连重报运行/完成作业状态(bug-396 兜底)。依赖 ha-consistency-invariants。scheduler 间接受影响(恢复作业需调度状态核对)。 |
| entity-bearing snapshots | backlog | 解锁 config-upgrade-snapshot、基于快照的状态传输。影响 scheduler 模拟(snapshot/restore)。COW 机制存在但休眠。 |
| project-resource-ownership | 未来 spec | 层级项目树 + 资源配额,project-aware picker 插件,queue↔project 映射。核心循环零改动(只加新 picker)。 |
| perf-tuning-extraction / clusterconfig-schema-split | 计划 | 配置 schema 变更触及 scheduler 配置摄取。 |
| bulk job-array query/cancel | 推迟 | 依赖 job-array-single-wal-record。 |
---
## 七、文档空白(设计层面没人写过)
1. **调度决策 commit barrier 细节**——roadmap 只提了标题,无 spec/design。
2. **scheduler 状态在 controller failover 后如何同步**——全量重推?增量?文档沉默。roadmap:67 提到 lightweight rejoin re-attach(当前是 full-state rejoin,"大但罕见")。
3. **scheduler 模拟模式 vs controller WAL replay 关系**——failover 后 scheduler 从 controller WAL 重放还是收新状态推送?未讨论。
4. **core/driver 分离下的对象内存/生命周期**——三线程(picker/allocator/driver)async 生产者/消费者模型下借用指针的归属未细化。
5. **无 scheduler 专属 HA soak 测试**——多次提到 "HA soak regression" 但无 `/xce-test-ha` 变体专门跑 scheduler failover/reconnect。
6. **`src/scheduler/CLAUDE.md` 太薄**——约 25 行,无 spec 状态、无已知 bug 清单、无剩余工作节。建议补全(对照 `src/controller/CLAUDE.md`)。
7. **scheduler 与 raft/TLA+ 架构整合**——raft 系列落地后 scheduler 与 log/commit 模型的交互未讨论。
---
## 八、scheduler-agent(chatbot / AI 辅助)剩余工作
- 状态:持续更新
- 日期:2026-08-07
- 来源:`docs/Scheduler-Agent-设计文档.md`(v1.2,权威设计文档)、`src/docs/chatbot-verification.md`、`src/frontend/CLAUDE.md`、`CLAUDE.md`
- **注意**:feature 直接从设计文档实现,**未走 .kiro spec 流程**(`.kiro/specs/` 无 scheduler-agent/chatbot spec)。`/home/lchen/code/chatbot/` 是 XCE 完整镜像工作树,代码两份一致。
### 架构与现状
用户自然语言 → Claude Code(LLM)→ MCP stdio → mcp-server → schedulerclient → apiserver REST → controller(C 后端)。**不是独立聊天组件,而是自然语言调度管理 Agent 框架**。
**已完成**:
| Phase | 内容 | 状态 |
|-------|------|------|
| Phase 0 | 只读 MCP Server:6 读工具、schedulerclient、`mcp_readonly` 角色、API Key 认证 | ✅ 2026-07-26 |
| Phase 1 | 4 写工具(submit/cancel/hold/release)、`general_serial` 模板、`mcp_operator`、`dry_run` 审查 | ✅ 2026-08-01(代码);**2026-08-12 完整集群 E2E 验证通过**:submit→运行→DONE、cancel(kill)→EXIT、读接口全通。注意:job control 动作是 kill/stop/resume/checkpoint(schedulerclient 已正确映射) |
| Phase 2 | SSE 事件流(`/xce/v1/events` + EventBroker)+ `WatchJobs()` + 4 高级工具 | ✅ **2026-08-12 实施并集群验证**(见下)|
**Phase 2 落地明细(2026-08-12)**:
- **apiserver**:`/xce/v1/events` SSE endpoint + `backend.Broker`(EventBroker,DefaultHandler 发布 job.created/updated/deleted/finished);RBAC `event:view`(mcp_readonly/mcp_operator/cluster_admin);whitelist 加 `/xce/v1/events`。
- **schedulerclient**:`WatchJobs(ctx)` 订阅 SSE 流;**顺带修复** `ListJobs` 的 filter 参数——apiserver 用 `filter=queue_name:eq:...`(field:op:value),原 `queue_name`/`submit_user` 参数被 400 拒绝(影响带过滤的列表 + estimate_wait_time)。
- **mcp-server**:14 工具(10 原有 + `scheduler_wait_job`/`scheduler_analyze_failure`/`scheduler_suggest_resources`/`scheduler_estimate_wait_time`)。
- **人类可读 jobid(2026-08-13)**:apiserver 响应加 `job_id_human`/`human_id`(`cluster-apiserver-时间戳-序号`,如 `1-0-1786585485-0`),复用 `backend.FormatJobID`——MCP 原来只返回裸 64 位数字(`73930964699447296`),xce_test/xcecli 只认连字符格式,导致跨工具无法引用。架构原则:**apiserver 负责数据正确性,mcp-server 只读取透传**。
- **Claude Code 集成**:`.mcp.json` 注册 `xce-scheduler` server,key 用 `${XCE_API_KEY}` 环境变量(不硬编码提交);apiserver 重启后 key 失效需重新生成。
**注意**:apiserver 在 controller 重启后的自动恢复**已修复(2026-08-14,e505066)**——`needsRejoinAfterHeartbeat` 让熔断在 `IsDegraded()` 时恢复,lib `xcecli_force_reconnect` + apiserver 2s `recoveryLoop` 强制重连+rejoin(见第四节)。controller 完整死亡+重启后无需手动重启 apiserver。
代码:`src/frontend/mcp-server/`(14 工具)、`src/frontend/schedulerclient/`(~50 测试)、apiserver API Key + RBAC + SSE 支持。
### 1. 阻塞性 bug(影响 chatbot E2E 验证)
| Bug | 影响 |
|-----|------|
| **bug-1490** | ✅ 已修复(c90e63e)。MCP 写工具(submit/hold/release/cancel)集群 E2E 验证通过;`scheduler_get_job` 的 CompConditions 过滤 bug 也已修复(0572740)。另修了部署缺口:/opt/xce/config 缺 rbac.yaml 导致 mcp API key 全 403 |
| **bug-1494** | 作业全 PEND 不调度,Agent 提交流程无法完成。**已修复(2026-08-11)**:子问题一 dispatch-fail 重试(bug-1510)+ 子问题二 worker 重新 join 后 slots 不更新(见第一节) |
| **chatbot 过度建议** | ✅ 已缓解(3db216c):mcp-server 加 server instructions + 状态工具 report-only 描述,防止 LLM 把非 OK 状态当事故、主动给一堆排查建议 |
### 2. Phase 2:监控 + 纠错闭环(✅ 已实施 2026-08-12)
- **SSE 事件流**(ADR-004 已实施):apiserver `/xce/v1/events` + EventBroker、schedulerclient `WatchJobs()`、mcp-server 4 高级工具。t1 集群验证:SSE 流推送 PEND→RUN→DONE、WatchJobs 捕获完整生命周期、4 工具全部 live 工作。
- 高级工具:`scheduler_wait_job`、`scheduler_analyze_failure`、`scheduler_suggest_resources`、`scheduler_estimate_wait_time`(14 工具)
- Agent 工作流已打通:submit → wait_job → 取日志 → analyze(详见设计文档 §5.3)
### 3. Phase 3 / Phase 4:后端适配器(未开始)
- Phase 3:**LSF adapter**(CLI 解析优先,Python Sidecar 后续,估 +1 月)
- Phase 4:**Slurm**(slurmrestd)+ **K8s**(client-go)(估 +1 月)
### 4. 推迟 / 未决
- `scheduler_modify` 工具推迟——apiserver 当前无 modify 端点(control 仅 kill/stop/resume/checkpoint),需新增后端端点
- 3 个未决决策:LLM 模型选型(Claude API/自建/混合)、多集群 URM 来源识别、air-gapped LLM 访问
- **PEND reason 分类体系(进行中,2026-08-14 已实施 P0+P1 部分)**:见 `docs/pend-reason-investigation-design.md`。**已完成(commit 4e2ac86)**:
- **code 策略已定**:扩展 PREASON_* 枚举到 9 个(BAD_RESREQ/NO_RESOURCE/MATCH_FAIL/LIMIT_GLOBAL/LIMIT_HOST/QUEUE_CLOSED/QUEUE_DRAINING/TIME_WINDOW/HOST_UNAVAIL),capnp UInt32 无限制。
- **P0**:main_reason 修复(首个 detail code 设为主因,集群验证 PEND 作业 main_reason 非 0 + reason_name)+ limit 插件 attach(host 限额→LIMIT_HOST+limit 名,全局限额→LIMIT_GLOBAL+limit 名)。**集群验证**:PEND 作业 API 显示 `main_reason:3 main_reason_name:"match_fail"` + 每条 host/res reason 带 reason_name。
- **P1 部分**:队列状态(sched_queue_is_ready 非 stub,closed/inactive 队列不参选 + fcfs election attach QUEUE_CLOSED/DRAINING);worker 过滤(sched_try_alloc_on_host_ 跳过 UNAVAIL/CLOSED worker + HOST_UNAVAIL)。
- **剩余**:P1 时间窗(TIME_WINDOW——scheduler 需保留 dispatchwindow 配置 + 自写"now in window"评估,controller 不计算窗口状态);P2 依赖/license/保留/exclusive/fairshare(机制本身未实现);MCP `bjobs -p` 等价工具(未做)。
### 5. 设计层加固(文档已写、代码零实现)
- **Auto-pilot 模式**:用户显式授权范围内的自主行为
- **AI 操作审计日志**:每条操作记 `[timestamp] [user] [action] [params] [confirmed?]`
- **Golden test suite**:同一自然语言输入 → 同一工具调用序列的回归测试
---
## 建议优先级(2026-08-13 更新)
1. ~~**bug-1490**~~ ✅ 已修复(c90e63e),写工具 E2E 通过。
2. ~~**bug-1494**~~ ✅ 已修复(bug-1510 + bug-1511,2026-08-11),作业全 PEND 解决。
3. ~~**scheduler-agent Phase 2(SSE 事件流)**~~ ✅ 已实施并验证(2026-08-12)。
4. **msg-gap G-8/G-3/G-5**——scheduler-controller 消息缺陷,小而明确,能立即修。
5. **component-failover-adoption**(scheduler/worker/apiserver 重启后自动重连)——仍是最重要基础设施缺口;apiserver 的 rejoin 缺口已实测确认。
6. **scheduler-framework 重构**——大规划,建议等前几项稳定后再动。
7. **scheduler-agent 下一步**:Phase 3 LSF adapter(估 +1 月),或先跑通 agent 工作流真实试用 + 补齐 3 个未决决策(LLM 选型/多集群 URM/air-gapped)。