feat(task): 资产覆盖度功能可按任务开关

创建任务时新增「资产覆盖度功能」开关(默认开)。关闭后:
- 不计算/展示测试覆盖度,总览卡片隐藏、覆盖度 API 返回 enabled:false
- 态势图仅展示资产不显示测试进度(B1:抹平 tested、去已测统计与图例)
- 不再自动累积 task_scope(source=auto)
- planner/mainagent 的 add_task_scope、list_untested_assets 从工具列表剔除
- graph_overview 丢弃 coverage 度量块、保留 scope 字段(防上下文污染)

company 关联(task_scope kind=company)与此开关无关,永不受影响:
insertTaskCompanies 不 gate,TaskCompanyIDs 照常读回,scope 字段照常喂给 agent。

DB:tasks 加 coverage_enabled 列(schema.sql + ALTER ADD COLUMN IF NOT EXISTS
补旧库,默认 true 保持存量任务原行为)。

Claude-Session: https://claude.ai/code/session_01Jm87Gr5fq5aso6SfLyguhx
This commit is contained in:
Autumn-27 committed 2026-08-22 10:03:18 -04:00
1 parent 5126ac4592
commit eb3f278711
18 files changed
+179 -43

No files matched your search

+15
View File
@@ -248,6 +248,7 @@ type CoverageByType struct {
// NOT a precise metric. Denominator = assets matching any active task_scope row;
// Tested = those anchored to at least one fact node in the exploration.
type Coverage struct {
Enabled bool `json:"enabled"` // 资产覆盖度功能是否开启;false 时其余字段为零值
ScopeRows int `json:"scope_rows"` // 0 → 范围未锚定
Denominator int `json:"denominator"` // 范围内资产数
Tested int `json:"tested"` // 已测(约)
@@ -255,6 +256,20 @@ type Coverage struct {
ByType []CoverageByType `json:"by_type"` // 按资产类型的 总数/已测
}
// CoverageEnabled reports whether a task has the asset-coverage feature turned on
// (tasks.coverage_enabled). Missing row / error → true (fail open to the default),
// so unknown/legacy tasks keep the historical behavior. taskID<=0 → true.
func (s *AssetStore) CoverageEnabled(taskID int64) bool {
if taskID <= 0 {
return true
}
var enabled bool
if err := s.db.QueryRow(`SELECT COALESCE(coverage_enabled,true) FROM tasks WHERE id=$1`, taskID).Scan(&enabled); err != nil {
return true
}
return enabled
}
// task_scope→assets match predicate, reused by the count / by-type / untested queries. $1=taskID.
const covTargetCTE = `
target AS (