Skip to content

Latest commit

 

History

History
193 lines (141 loc) · 10.5 KB

File metadata and controls

193 lines (141 loc) · 10.5 KB

Graft 项目文件组织与扩展点设计

1. 目的与适用范围

本文定义 Graft 面向平台化演进的项目文件组织、外部能力扩展点和渐进迁移规则。

本文是目标组织模型,不代表本次已经完成物理目录迁移。当前 live 代码继续按照现有 server/internal/**server/modules/**server/runner/** 工作;只有完成对应迁移切片并通过验证后,目标路径才可取代旧路径。

本设计覆盖:

  • server 的 Core、Runtime、Application、Ports、Services、Adapters、Providers、Integrations、Agents 与 Runner;
  • 根级 deployments/**tests/** 的部署和 conformance fixture;
  • 后续 Agent 的目录判定、依赖方向和迁移入口。

web 继续遵循自己的模块和壳层架构,本设计不重写 web 目录。

2. 稳定架构原则

2.1 Application First

业务用例先表达应用能力和生命周期,再选择 Docker、Kubernetes、Vault 或其它外部实现。业务模块、Application 和 Core 不得导入供应商 SDK、读取供应商 endpoint、解析宿主机路径或持有 secret 明文。

目标依赖方向:

module / application
        |
        v
provider-neutral port or moduleapi capability
        |
        v
provider implementation -> adapter / external SDK

2.2 Compile-time Provider

Provider 通过 module.Specmodule.Builder 或生成的 compile-time registry 显式注册。当前版本不引入:

  • runtime filesystem scan、动态插件加载或 hot-load;
  • 反射式 Provider discovery、通用 service locator 或第二套 DI;
  • 第三方 Provider marketplace;
  • Provider 自有 scheduler、queue、Task state machine、global health registry 或 evidence store。

Provider 生命周期必须由现有 Runtime 管理,至少能被显式校验、启动、停止,并在失败时以 capability-local 的 Unavailable/Degraded 语义返回,不得把单个 Provider 故障伪装成全局服务故障。

Provider、Agent、Runner 与 Module 的跨边界资源 ownership、capability visibility 和 cleanup declaration 由 运行时组合与资源治理设计.md 统一约束;本文继续只拥有物理组织、依赖方向和扩展点分类。

2.3 当前 authority 不变

  • server/modules/<name>/** 继续拥有业务能力、业务持久化、路由、菜单、权限、任务定义和模块私有 contract。
  • server/internal/moduleapi/** 继续拥有跨模块业务 capability、稳定 DTO 和窄稳定服务接口。
  • server/internal/contract/** 继续拥有平台级 typed contract。
  • server/internal/app/**internal/module/**internal/container/** 等继续拥有显式 Runtime/Core 生命周期。
  • internal/ports/** 仅作为未来外部能力端口的保留边界,不替代 moduleapi,也不能成为通用 shared/common/utils 目录。

3. 目标组织模型

以下路径是目标落点;本次不创建空目录。

server/
├── cmd/                         # 现有 CLI 与一次性命令入口
├── internal/
│   ├── core/                    # 目标概念边界;仅放真正平台基础设施
│   ├── application/             # 目标概念边界;跨模块用例编排
│   ├── ports/                   # 目标概念边界;外部能力端口,非业务 capability
│   ├── services/                # 目标概念边界;平台级应用服务
│   └── adapters/                # 目标概念边界;共享协议/SDK/transport adapter
├── modules/                     # 当前及长期业务模块 canonical 路径
├── providers/                   # compile-time Provider 实现
│   ├── runtime/                 # Docker、Kubernetes、Podman 等运行时 Provider
│   ├── builder/                 # Docker、BuildKit、Kaniko 等构建 Provider
│   ├── secret/                  # Vault、AWS、local 等 secret Provider
│   └── certificate/             # Vault PKI、step-ca 等证书 Provider
├── integrations/                # GitHub、GitLab、Jira、Slack 等业务系统集成
├── agents/                      # 独立部署/发布单元,如 builder、runtime agent
└── runner/                      # 外部副作用执行器及其实现

deployments/                     # 仓库级部署拓扑与发布 fixture
├── docker/
├── compose/
└── kubernetes/

tests/
└── conformance/                 # Provider/Agent/Runner 的 provider-neutral 一致性 fixture

internal/coreinternal/applicationinternal/servicesinternal/adapters 是目标概念分层。迁移前, 现有 internal/appinternal/httpxinternal/eventinternal/eventbusinternal/config 等显式 Core 边界继续有效,不得为了目录外观进行批量搬迁。

4. Provider、Adapter 与 Integration 的区别

Provider

Provider 提供平台运行能力,是某个 Port 的可替换实现,并参与 compile-time registration。例如:

  • Docker Runtime Provider;
  • Kubernetes Deployment Provider;
  • Vault Secret Provider;
  • BuildKit Builder Provider。

Provider 可以使用自己的 adapter,但不能把供应商类型泄露到业务 capability 或公共 API。

Adapter

Adapter 是对 SDK、CLI、协议、传输或原始外部事实的窄封装。共享 adapter 只能进入明确的 Core/Adapter 边界; 供应商专属 adapter 默认放在 Provider 内部,避免同一实现同时存在于 internal/adaptersproviders

Integration

Integration 连接外部业务系统或协作平台,不拥有 Graft 平台运行时能力。例如 GitHub、GitLab、Jira、Slack、邮件 或 webhook 消费。Integration 可以使用 HTTP、OAuth 或 webhook adapter,但不能被命名为 Runtime Provider,也不能 改变 Graft 的 Task、权限或配置 authority。

因此,GitHub IntegrationDocker Runtime Provider 是不同概念;前者连接外部业务系统,后者提供平台执行能力。

5. Agents 与 Runner

5.1 Agents

Agent 是独立部署单元,不是 cmd/ 下的若干参数分支。目标布局为:

server/agents/<name>/
├── cmd/main.go
├── internal/                    # bootstrap、identity、transport、heartbeat 等私有实现
├── config/
└── Dockerfile

Docker 能力采用一个独立部署的 docker-runtime-agent。现有实验期仅面向构建的 Agent 直接升格并改名, 不保留并行 Builder Agent、Runtime Agent 或兼容别名。Agent 拥有独立配置、身份、传输和发布生命周期,作为 唯一常驻 Docker socket owner 承载 Container、Compose 和 Build Provider adapter;它不直接拥有业务数据库 真相,不绕过 Server 的授权、Task/Submission、审计和 Provider conformance 边界。

Agent 只能通过 Runtime Target 的 mTLS listener 拉取 Task Runtime 已冻结的 external execution lease,并用受限 日志与 receipt 回写执行事实。它不得接受 server push、创建第二套 queue/retry/state machine,或把 endpoint、 证书路径、凭据和 SDK 类型写入 TaskPlan。具体边界由 ADR-026 固定。

Application、Container 与 Build 的有限副作用分别通过 compose_executioncontainer_executionoci-build capability 进入该 Agent。业务模块只冻结领域 action/policy;Compose 和 Build 所需 workspace、 定义文件与短时 Registry 凭据由所属 resolver 在 claim 后按 lease/fence 瞬时提供,不属于 Task 或 Agent 持久状态。 Container list/detail、stats、events、logs 与 exec 仍属于 后续 Agent-initiated snapshot/interactive transport,不得把 Agent 的 SDK adapter 反向放回业务 module 作为 fallback。

5.2 Runner

Runner 只执行受控的外部副作用,例如平台自更新、Helm 或 Terraform。它的输入应是不可变 operation snapshot, 完成结果应通过现有 Task/Submission receipt 语义返回;Build 可在 terminal receipt 前通过瞬时 result 边界 交给自己解释 Artifact/Publication,Task 仅保留结果摘要用于幂等重放。

Runner 不得自建第二套任务状态机、队列、重试策略、全局日志库或业务持久化。现有 server/runner/compose 在 迁移完成前继续作为当前实现和历史 authority,不得直接移动或复制出第二份 Compose runner。

6. 当前路径状态与新增代码规则

当前路径 当前状态 后续规则
server/modules/** canonical/current 继续承载业务模块
server/internal/moduleapi/** canonical/current 继续承载跨模块业务 capability
server/internal/app/** 等 Core 包 canonical/current 继续承载显式 Runtime/Core 生命周期
server/runner/compose/** current/legacy-frozen 只维护,不新增第二套抽象;迁移时先更新 authority
server/providers/** target/reserved 新 Provider 实现的目标路径
server/agents/** target/reserved 新独立 Agent 的目标路径
server/integrations/** target/reserved 新外部业务系统集成的目标路径
deployments/**tests/conformance/** target/reserved 部署拓扑与一致性 fixture,不进入 Core

新代码必须先完成边界判定:业务模块、Core Runtime、Port、Provider、Adapter、Integration、Agent、Runner 或 Fixture。 无法分类时,先更新设计文档;禁止把代码临时塞进 internal/**commonsharedutils

7. 迁移顺序

  1. 文档和 authority 收敛;本阶段不改代码、不建空目录。
  2. 新代码直接使用目标边界,旧路径冻结。
  3. 以 capability 为单位迁移 Compose Runner、Docker Runtime、Builder、Secret 和 Certificate Provider。
  4. 将实验期仅面向构建的 Agent 直接升格为单一 Docker Runtime Agent,迁移部署拓扑与 conformance fixture。
  5. 完成 Provider conformance、Task/Submission recovery、权限、审计和配置验证后,再删除旧路径。

每个迁移切片必须同时说明 canonical owner、依赖方向、失败/取消/超时/recovery 语义、验证范围和可删除的旧代码。

8. 设计验收标准

  • Core/Application 不依赖 Docker、Vault、Kubernetes 或其它供应商 SDK。
  • moduleapiports 的职责没有重叠或双重 authority。
  • Provider 只能通过 compile-time wiring 进入 Runtime。
  • Agent、Runner、Integration 都没有创建第二套启动、任务、配置或恢复流程。
  • 旧路径没有被偷偷移动、复制或引入新业务实现。
  • Provider-neutral conformance fixture 可以验证不同 Provider 的共同语义。