feat(coverage): 资产测试覆盖度(task_scope 范围 + fact 派生已测)
按 docs/任务覆盖度设计-最终版.md 实现(轻量版,粗估供 agent 参考):
- 新表 task_scope(覆盖度分母 + per-task 授权边界):CREATE TABLE IF NOT EXISTS 进
schema.sql,随 db.go 每次启动 Exec,旧库自动生效。
- db/task_scope.go:AddAutoScope(insertAssets 按资产类型保守入范围)、AddAgentScope
(add_task_scope 工具:company/root_domain/subdomain/ip/cidr)、ListTaskScope、
TaskCoverage(范围内资产中被 fact 节点锚定过的占比 + backlog 取样)。
- insertAssets 顶层循环按 worker 显式插入的资产类型自动入范围(source=auto);
side-effect 派生的资产不触发(钩子在 handler 顶层、派生在 db 层内部),范围不盲目扩大。
- add_task_scope 工具绑 planner,随 BuiltinToolSeeds 播种(新库/旧库皆 seed)。
- graph_overview 注入 coverage(denominator/tested/backlog_sample + 粗估提示)供 planner 参考。
- HTTP:GET /api/tasks/{id}/coverage、/scope;任务总览页覆盖度卡(含 backlog)。
- 修 toolcatalog_test(record_fact 绑定断言,早前 mainagent 加 recordFact 后未同步)。
验证:go build / vet / agent test / 前端 tsc 均通过。注:DB 层 SQL 尚未经 live Postgres 运行验证。
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
58e057a3f2
commit
aeadd0d48b
8 files changed
+499
-4
No files matched your search
@@ -248,6 +248,30 @@ DROP TRIGGER IF EXISTS trg_tasks_upd ON tasks;
|
||||
CREATE TRIGGER trg_tasks_upd BEFORE UPDATE ON tasks
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- 任务测试范围(资产覆盖度的分母 + 授权边界)。
|
||||
-- 自动填(source='auto'):insertAssets 顶层按 worker 显式插入的资产类型加保守范围
|
||||
-- (root_domain→root_domain,subdomain/service/endpoint→subdomain(host),ip→ip);
|
||||
-- side-effect 派生的资产不入范围(钩子在 handler 顶层,派生在 db 层内部)。
|
||||
-- agent 填(source='agent'):add_task_scope 加 company/root_domain/subdomain/ip。
|
||||
-- 覆盖度 = 匹配 active 行的 assets(分母)中,被 fact 节点锚定过的占比(分子)。
|
||||
CREATE TABLE IF NOT EXISTS task_scope (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
task_id BIGINT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('company','root_domain','subdomain','ip','cidr')),
|
||||
company_id BIGINT REFERENCES companies(id) ON DELETE CASCADE, -- kind='company'
|
||||
domain TEXT, -- root_domain / subdomain
|
||||
net CIDR, -- ip / cidr
|
||||
source TEXT NOT NULL DEFAULT 'auto' CHECK (source IN ('auto','agent','manual')),
|
||||
reason TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
-- 去重:同一 task 的同一条范围只存一次(自动填批量插入靠它幂等)。
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_task_scope ON task_scope(
|
||||
task_id, kind, COALESCE(domain,''), COALESCE(net::text,''), COALESCE(company_id,0));
|
||||
CREATE INDEX IF NOT EXISTS idx_ts_domain ON task_scope(domain) WHERE kind IN ('root_domain','subdomain');
|
||||
CREATE INDEX IF NOT EXISTS idx_ts_net ON task_scope USING GIST(net inet_ops) WHERE kind IN ('ip','cidr');
|
||||
CREATE INDEX IF NOT EXISTS idx_ts_company ON task_scope(company_id) WHERE kind = 'company';
|
||||
|
||||
-- =====================================================================
|
||||
-- E. Agents / 提示词模板 / 变量目录
|
||||
-- =====================================================================
|
||||
|
||||
Reference in new issue
Block a user