55 Commits

Author SHA1 Message Date
ymq
d9827c391b fix(orchestration): 元景三问题根治——task_title归位+问题通道统一冒泡+依赖启动策略+确认去重
问题1(部署早于开发启动):
- _check_orchestration_gaps 重构为结构化缺口(kind/fingerprint/task_id/fix_ids)
- 缺口不再只打日志:派发后当场回给PM + 持久化pipeline_pm_notices注入PM下回合上下文
- 新增 update_task_deps 原语:PM核实缺口后补依赖(修正是LLM决策,代码只查漏)

问题2(env补齐后waiting不唤醒):
- _bubble_deploy_env_missing 从自建人工任务死胡同迁移到统一问题通道(raise_problem)
- owner在待办回答→resolve_problem自动唤醒任务→QA注入agent prompt,信息真正交给LLM

问题3(task_title错位+重复确认):
- SDL_ROLES task_title 各归其位(需求分析/架构设计/脚手架开发/部署测试/功能测试)
- 确认去重:同迭代已确认且非回退重做→跳过重复确认直接派发
- _create_next_task 单例阶段幂等:requirement/design复用同迭代任意活跃任务

机制增强:
- 依赖启动策略 params.dep_policy: all(默认)/any/at_least{n},纯函数_eval_deps_policy
- init.py poller 手写依赖求值收敛到同一纯函数(消除两处语义漂移)
2026-08-27 22:52:27 +08:00
ymq
31eab89234 fix(orchestration): 多依赖门控 4 处放行漏洞 + description 继承 + 幂等 + 完备性查漏
【1. description 不再继承 + 用 PM 的 next_task_description】
_create_next_task 原实现 new_params={**params} 把上游 description 整个继承,导致
design 派生的「应用脚手架 develop」拿到需求任务的描述(产出需求规格说明书),于是它交付
文档、4 分钟 approved —— 一行代码没写却走完 develop,打破「应用级 develop approved =
编码完成」这个 deploy_test 门控前提,造成 deploy_test 在编码未完成时提前启动。
同时 PM 在 review_approve 里给出的 next_task_title/next_task_description 一直被丢弃
(1935 行采集、2239 行调用时没传) —— 现已接上,流转决策权归 LLM,代码只做兜底。

【2. 多依赖门控 4 处漏洞(用户重点要求)】
D1 _task_deps_satisfied 查「不在终态的依赖」,依赖ID不存在时查出0行 → 误判满足而放行
D2 PM 派发时未知依赖引用只警告、静默丢弃 → 任务以更少依赖落库 → 并行开跑
D3 len>=20 就当有效任务ID收下、不校验存在性,配合 D1 让门控完全失效
D4 依赖处于 cancelled/failed 时依赖方永久 submitted,死锁且无人知晓
修法:逐个比对依赖存在性与状态;missing/dead/self 一律阻塞并冒泡;PM 派发时依赖
无法解析的任务置 waiting 而非静默降级为并行。init.py 的 poller 同步同语义(两处实现
必须一致,否则一处拦住另一处放行)。

【3. 幂等】并发多任务同时 approved 会各自创建下一阶段任务 → 同迭代重复任务(历史上出现
过「同一迭代两个 design 任务」)。按 (迭代, 角色, 系统派生) 先查后建。

【4. 逃逸阀通则】依赖永不可达时冒泡 dependency_blocked 人工任务(按 task_id 去重),
消除静默死锁。对照:failed_poller 自动 pause 项目却无人通知,hrs7 因此卡近 1 小时。

【5. 完备性查漏 _check_orchestration_gaps】代码只查漏、不替 PM 决策:
G1 依赖自引用/成环(DFS 回边) → 必然死锁
G2 应用级 develop 未依赖未完成的模块级 develop → 正是本次故障成因
G3 设计清单 generated_modules 有模块无对应 develop 任务 → PM 漏派

逻辑验证:/tmp 两组离线用例共 30 例全过,并以可执行方式证实原实现 4 处放行漏洞。
2026-08-26 11:49:24 +08:00
ymq
1d743df4e3 feat(approval): 钉钉审批接成产线审批关卡
复用引擎既有 approval_gate 机制,不重造状态机:
- 新增 dingtalk_approval.py:注册 step_type='dingtalk_approval'(interactive),
  进入步骤自动向钉钉发起审批;注册 biz_type='pipeline_approval' 回调钩子,
  审批结果回来调 approval_approve/reject 推进产线(内部已 save_artifact+resume_task)
