feat(ack): add project delivery workflow
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://git.yumee.top/laily/skills/skills/ack/templates/delivery.schema.json",
|
||||
"title": "ACK project delivery contract",
|
||||
"description": "docs/ack/delivery.yaml 的权威结构;语义规则由 scripts/validate_delivery.py 补充。",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"version",
|
||||
"project",
|
||||
"enabled",
|
||||
"defaultProfile",
|
||||
"entrypoints",
|
||||
"artifacts",
|
||||
"destinations",
|
||||
"environments",
|
||||
"profiles"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"version": { "type": "integer", "const": 1 },
|
||||
"updatedAt": { "type": "string" },
|
||||
"project": {
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": { "type": "string", "minLength": 1, "pattern": "\\S" }
|
||||
}
|
||||
},
|
||||
"enabled": { "type": "boolean" },
|
||||
"defaultProfile": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[a-z][a-z0-9-]{0,63}$"
|
||||
},
|
||||
"entrypoints": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/definitions/id" },
|
||||
"additionalProperties": { "$ref": "#/definitions/entrypoint" }
|
||||
},
|
||||
"artifacts": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/definitions/id" },
|
||||
"additionalProperties": { "$ref": "#/definitions/artifact" }
|
||||
},
|
||||
"destinations": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/definitions/id" },
|
||||
"additionalProperties": { "$ref": "#/definitions/destination" }
|
||||
},
|
||||
"environments": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/definitions/id" },
|
||||
"additionalProperties": { "$ref": "#/definitions/environment" }
|
||||
},
|
||||
"profiles": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/definitions/id" },
|
||||
"additionalProperties": { "$ref": "#/definitions/profile" }
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9-]{0,63}$"
|
||||
},
|
||||
"relativePath": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[A-Za-z0-9._/*?+-]+$"
|
||||
},
|
||||
"stringList": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"secretName": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"kind",
|
||||
"args",
|
||||
"requiredSecrets",
|
||||
"workingDirectory",
|
||||
"timeoutSeconds"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["make", "just", "task", "dagger", "script"]
|
||||
},
|
||||
"target": { "type": "string", "minLength": 1 },
|
||||
"function": { "type": "string", "minLength": 1 },
|
||||
"path": { "$ref": "#/definitions/relativePath" },
|
||||
"args": { "$ref": "#/definitions/stringList" },
|
||||
"requiredSecrets": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": { "$ref": "#/definitions/secretName" }
|
||||
},
|
||||
"workingDirectory": { "$ref": "#/definitions/relativePath" },
|
||||
"timeoutSeconds": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 86400
|
||||
}
|
||||
}
|
||||
},
|
||||
"artifact": {
|
||||
"type": "object",
|
||||
"required": ["type", "build"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": { "type": "string", "enum": ["deb", "oci-image", "file"] },
|
||||
"build": { "$ref": "#/definitions/id" },
|
||||
"outputs": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": { "$ref": "#/definitions/relativePath" }
|
||||
},
|
||||
"image": { "type": "string", "minLength": 1 },
|
||||
"platforms": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": { "type": "string", "pattern": "^[a-z0-9]+/[A-Za-z0-9._-]+$" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"type": "object",
|
||||
"required": ["type", "channel"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["apt-repository", "oci-registry", "ci-artifact"]
|
||||
},
|
||||
"channel": {
|
||||
"type": "string",
|
||||
"enum": ["preview", "staging", "stable"]
|
||||
},
|
||||
"registry": { "type": "string", "minLength": 1 },
|
||||
"repository": { "type": "string", "minLength": 1 },
|
||||
"endpoint": { "type": "string", "minLength": 1 },
|
||||
"artifactName": { "type": "string", "minLength": 1 },
|
||||
"upload": { "$ref": "#/definitions/id" }
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"classification",
|
||||
"target",
|
||||
"deploy",
|
||||
"healthCheck",
|
||||
"mutex"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["ssh-host", "docker-compose", "kubernetes", "custom"]
|
||||
},
|
||||
"classification": {
|
||||
"type": "string",
|
||||
"enum": ["development", "staging", "production"]
|
||||
},
|
||||
"target": { "type": "string", "minLength": 1 },
|
||||
"deploy": { "$ref": "#/definitions/id" },
|
||||
"healthCheck": { "$ref": "#/definitions/id" },
|
||||
"rollback": { "$ref": "#/definitions/id" },
|
||||
"mutex": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"step": {
|
||||
"type": "object",
|
||||
"required": ["id", "action"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "$ref": "#/definitions/id" },
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"verify",
|
||||
"pull-request",
|
||||
"build",
|
||||
"publish",
|
||||
"deploy",
|
||||
"health-check",
|
||||
"approval",
|
||||
"mark-ready"
|
||||
]
|
||||
},
|
||||
"entrypoint": { "$ref": "#/definitions/id" },
|
||||
"artifact": { "$ref": "#/definitions/id" },
|
||||
"destination": { "$ref": "#/definitions/id" },
|
||||
"environment": { "$ref": "#/definitions/id" },
|
||||
"gate": { "type": "string", "enum": ["release", "production"] },
|
||||
"draft": { "type": "boolean" },
|
||||
"remote": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
||||
},
|
||||
"baseBranch": { "type": "string", "minLength": 1, "maxLength": 255 }
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"type": "object",
|
||||
"required": ["stopAt", "steps"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"stopAt": {
|
||||
"type": "string",
|
||||
"enum": ["verified", "review_ready", "released"]
|
||||
},
|
||||
"steps": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/step" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
# 复制为 docs/ack/delivery.yaml。默认关闭;由用户明确配置后再启用。
|
||||
version: 1
|
||||
updatedAt: "<YYYY-MM-DDTHH:mm:ss+TZ>"
|
||||
project:
|
||||
name: "<project_name>"
|
||||
|
||||
enabled: false
|
||||
defaultProfile: null
|
||||
|
||||
# 所有可执行入口都使用结构化 argv 语义;requiredSecrets 只保存名称,不保存值。
|
||||
# 不在此保存 shell、env 或凭据正文。
|
||||
entrypoints: {}
|
||||
|
||||
# 支持 deb、oci-image 和 file。复杂构建逻辑留在项目已有入口中。
|
||||
artifacts: {}
|
||||
|
||||
# 支持 apt-repository、oci-registry 和 ci-artifact。
|
||||
destinations: {}
|
||||
|
||||
# 支持 ssh-host、docker-compose、kubernetes 和 custom。
|
||||
environments: {}
|
||||
|
||||
# enabled=true 时,defaultProfile 必须指向一个非空 profile。
|
||||
profiles: {}
|
||||
@@ -8,7 +8,8 @@
|
||||
> 若希望 Agent 自动加载,可由项目维护者自行在 `AGENTS.md` 中引用本文件;ACK
|
||||
> 不会自动修改 `AGENTS.md`、`CLAUDE.md` 或其它 Agent 指令文件。
|
||||
> 无论叫什么,都在 `tasks.yaml` 的 `project.overlayFile` 记录实际路径。
|
||||
> `docs/ack/` 只保存本项目的 `project.md`、`tasks.yaml` 与 `knowledge.yaml`,
|
||||
> `docs/ack/` 只保存本项目的 `project.md`、`tasks.yaml`、`knowledge.yaml` 与默认关闭的
|
||||
> `delivery.yaml`,
|
||||
> 不复制或链接 Skill。
|
||||
|
||||
## 项目概览
|
||||
@@ -19,6 +20,7 @@
|
||||
- Base URL:`<base_url>`
|
||||
- 任务板:`docs/ack/tasks.yaml`
|
||||
- 项目知识:`docs/ack/knowledge.yaml`
|
||||
- 交付契约:`docs/ack/delivery.yaml`(默认关闭)
|
||||
- 覆盖层文件:`<overlay_file_path>`(默认 `docs/ack/project.md`)
|
||||
|
||||
## 通用规范(由 ACK Skill 按需读取)
|
||||
@@ -30,6 +32,7 @@
|
||||
- 验收信号与三轮策略:`references/optimization-method.md`
|
||||
- 派发 prompt 模板:`references/prompt-templates.md`
|
||||
- Orca 编排命令(可选):`references/orca-adapter.md`
|
||||
- 验证后交付与配置维护(可选):`references/delivery.md`
|
||||
|
||||
## Worker 路由
|
||||
|
||||
@@ -64,6 +67,7 @@ receipt 全部以 `docs/ack/tasks.yaml` 的 `project.orchestration` 与顶层
|
||||
| `<local_config_paths>` | Read-only | Read-only | Read-only | 本地私有配置 |
|
||||
| `tasks.yaml` | R/W | Read-only | Read-only | 只有 Coordinator 写 |
|
||||
| `knowledge.yaml` | R/W | Read-only | Read-only | 只有 Coordinator 写;Developer/Test 通过回报提名或验证 |
|
||||
| `delivery.yaml` | 仅显式维护时 R/W | Read-only | Read-only | 项目交付能力,不是执行授权 |
|
||||
|
||||
## 命令(项目覆盖层)
|
||||
|
||||
@@ -91,8 +95,9 @@ Skill 的 `scripts/run_verification.py` 执行,不直接拼接 path/args。检
|
||||
`ACK_PROJECT_ROOT` 是 runner 固定的根目录 fd 路径;仅用于日志的原始路径位于
|
||||
`ACK_PROJECT_ROOT_DISPLAY`。
|
||||
|
||||
项目状态校验由 `/ack` 使用 Skill 自带的 `scripts/validate_tasks.py` 和
|
||||
`scripts/validate_knowledge.py` 执行。
|
||||
项目状态校验由 `/ack` 使用 Skill 自带的 `scripts/validate_tasks.py`、
|
||||
`scripts/validate_knowledge.py` 和 `scripts/validate_delivery.py` 执行。
|
||||
构建/发布/部署的机器入口以 `delivery.yaml` 为准;本文件不维护第二套交付命令。
|
||||
|
||||
## 硬规则(其余见 references/)
|
||||
|
||||
@@ -112,5 +117,9 @@ Skill 的 `scripts/run_verification.py` 执行,不直接拼接 path/args。检
|
||||
- Developer 回报 `knowledgeApplied` 与 `knowledgeCandidates`,Test 回报
|
||||
`knowledgeChecks`。关键约束应下沉为测试、lint、CI 或正式规范。
|
||||
- ACK 不自动修改 `AGENTS.md`、`CLAUDE.md` 或其它 Agent 指令文件。
|
||||
- `delivery.yaml` 默认关闭,只描述能力,不自动授权提交、推送、发布或部署;交付仅在
|
||||
任务 `verified` 且本次 profile/目标/停止点得到确认后运行。
|
||||
- 默认交付 profile 最多到 `review_ready`;stable 发布或 production 部署必须有
|
||||
approval 步骤并再次获得明确批准。配置变更只影响下一次 run。
|
||||
- 每个任务最多派发 3 轮,仍不过标记 `leftover` 并继续下一个。
|
||||
- 不提交或推送,除非用户明确要求。
|
||||
- 不提交、推送、发布或部署,除非用户确认的 ACK 任务或 delivery profile 明确包含。
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
"const": "docs/ack/knowledge.yaml",
|
||||
"description": "项目知识护栏库的唯一权威路径"
|
||||
},
|
||||
"deliveryFile": {
|
||||
"type": "string",
|
||||
"const": "docs/ack/delivery.yaml",
|
||||
"description": "可选项目交付契约的唯一权威路径"
|
||||
},
|
||||
"orchestration": {
|
||||
"$ref": "#/definitions/orchestration"
|
||||
}
|
||||
@@ -57,6 +62,10 @@
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/workerReceipt" }
|
||||
},
|
||||
"deliveryRuns": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/deliveryRun" }
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/task" }
|
||||
@@ -128,6 +137,26 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "object",
|
||||
"required": ["deliveryFile"],
|
||||
"properties": {
|
||||
"deliveryFile": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["project"]
|
||||
},
|
||||
"then": {
|
||||
"required": ["deliveryRuns"],
|
||||
"properties": {
|
||||
"deliveryRuns": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
@@ -721,6 +750,165 @@
|
||||
"checkedAt": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"deliveryArtifactEvidence": {
|
||||
"type": "object",
|
||||
"required": ["id", "type", "reference"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^[a-z][a-z0-9-]{0,63}$" },
|
||||
"type": { "type": "string", "enum": ["deb", "oci-image", "file"] },
|
||||
"reference": { "type": "string", "minLength": 1 },
|
||||
"digest": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^sha256:[0-9a-f]{64}$"
|
||||
}
|
||||
}
|
||||
},
|
||||
"deliveryDeploymentEvidence": {
|
||||
"type": "object",
|
||||
"required": ["environment", "result", "evidence"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"environment": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9-]{0,63}$"
|
||||
},
|
||||
"result": {
|
||||
"type": "string",
|
||||
"enum": ["succeeded", "failed", "rolled_back"]
|
||||
},
|
||||
"evidence": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"deliveryRun": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"profile",
|
||||
"taskIds",
|
||||
"status",
|
||||
"sourceRevision",
|
||||
"configRevision",
|
||||
"pullRequest",
|
||||
"artifacts",
|
||||
"deployments",
|
||||
"evidence",
|
||||
"updatedAt"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^DR-[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
|
||||
},
|
||||
"profile": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9-]{0,63}$"
|
||||
},
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"planned",
|
||||
"running",
|
||||
"blocked",
|
||||
"failed",
|
||||
"review_ready",
|
||||
"released",
|
||||
"skipped"
|
||||
]
|
||||
},
|
||||
"sourceRevision": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9a-f]{7,64}$"
|
||||
},
|
||||
"configRevision": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9a-f]{7,64}$"
|
||||
},
|
||||
"pullRequest": { "type": ["string", "null"] },
|
||||
"artifacts": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/deliveryArtifactEvidence" }
|
||||
},
|
||||
"deployments": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/deliveryDeploymentEvidence" }
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"updatedAt": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"enum": [
|
||||
"planned",
|
||||
"running",
|
||||
"blocked",
|
||||
"failed",
|
||||
"review_ready",
|
||||
"released"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["status"]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"sourceRevision": { "type": "string" },
|
||||
"configRevision": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"enum": [
|
||||
"blocked",
|
||||
"failed",
|
||||
"review_ready",
|
||||
"released",
|
||||
"skipped"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["status"]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"evidence": { "minItems": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": { "enum": ["review_ready", "released"] }
|
||||
},
|
||||
"required": ["status"]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"sourceRevision": { "type": "string" },
|
||||
"configRevision": { "type": "string" },
|
||||
"pullRequest": { "type": "string", "minLength": 1 },
|
||||
"evidence": { "minItems": 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"task": {
|
||||
"type": "object",
|
||||
"required": ["id", "title", "status"],
|
||||
|
||||
@@ -10,6 +10,7 @@ project:
|
||||
devWorktree: "<dev_worktree>"
|
||||
overlayFile: "docs/ack/project.md"
|
||||
knowledgeFile: "docs/ack/knowledge.yaml"
|
||||
deliveryFile: "docs/ack/delivery.yaml"
|
||||
orchestration:
|
||||
profileVersion: 1
|
||||
mode: "orca"
|
||||
@@ -69,6 +70,7 @@ project:
|
||||
developerUpgraded: "codex-dev-strong"
|
||||
|
||||
workerReceipts: []
|
||||
deliveryRuns: []
|
||||
|
||||
summary:
|
||||
verified: []
|
||||
|
||||
Reference in New Issue
Block a user