fix: stop blocking Artificer on task reference formats
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
Pipelines as Code CI / platform-infra-gitea-nc01- Success
Pipelines as Code CI / unidesk-host- Success

This commit is contained in:
pikastech
2026-07-19 19:44:14 +02:00
parent 25f9ada20c
commit e4f5ede8d7
5 changed files with 16 additions and 13 deletions
+5
View File
@@ -12,6 +12,11 @@ description: UniDesk 主代理调度子代理的必读技能。用户提到子
- 涉及 PK01 的派单默认只允许只读调查:
- 只有用户在当前请求中明确要求修改 PK01,子 issue、TaskTree Task 或代理 prompt 才能授权修改其版本、配置、Secret 绑定、边缘路由、容器或运行面;
- 泛化的修复、恢复、部署和排障目标不构成 PK01 变更授权。
- 派单元数据不得使用白名单式阻塞校验:
- issue、TaskTree、遗留 MDTODO、标题、仓库标签和其他治理字段只作为关联与可见性元数据;
- CLI 可以记录缺失、未知或非推荐格式并输出非阻塞 warning,但不得按允许值、前缀、正则或枚举白名单拒绝核心派单;
- 只有用户明确要求某个白名单成为门禁,或认证、权限、目标唯一性与不可逆损害预防确实要求时,才允许阻断;
- 新增白名单式阻塞前必须取得用户对该具体门禁的明确授权,禁止以治理便利、历史格式或测试断言自行扩大。
- 主代理与子代理必须按用户明确目标控制实现范围:
- 未经用户明确要求,禁止新增或扩展通用合同、租约、安全机制、围栏及其配套门禁;
- 既有权限、Secret 脱敏、不可逆操作和损害预防边界继续生效,本规则不授权绕过既有安全底线;
+5
View File
@@ -35,6 +35,11 @@ The following practices are not acceptable as the long-term or hidden source of
- 只有业务数据本身无法解释、违反安全/权限边界或会造成不可逆损害时才允许拒绝,并返回与具体业务字段相关的 typed error
- 禁止把版本、commit 或契约漂移包装成 `schema-invalid``503` 或其他用户阻塞错误;
- CI/CD、status 和 observability 可以报告版本漂移,但只能作为修复提示,不能压过真实业务成功证据。
- 白名单式校验默认不得阻塞核心业务:
- 未经用户对具体门禁的明确要求,不得按名称、前缀、正则、枚举、标签、issue、TaskTree、遗留 MDTODO 或其他治理元数据白名单拒绝请求、派单、发布或验收;
- 既有白名单校验应降级为结构化 warning,并保留实际值、建议格式和继续执行结果;
- 认证、权限、目标无法唯一确定和不可逆损害预防仍可阻断,但不得伪装成治理白名单;
- 新增阻塞白名单必须说明保护的真实损害、授权来源、作用范围和退出条件,不能只因实现方便或历史测试存在而加入。
- Hand editing D601 runtime files, k3s manifests, ConfigMaps, Deployments or container env values and treating the live result as source of truth.
- Rebuilding backend-core, frontend, k3sctl-adapter or other managed services from a dirty worktree on the master server, D601 or an operator machine.
+2 -2
View File
@@ -222,7 +222,7 @@ describe("Artificer Target one-command dispatch", () => {
"--target-workspace", "relative/workspace",
"--repo", "pikasTech/unidesk",
"--ref", "fix/path-check",
"--mdtodo-id", "R5.2",
"--mdtodo-id", "tt_example-tasktree-id",
])).toThrow("--target-workspace 必须是 Target 上的绝对路径");
const request = targetTaskRequestFromArgs([
@@ -231,7 +231,7 @@ describe("Artificer Target one-command dispatch", () => {
"--target-workspace", "/definitely/missing/agentrun-workspace",
"--repo", "pikasTech/unidesk",
"--ref", "fix/path-check",
"--mdtodo-id", "R5.2",
"--mdtodo-id", "tt_example-tasktree-id",
]);
if (request === null) throw new Error("expected Target request");
expect(() => preflightTargetTask(request)).toThrow("Target 工作区不存在或不是目录");
+3 -3
View File
@@ -69,7 +69,7 @@ export function agentRunHelp(): unknown {
"bun scripts/cli.ts agentrun get attempts --task <taskId> --limit 20",
"bun scripts/cli.ts agentrun dispatch task/<taskId>",
"bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --prompt-stdin --idempotency-key <key>",
"bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target <Target> --target-workspace <absolute-task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <R6.3> --prompt-stdin [--dry-run]",
"bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target <Target> --target-workspace <absolute-task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <opaque-task-reference> --prompt-stdin [--dry-run]",
"bun scripts/cli.ts agentrun apply -f - --dry-run",
"bun scripts/cli.ts agentrun send session/<sessionId> --aipod Artificer --prompt-stdin",
"bun scripts/cli.ts agentrun explain task",
@@ -318,7 +318,7 @@ export function agentRunHelpText(args: string[]): string {
return "Usage: bun scripts/cli.ts agentrun dispatch task/<taskId>";
}
if (verb === "create") {
return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --title <中文短标题> --target <Target> --target-workspace <task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <R6.3> --prompt-stdin [--idempotency-key <key>] [--dry-run]";
return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --title <中文短标题> --target <Target> --target-workspace <task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <opaque-task-reference> --prompt-stdin [--idempotency-key <key>] [--dry-run]";
}
if (verb === "apply") {
return "Usage: bun scripts/cli.ts agentrun apply -f task.yaml|json|- [--dry-run]\nTask manifests use kind: Task and spec: <AgentRun task payload>.";
@@ -413,7 +413,7 @@ export function agentRunHelpText(args: string[]): string {
" bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
" bun scripts/cli.ts agentrun retry task/<taskId> --idempotency-key <key> --reason <text> --dry-run",
" bun scripts/cli.ts agentrun get attempts --task <taskId> --limit 20",
" bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target <Target> --target-workspace <task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <R6.3> --prompt-stdin",
" bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target <Target> --target-workspace <task-worktree> --repo <owner/repo> --ref <branch> --mdtodo-id <opaque-task-reference> --prompt-stdin",
"",
"Machine/debug output:",
" -o json|yaml emits a stable UniDesk resource object without the global JSON envelope.",
+1 -8
View File
@@ -84,7 +84,7 @@ export function targetTaskRequestFromArgs(args: string[]): AgentRunTargetTaskReq
targetWorkspace: validateTargetWorkspace(raw.targetWorkspace as string),
repository: normalizeRepository(raw.repository as string),
ref: validateRef(raw.ref as string),
mdtodoId: validateMdtodoId(raw.mdtodoId as string),
mdtodoId: raw.mdtodoId as string,
};
}
@@ -345,13 +345,6 @@ function validateRef(value: string): string {
return value;
}
function validateMdtodoId(value: string): string {
if (!/^R[1-9][0-9]*(?:\.[1-9][0-9]*)*$/u.test(value)) {
throw new AgentRunTargetTaskPreflightError("target-context", "--mdtodo-id 必须使用 R1 或 R1.1 这类 MDTODO ID");
}
return value;
}
function sha256(value: string): string {
return `sha256:${sha256Hex(value)}`;
}