- executor._handle_interactive_step 加外部通知钩子(按 step_type meta.notifier 分派),
  并把 tenant_id 从 _execute_step 传下来(原 step_info 里无此字段,会永远取空)
- biz_id 编码 tenant_id:task_id:step_name,回调据此定位步骤
- 软依赖 dingdingflow:未加载时步骤仍挂起等人工审批,不推钉钉、不报错
- 通知失败只记日志不改步骤状态,避免外部系统故障导致步骤 FAILED
2026-08-25 18:22:03 +08:00
ymq
7404ab1ecd fix(gate): poller 派发门禁纳入需求/设计确认任务
根因:门禁 SQL 只认 general/bug_acceptance,漏了 requirement_confirmation/design_confirmation。
导致 PM 用 create_tasks 显式派发的下游任务绕过确认门禁被 poller 捞起执行
(实测 hrs7:设计确认 pending 期间 develop 任务已 running)。
在 poller 候选筛选层拦(agent + pm 两处),覆盖所有派发路径。
2026-08-25 14:16:27 +08:00
ymq
106a600c45 feat(llm-proxy): 内部 LLM 代理 + 短期 token,真 api_key 永不下发运行环境
运行环境(agent run_shell 子进程/bwrap 沙箱/远程目标机/被开发的 AI 应用)需要调 LLM 时,
不下发真实模型 key,改为签发短期 token(绑定 org_id+project_id+task_id,带过期/调用上限/可吊销),
运行环境用 token 当 api_key 调本平台 OpenAI 兼容代理端点;真 key 只在服务进程内存解析。

- create_llm_token / verify_llm_token / revoke_llm_token / revoke_task_tokens
- proxy_chat_completion: 按 token 绑定 org_id 解析真 key(机构隔离) + 转发 + 用量回填
- list_llm_tokens: 审计用,不返回 token 明文
2026-08-25 14:11:29 +08:00
ymq
b409f18929 feat(sdlc): requirement/design 审核通过后加 owner 人工确认门禁
- pm_review_run: requirement/design approved 后不再直接派发下一角色任务,而是发确认任务给 owner
- human_task_capability: 新增 confirm_stage_gate(确认通过→继续派发下一角色; 不确定→退回原角色重做)
- create_human_task 加 task_id 参数绑定原引擎任务
- has_blocking_human_task 纳入确认任务 pending 阻塞
- init.py 注册 confirm_stage_gate
2026-08-25 13:19:46 +08:00
ymq
e5ae2f1555 feat: check_task_owner/check_tenant_owner 任务操作 owner 校验(通用引擎任务放行) 2026-08-24 12:25:05 +08:00
ymq
d417772f42 feat: 项目owner+人类任务清单+bug验收+流转门禁
- check_project_owner: owner=created_by 统一校验
- human_task_capability: 派发/处理/QC/列表/计数/bug验收(复用pipeline_human_tasks)
- bug_flow: verified 分流(human报告→创建验收任务给报告人, agent→自动close)
- qc_review_run: human_task_qc 分支(检查对象=pipeline_human_tasks 结果)
- 流转门禁: agent/pm poller + start_next_iteration 检查未完成人类任务
- pipeline_human_tasks 加 project_id/iteration_id/bug_id/qc_status/qc_comment/title/description
2026-08-24 12:18:27 +08:00
ymq
434ab76d88 feat: Bug 生命周期独立循环(与任务循环平行的第二套逻辑)
用户定:任务和 bug 做成真正独立的两个事情,机制一样(poller+状态机)、
两套独立逻辑。之前把 bug 动作嵌在 PM 审核任务里(在任务里加 bug 动作)是错的。

