feat: rename skills/skiff to pouch and move ACK state under .pouch
Use ~/.pouch, the pouch CLI, and .pouch.yaml as the SSOT container. Keep the inner skills/ packages, and store ACK project state in .pouch/ack instead of docs/ack.
This commit is contained in:
@@ -51,7 +51,7 @@ from worker_profiles import ( # noqa: E402
|
||||
PROTOCOL_VERSION = LAUNCH_PROTOCOL_VERSION
|
||||
RECEIPT_VERSION = 1
|
||||
ENVIRONMENT_POLICY = "per-cli-allowlist-v1"
|
||||
TASKS_RELATIVE_PATH = Path("docs/ack/tasks.yaml")
|
||||
TASKS_RELATIVE_PATH = Path(".pouch/ack/tasks.yaml")
|
||||
MAX_CONTROL_OUTPUT = 1024 * 1024
|
||||
MAX_RECORD_SIZE = 256 * 1024
|
||||
LAUNCH_TTL_SECONDS = 120
|
||||
|
||||
@@ -57,7 +57,7 @@ def _validate_knowledge_location(
|
||||
knowledge_path: Path,
|
||||
project_root: Path,
|
||||
) -> str | None:
|
||||
expected = project_root / "docs" / "ack" / "knowledge.yaml"
|
||||
expected = project_root / ".pouch" / "ack" / "knowledge.yaml"
|
||||
lexical = Path(os.path.abspath(knowledge_path.expanduser()))
|
||||
if lexical != expected:
|
||||
return (
|
||||
@@ -171,7 +171,7 @@ def load_authoritative_knowledge(
|
||||
) -> tuple[dict[str, Any] | None, str | None]:
|
||||
source_fd, open_error = _open_regular_beneath(
|
||||
project_root,
|
||||
"docs/ack/knowledge.yaml",
|
||||
".pouch/ack/knowledge.yaml",
|
||||
require_executable=False,
|
||||
)
|
||||
if open_error is not None or source_fd is None:
|
||||
@@ -329,7 +329,7 @@ def main(argv: list[str] | None = None) -> int:
|
||||
parser.add_argument("verification_ref", help="verificationRegistry 中的检查 ID")
|
||||
parser.add_argument(
|
||||
"--project-root",
|
||||
help="项目根目录;默认从 knowledge.yaml 的 docs/ack 布局或 Git 推断",
|
||||
help="项目根目录;默认从 knowledge.yaml 的 .pouch/ack 布局或 Git 推断",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ def _parser() -> argparse.ArgumentParser:
|
||||
parser.add_argument(
|
||||
"tasks",
|
||||
nargs="?",
|
||||
default="docs/ack/tasks.yaml",
|
||||
default=".pouch/ack/tasks.yaml",
|
||||
help="任务板路径",
|
||||
)
|
||||
parser.add_argument("--task-id", action="append", default=[])
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
检查引用、步骤顺序、默认 profile 安全边界、敏感信息和仓库内入口路径。
|
||||
|
||||
用法:
|
||||
python3 validate_delivery.py docs/ack/delivery.yaml
|
||||
python3 validate_delivery.py docs/ack/delivery.yaml \
|
||||
--tasks docs/ack/tasks.yaml --project-root <project-root>
|
||||
python3 validate_delivery.py .pouch/ack/delivery.yaml
|
||||
python3 validate_delivery.py .pouch/ack/delivery.yaml \
|
||||
--tasks .pouch/ack/tasks.yaml --project-root <project-root>
|
||||
|
||||
退出码: 0 通过 / 1 校验失败 / 2 环境或用法错误。
|
||||
"""
|
||||
@@ -777,8 +777,8 @@ def validate_tasks_link(delivery: dict[str, Any], tasks: dict[str, Any]) -> list
|
||||
project = tasks.get("project")
|
||||
if not isinstance(project, dict):
|
||||
return ["tasks.project 必须是对象"]
|
||||
if project.get("deliveryFile") != "docs/ack/delivery.yaml":
|
||||
errors.append("tasks.project.deliveryFile 必须固定为 docs/ack/delivery.yaml")
|
||||
if project.get("deliveryFile") != ".pouch/ack/delivery.yaml":
|
||||
errors.append("tasks.project.deliveryFile 必须固定为 .pouch/ack/delivery.yaml")
|
||||
delivery_project = delivery.get("project")
|
||||
if (
|
||||
isinstance(delivery_project, dict)
|
||||
@@ -806,8 +806,8 @@ def validate_with_schema(data: dict[str, Any], schema_path: Path) -> list[str]:
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="校验 ACK 项目交付契约")
|
||||
parser.add_argument("delivery", nargs="?", default="docs/ack/delivery.yaml")
|
||||
parser.add_argument("--tasks", help="关联的 docs/ack/tasks.yaml")
|
||||
parser.add_argument("delivery", nargs="?", default=".pouch/ack/delivery.yaml")
|
||||
parser.add_argument("--tasks", help="关联的 .pouch/ack/tasks.yaml")
|
||||
parser.add_argument("--project-root", help="项目根目录;提供后检查入口路径")
|
||||
parser.add_argument("--schema", help="delivery.schema.json 路径(默认自动探测)")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
@@ -189,10 +189,10 @@ def _timestamp(value: Any) -> datetime | None:
|
||||
|
||||
|
||||
def infer_project_root(document_path: Path) -> Path | None:
|
||||
"""从标准 docs/ack 布局或 Git marker 推断项目根,不解析文档 symlink。"""
|
||||
"""从标准 .pouch/ack 布局或 Git marker 推断项目根,不解析文档 symlink。"""
|
||||
lexical = document_path.expanduser().absolute()
|
||||
parent = lexical.parent
|
||||
if parent.name == "ack" and parent.parent.name == "docs":
|
||||
if parent.name == "ack" and parent.parent.name in {".pouch", "docs"}:
|
||||
return parent.parent.parent.resolve()
|
||||
for candidate in (parent, *parent.parents):
|
||||
if (candidate / ".git").exists():
|
||||
@@ -245,7 +245,7 @@ def _tasks_project_root(
|
||||
return inferred
|
||||
|
||||
# Legacy task boards may still declare repoPath. It is only a fallback for
|
||||
# non-standard layouts; docs/ack location is authoritative when available.
|
||||
# non-standard layouts; .pouch/ack location is authoritative when available.
|
||||
project = tasks_data.get("project")
|
||||
repo_path = project.get("repoPath") if isinstance(project, dict) else None
|
||||
if _nonempty(repo_path):
|
||||
@@ -779,10 +779,10 @@ def _validate_knowledge_file_binding(
|
||||
knowledge_file = project.get("knowledgeFile")
|
||||
if not _nonempty(knowledge_file):
|
||||
return ["[tasks] project.knowledgeFile 必填"]
|
||||
if knowledge_file != "docs/ack/knowledge.yaml":
|
||||
if knowledge_file != ".pouch/ack/knowledge.yaml":
|
||||
errors.append(
|
||||
"[tasks] project.knowledgeFile 必须固定为 "
|
||||
"'docs/ack/knowledge.yaml'"
|
||||
"'.pouch/ack/knowledge.yaml'"
|
||||
)
|
||||
relative = Path(knowledge_file)
|
||||
segments = knowledge_file.replace("\\", "/").split("/")
|
||||
@@ -812,7 +812,7 @@ def _validate_knowledge_file_binding(
|
||||
binding_root = project_root or declared_root
|
||||
if binding_root is None or not binding_root.is_dir():
|
||||
errors.append(
|
||||
"[tasks] 无法从 docs/ack 布局确定现有项目根目录;"
|
||||
"[tasks] 无法从 .pouch/ack 布局确定现有项目根目录;"
|
||||
"请传入 --project-root"
|
||||
)
|
||||
return errors
|
||||
@@ -1071,7 +1071,7 @@ def main(argv: list[str] | None = None) -> int:
|
||||
parser.add_argument("--tasks", help="可选 tasks.yaml,用于跨文件引用校验")
|
||||
parser.add_argument(
|
||||
"--project-root",
|
||||
help="可选项目根目录;默认从 tasks.yaml 的 docs/ack 布局推断",
|
||||
help="可选项目根目录;默认从 tasks.yaml 的 .pouch/ack 布局推断",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -763,17 +763,17 @@ def validate_builtin(data: dict) -> list[str]:
|
||||
)
|
||||
if (
|
||||
"knowledgeFile" in project
|
||||
and project.get("knowledgeFile") != "docs/ack/knowledge.yaml"
|
||||
and project.get("knowledgeFile") != ".pouch/ack/knowledge.yaml"
|
||||
):
|
||||
errors.append(
|
||||
"project.knowledgeFile 必须固定为 docs/ack/knowledge.yaml"
|
||||
"project.knowledgeFile 必须固定为 .pouch/ack/knowledge.yaml"
|
||||
)
|
||||
if (
|
||||
"deliveryFile" in project
|
||||
and project.get("deliveryFile") != "docs/ack/delivery.yaml"
|
||||
and project.get("deliveryFile") != ".pouch/ack/delivery.yaml"
|
||||
):
|
||||
errors.append(
|
||||
"project.deliveryFile 必须固定为 docs/ack/delivery.yaml"
|
||||
"project.deliveryFile 必须固定为 .pouch/ack/delivery.yaml"
|
||||
)
|
||||
if "deliveryFile" in project and not isinstance(data.get("deliveryRuns"), list):
|
||||
errors.append("引用 deliveryFile 的任务板必须包含 deliveryRuns 列表")
|
||||
|
||||
@@ -13,7 +13,7 @@ import sys
|
||||
|
||||
MIGRATION_MESSAGE = (
|
||||
"ACK v0.10 已停用自由 worker command 校验器;请在 "
|
||||
"docs/ack/tasks.yaml 的 project.orchestration 中声明 profile,并仅调用 "
|
||||
".pouch/ack/tasks.yaml 的 project.orchestration 中声明 profile,并仅调用 "
|
||||
"scripts/launch_worker.py profile-hash|plan|launch。"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user