改动:
1. 撤销 pm_review_run 里的 bug 动作(PM_SYSTEM_PROMPT bug 段 + tool_call bug 路由)
2. 新增 bug_flow.py:独立 bug 循环模块
   - _advance_bug_states:确定性流转(verified→close / fixed→派发复测 / confirmed→派发修复)
   - pm_bug_confirm_run:PM 独立确认 open bug(open→confirmed/rejected,LLM 判断)
   - bug_flow_poll_once:一轮完整 bug 循环入口
3. init.py 新增 _bug_poller(扫 sd_bugs 驱动状态机,与 role/pm/qc/failed 任务 poller 平行)

只处理进行中迭代(in_progress)的 bug。两循环唯一交互点:bug 循环在
confirmed/fixed 时创建任务(修复/复测)交给任务循环执行,任务执行时角色 agent
调 start_fix/fix_bug/verify_bug 反馈推进 bug 状态。
2026-08-24 08:28:16 +08:00
ymq
191d28547b fix: paused 生命周期三处修复——切迭代自动 resume + 三 poller 统一排除 paused
1. start_next_iteration 启动新迭代后自动 resume_project:旧迭代遗留的 paused
   (任务达上限触发 failed_poller 自动 pause)随任务作废消除,新迭代恢复 active,
   否则 PM poller 跳过 review 任务导致新迭代卡在 PM 审核(2026-08 实测卡 27 分钟)
2. agent poller / qc poller 也排除 paused 项目,与 PM poller 语义统一:
   paused = 完全暂停推进(不派发/不审查/不审核),消除「任务照常派发却卡审核」半吊子状态
2026-08-22 17:39:13 +08:00
ymq
f17f745ac6 fix(sdlc): pm_poller 队列饥饿——paused 项目僵尸 review 任务卡队头饿死 active 项目
根因:pm_poller SELECT state='review' AND claimed_by IS NULL ORDER BY created_at ASC LIMIT 5,
只取最老 5 个 review 任务,但暂停门控在 pm_review_run 认领后才检查。paused 项目(人事系统/人事系统1)
的 8 个 develop/deploy_test 僵尸任务永远占住队头,每 15s dispatch 后暂停门控 return idle、claimed_by 恒 NULL,
active 项目(人事项目2)的 requirement/design 任务排在后面对、永远进不了 LIMIT 5 窗口 → PM 无法推进项目。

修复(对齐 agent_poller 队列饥饿修复三件套):
1. SELECT 加 NOT EXISTS paused 项目过滤(暂停门控提前到筛选阶段)
2. LIMIT 5 → 200 容纳僵尸任务
3. 项目轮询 round-robin 保证项目间公平
2026-08-21 13:20:32 +08:00
ymq
ff2179be67 feat(poller): 每项目/租户并发上限 max_agents_per_project,防单项目占满全局并发
agent_poller 项目轮询基础上,新增每项目并发门控:
- 读 appbase params 表 max_agents_per_project(默认 4),改后下一轮(10s)立即生效
- 每轮查各项目 running 计数(GROUP BY tenant_id),达上限的项目跳过不派新任务
- 改小后不强制杀,超出的 running 任务自然跑完即「等其完成」语义
- 与全局 max_concurrent_agents(默认3→预置10) + 项目轮询配套,形成三级并发控制
2026-08-20 15:44:51 +08:00
ymq
77f5aa45dc fix(poller): 依赖门控提前到候选筛选 + 项目轮询,修复队列饥饿
agent_poller 原来 SELECT 后 [:avail] 截断只取队列头 avail 个任务,依赖门控却
在认领阶段(_claim_task)才检查——依赖未满足的僵尸 submitted 任务(created_at 最早)
永久占住队头,导致其他项目/新任务饿死(一项目卡死全平台瘫痪)。

改动:
1. 候选 SELECT 带上 depends_on,批量查依赖状态,排除依赖未满足的任务(终态=completed/approved)
2. 项目轮询(round-robin): 按 tenant_id 分组轮流取就绪任务,保证项目间公平
3. SELECT LIMIT 20->200 容纳僵尸任务;批量查依赖替代 N+1
2026-08-20 11:34:49 +08:00
ymq
1eba1c3f87 feat(worker): load_pipeline_service 按 PIPELINE_MODE 门控 poller 注册(web=仅HTTP无poller, worker=仅poller, all=默认) 2026-08-18 17:15:21 +08:00
ymq
31ba001482 refactor(init): 移除 _init_v2_tables 启动期建表/加列,schema 变更统一走部署期 create_tables.py 2026-08-18 16:02:19 +08:00
ymq
ab776d0c37 feat: 新增 QC 角色(质量门禁)+ 部署拆分为 deploy_test/deploy_prod + requirement 明确部署环境需求
- SDL_ROLES 6 环新链:requirement→design→develop→deploy_test→test→deploy_prod,新增 agent.qc
- 状态机新增 qc_review:角色交付→QC 合规/质量检查→PM 验收→下一环
- qc_review_run + qc poller;不合规退回重做
- requirement 职责增加部署环境需求明确
2026-08-18 15:16:43 +08:00
ymq
b819a665f6 fix: poller 加 watchdog(wait_for 60s 超时),防连接池/MDL 锁卡死导致停摆
agent_poller 和 pm_poller 的 poll_loop 改为 _poll_once + asyncio.wait_for(timeout=60)
包裹,每轮 poll 卡住超过 60s 就跳过本轮继续,不再因连接池耗尽/MDL 锁等待
(lock_wait_timeout 默认 24h)而永久停摆(2026-08 生产事故:poller 停摆 15.7h)。
2026-08-18 11:14:23 +08:00
ymq
0b75f10731 Revert "fix: 心跳超时从 20 分钟回收重跑改为 10 分钟强制结束标注超时失败"
This reverts commit feb88aca023fdf0859fa1f8dae589acbd14c771c.
2026-08-18 10:59:51 +08:00
ymq
feb88aca02 fix: 心跳超时从 20 分钟回收重跑改为 10 分钟强制结束标注超时失败
running 任务 updated_at 超 10 分钟未更新(进程崩溃/协程挂起僵尸),原逻辑回收回
submitted 重跑,改为 state=failed + last_error=心跳超时。中文 last_error 让
_classify_failure 判 fault 不自动重跑,failed_poller 报故障通知用户。
2026-08-18 10:53:13 +08:00
ymq
3687270ca7 feat(task-capability): 任务状态机语义化迁移能力 + 通用审计原语
- task_capability.py: claim/submit/approve/reject/complete/mark_failed/retry/suspend/revive/set_task_state
  CAS 原子迁移(防并发/越权覆盖) + tenant 隔离 + record_audit 审计
  定位=状态机语义化操作层,CRUD 复用 storage.py,不遮蔽 storage/executor 同名函数
- audit.py: record_audit append-only 通用审计原语(支持 sor 复用避免嵌套连接)
- models/audit_log.json: 审计日志表(append-only, tenant 隔离)
- init.py: 注册 task_* + record_audit 到 ServerEnv
2026-08-16 23:39:05 +08:00
ymq
6707cabedc refactor(team-communication): 问题冒泡改为显式路由,规范移交 skill
规范(团队角色/问题类型/冒泡路径)移交 team-communication skill,由 LLM 读 skill 决策;
系统只固化通用问题工具,不读配置表、不存路径快照:
- communication.py: raise/resolve/escalate/list_for 显式路由,
  escalate 显式传 next_handler;current_handler_role/agentid 两列确定性过滤
- questions.py: 向后兼容层适配
- agent_loop.py: need_info/review_reject/fault_report 显式 first_handler_role
- sdlc_ability.py: escalate_question 显式转 customer
- models: 去 escalation_path/pos,加 current_handler_role/agentid
2026-08-16 22:08:00 +08:00
ymq
4f2c6da6cf feat(team-communication): 通用问题冒泡引擎(多agent感知)
- communication.py: raise/resolve/escalate/list_for,问题类型→冒泡路径,处理方=role+agentid
- questions.py: 向后兼容层,委托 communication
- agent_loop.py: 角色提问(need_info)/PM退回(review_reject)/故障(fault_report)走 raise_problem;
  _build_qna_section 按 handler 路由注入;PM approved 只答结 review_reject
- sdlc_ability.py: list_questions/answer_question/escalate_question 按 handler 路由
- models: pipeline_agent_questions 加 from_agentid/problem_type/escalation_path/escalation_pos
2026-08-16 21:25:39 +08:00
ymq
2cdd3cb986 feat: gateway服务层(统一消息入口+会话生命周期+通道注册)+AgentIO适配走gateway 2026-08-15 10:02:54 +08:00
ymq
82b0944424 feat: 全局并发agent数限制(max_concurrent_agents params表)+机构工作目录workspace_base动态化(_is_safe_workdir读params表) 2026-08-15 10:00:03 +08:00
ymq
14a42aac7b fix: SELECT-only 事务显式 COMMIT,修复 MDL 元数据锁泄漏阻塞 DDL
failed poller / handle_failed_task 的 SELECT-only 事务未提交,连接回池后仍持有元数据锁,
导致 ALTER TABLE ADD COLUMN 卡死并阻塞整表。改为 SELECT 后显式 COMMIT 释放锁。
2026-08-15 01:09:05 +08:00
ymq
aa0dcc9c04 feat: 失败任务处理第二层——failed poller 自动重跑(最多3次)+报故障给用户
- pipeline_tasks 加 retry_count/last_error 列(启动时幂等 DDL)
- role/pm agent 失败时记录 last_error(含异常类型)
- handle_failed_task: 瞬时错误(超时/连接/5xx/429)重跑,永久错误或重试>=3次报故障(建问题通知用户,任务置 waiting)
- init.py: 新增 failed poller 每60s扫描 failed 任务,role任务由pm上报、pm任务由cockpit上报
2026-08-15 00:57:05 +08:00
ymq
8c0d63efb1 fix: LLM 调用加瞬时错误重试(3次) + 超时 180s→300s(connect 30s);心跳回收阈值 10→20 分钟防误杀慢任务
- llm_bridge: 抽出 _post_chat_completion,超时/连接错误/429/5xx 重试3次退避;total=300 connect=30
- init.py: 僵尸回收阈值对齐 LLM 最坏单轮时长(3×300s≈15min),20分钟
- agent_loop_v2: diagnose 心跳超时判定 10→20 分钟
2026-08-15 00:46:30 +08:00
ymq
bc5ce2f06d fix: 任务链卡死根治 — 心跳+stale回收+claimed_by僵尸锁清除
- questions.py: agent_ask/answer_question 置 waiting/submitted 时清 claimed_by,否则 poll 器永不重新认领
- agent_loop_v2.py: _t_answer_question 回答后恢复任务 waiting→submitted(此前只标记问题已答,任务永久卡 waiting)
- agent_loop.py: _claim_task 加 claimed_by IS NULL 原子认领 + updated_at 心跳;role/pm 循环心跳 COMMIT;pm 认领保持 review 态
- init.py: role poller 回收僵尸 running 任务、pm poller 回收僵尸 review 任务(心跳超时 10 分钟)
2026-08-15 00:11:36 +08:00
ymq
d2f3caf8a7 refactor: workspace 路径解析收敛到 workspace.py,dspy 消除重复
- workspace.py 加 get_workspace_dir/get_workspace_base + load_workspace 注册到 ServerEnv
- 8 个 workspace dspy 内联重复的'读 workspace_base + 查 project 算 ws_dir'改为调 get_workspace_dir
- _t_create_project 复用 get_workspace_base(删掉死代码 _get_param)
- workspace.py 从 untracked 变为已跟踪提交
2026-08-14 18:07:33 +08:00
ymq
92ee88d1f4 refactor: 审计逻辑迁移到独立模块 app_audit
- 移除 pipeline_service/audit_service.py(迁移到 app_audit)
- __init__.py 移除 audit import,init.py 移除 sd_audit_logs/owner.audit DDL
2026-08-14 12:20:36 +08:00
ymq
eaaf5fad26 feat: 审计日志全局模块(append-only,查看/备份/删除仅 owner.audit)
- audit_service.py: audit_log 写入 + is_audit_role + list/backup/delete
- sd_audit_logs 表 + owner.audit 角色 DDL
- 审计独立性:owner.superuser 也无权查看审计日志
2026-08-14 12:10:57 +08:00
ymq
262d678e2a feat: 工作环境管理(沙箱本地/远程切换 + 目录迁移)
- work_env.py: get/set_work_env(用户/机构维度,缺省local)、rsync目录迁移、远程SSH+bwrap沙箱、远程bwrap部署
- run_in_work_env: 按mode分发本地bwrap/远程SSH+bwrap
- sd_work_envs 表 DDL
2026-08-14 11:12:54 +08:00
ymq
08ae248c2a feat: 应用部署主机逻辑账号系统(零root+bwrap沙箱)
- deploy_account.py: 逻辑账号(ag_前缀)创建/删除/列表,bwrap沙箱执行,免密目录读写
- 零root:不建真实Linux账号,逻辑隔离目录 + unprivileged user namespace
- init.py: sd_deploy_accounts 表 DDL 自动初始化
2026-08-13 17:57:09 +08:00
ymq
ea9b0f2ae4 feat: auto-add agent_config columns to DB 2026-08-10 17:01:18 +08:00
ymq
cd9208cbf4 feat: auto-create pipeline_user_memory table on startup 2026-08-10 11:10:53 +08:00
ymq
2d6709ee33 feat: Agent v2 执行引擎 - AgentExecutor with compression/memory/skills 2026-08-10 11:06:42 +08:00
ymq
eb889d8694 fix: poller dedup dispatched tasks + error handling to prevent lock pile-up 2026-08-08 13:43:19 +08:00
ymq
74ce3339d2 v3.4.0: agents produce real code files + git push + PM clones repos
- All agents can write code files via 'files' array in output JSON
- Auto git commit+push after code file creation
- PM agent clones project repos on first review
- PM review shows repository state
- shell_exec now allows ~/pipeline_ws
- Role-specific prompts guide code/file output
2026-08-08 11:42:49 +08:00
ymq
0270922205 v3.3.0: PM agent + task chain + workspace + file output 2026-08-08 10:36:04 +08:00
48f5048df8 fix: shell_exec 目录不存在时回落可写基础目录 2026-08-05 18:01:17 +08:00
1f848e0760 fix: _resolve_workdir 先检查父目录存在+可写再 mkdir 2026-08-05 17:58:53 +08:00
222bdbcd3d fix: _resolve_workdir → /tmp 回落(apitest无/d写权限) 2026-08-05 17:58:00 +08:00
5a7104aa5d feat(v3.2.1): shell_exec + skill_import_git — 主agent devops能力
- shell_exec: 安全子进程执行(沙箱在 /d/pipeline/workspaces 下,60s超时)
- skill_import_git: git clone + skills目录扫描,返回技能列表
- 注册到 env,cockpit_chat 可通过 dspy 直接调用
2026-08-05 17:56:22 +08:00
ee9ab066fc fix: on_startup handler spawn 后台任务后立即返回(不阻塞 aiohttp 启动) 2026-08-05 17:31:27 +08:00
99cc19f9aa fix: _role_poller 接受 app 参数(aiohttp on_startup 信号) 2026-08-05 17:28:23 +08:00
0bd9609532 fix: add_startup 传函数引用(非协程对象) 2026-08-05 17:27:24 +08:00
4c0b349718 feat: 后台轮询器 — add_startup 自动执行 role_task
- _role_poller 每10秒扫描 pipeline_tasks 中 submitted 的 role_task
- 逐条 dispatch 给对应角色 agent_loop 异步执行
- 修复 agent_loop 中 agent_ask 导入为相对导入
2026-08-05 17:20:26 +08:00
4cb406003e feat(v3.2.0): 主agent+角色agent架构 — role任务认领/问题回路
- pipeline_tasks 增加 role/claimed_by 字段+索引(存量库需ALTER)
- agent_loop 重写为角色循环:原子认领(role匹配+令牌校验)→LLM执行→交付/need_info提问
- 角色别名归一化(developer→develop等),ROLE_PROMPT改replace防花括号崩溃
- questions.py 新增问题回路:agent_ask/answer_question/forward_question/list_questions
- init.py 注册 pipeline_role_submit 与问题回路 env 接口
2026-08-05 12:58:52 +08:00
59e56b5e9c feat: Phase 2+4 — agent_loop engine + project agent config 2026-08-02 14:59:32 +08:00
0423fa3c99 refactor: add intent_classifier.py, register in init.py, LLM bridge shared 2026-08-02 00:00:20 +08:00