变更名:
forge-ai-hub-foundation执行原则:HARD-GATE Spike → 协议无关契约 → Registry → 静态能力 → MCP 适配 → 身份与目录验证 → UI 收敛 → 全量验证 每个任务先写 Red 测试,再写最小实现;禁止自动 commit/push
/apply forge-ai-hub-foundation;spec.md、tasks.md、test-spec.md、execution-log.md;code-copilot/rules/automated-testing-standard.md 复用历史验证基线;STREAMABLE,拒绝 SSE、STATELESS 和 stdio;/mcp 身份过滤器,身份缺失/解析失败在进入 SDK 前返回 HTTP 401,并统一传播 requestId;ValidatedCapabilitySchema,补齐关键字/类型组合、边界和 enum 类型一致性校验;tools/list 限制;code-copilot/changes/archive/2026-07-11-forge-ai-hub-foundation/。forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/pom.xml — 新建最小 MCP 插件,只引入 WebMVC MCP Server starter 与测试依赖;forge-server/forge-framework/forge-plugin-parent/pom.xml — 临时/正式聚合新模块;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/test/java/com/mdframe/forge/plugin/mcp/McpStreamableTransportCompatibilityTest.java — 最小 ApplicationContext 装配测试;code-copilot/changes/forge-ai-hub-foundation/execution-log.md — 记录依赖树、Bean、端点和失败证据;docs/Forge-AI中枢落地架构与阶段路线图.md — 回填经过验证的 transport ADR 结论。java
assertThat(context).hasSingleBean(WebMvcStreamableServerTransportProvider.class);
assertThat(context).doesNotHaveBean(WebMvcSseServerTransportProvider.class);
org.springframework.ai:spring-ai-starter-mcp-server-webmvc,显式配置 protocol=STREAMABLE、stdio=false、mcp-endpoint=/mcp;mvn -pl forge-framework/forge-plugin-parent/forge-plugin-mcp -am dependency:tree -Dincludes=org.springframework.ai,io.modelcontextprotocol.sdk,org.springframework.boot;/mcp 单端点;forge-plugin-capability 与核心契约forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/pom.xml — 新模块,只依赖 forge-starter-core 与必要 JSON 类型;forge-server/forge-framework/forge-plugin-parent/pom.xml — 聚合 capability 模块;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/model/CapabilityDefinition.java — 定义 code/toolName/version/behavior/risk/schema;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/model/CapabilityInvocation.java、CapabilityCallerContext.java、CapabilityResult.java — 不可变调用契约;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/spi/CapabilityExecutor.java、CapabilitySource.java、CapabilityAuthorizationPolicy.java — 执行、来源和授权 SPI。public interface CapabilitySource {
Collection<CapabilityDefinition> load(CapabilityQuery query);
}
- **Red/Green 步骤**:
- [x] 编写架构 Red 测试,扫描 capability 模块不得引用 `org.springframework.ai`、`io.modelcontextprotocol`、`forge.plugin.ai`;
- [x] 编写 record 构造校验测试:必填、不可变 scopes、duration 非负、安全 errorCode;
- [x] 实现 `CapabilityBehavior`、`CapabilityRiskLevel`、`CapabilityResultStatus` 和稳定错误码;
- [x] 明确 `JsonNode` 只表示 JSON 契约,不引入 MCP Schema;
- [x] 执行 capability 模块测试 Green 和 `jdeps/rg` 禁止依赖扫描。
- **验收标准**:核心类型可被 MCP 之外的调用方独立使用;无 Spring AI/MCP/AI 插件依赖;调用结果不包含 Throwable。
## Task 3: 实现名称、Schema 校验和 MCP 公共子集投影
- **目标**:让能力在注册前拥有稳定名称和可验证的 Draft 2020-12 输入输出契约。
- **涉及文件**:
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/naming/CapabilityToolNameMapper.java` — code 与 toolName 恒等映射及格式校验;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/schema/CapabilitySchemaValidator.java` — Draft 2020-12 公共子集校验;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/exception/CapabilityDefinitionException.java` — 带安全路径和错误码的定义异常;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/test/java/com/mdframe/forge/plugin/capability/naming/CapabilityToolNameMapperTest.java`;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/test/java/com/mdframe/forge/plugin/capability/schema/CapabilitySchemaValidatorTest.java`。
- **关键签名**:
```java
public String toProtocolToolName(String capabilityCode) { }
public ValidatedCapabilitySchema validate(
JsonNode inputSchema,
JsonNode outputSchema) { }
$schema、required、additionalProperties=false、enum、nested object、array/items、nullable 联合类型;$ref、递归/条件/动态关键字和无法投影的 nullable 明确失败,异常指出 JSON path;forge-plugin-mcp 增加 McpToolSchemaProjector 时只消费 ValidatedCapabilitySchema,不得重新猜测语义;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/registry/CapabilityRegistry.java、InMemoryCapabilityRegistry.java;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/registry/CapabilityRegistryFactory.java — 启动期聚合并校验 Source/Executor;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/model/CapabilityQuery.java、CapabilityPage.java、CapabilityCursor.java;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/registry/CapabilityInvoker.java — 输入/输出校验、requestId 与安全结果;forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/test/java/com/mdframe/forge/plugin/capability/registry/InMemoryCapabilityRegistryTest.java。public CapabilityResult invoke(CapabilityInvocation invocation) { }
- **Red/Green 步骤**:
- [x] Red 覆盖重复 code+version、重复 toolName、缺 Executor、无效 Schema 启动失败;
- [x] Red 覆盖 `canDiscover` 和 `canInvoke` 分离,未授权项不出现在内核列表且不能调用;
- [x] Red 覆盖排序 `toolName/version`、pageSize 边界、nextCursor、非法/过期/跨快照游标;
- [x] Red 覆盖无 caller、跨租户、跨组织和缺 scope 失败关闭;
- [x] 使用不可变 Map/List 快照,禁止调用期间修改全局工具集合;
- [x] 输入校验后执行、输出校验后返回;异常转安全错误,不返回原始 Throwable message;
- [x] 运行 Registry 并发与确定性测试 Green。
- **验收标准**:相同快照与 query 得到稳定分页;发现和执行均按 caller 过滤;注册冲突不会后写覆盖。
## Task 5: 注册并验证静态 `capability.ping`
- **目标**:用无业务依赖的只读能力打通 Registry 执行闭环。
- **涉及文件**:
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/builtin/PingCapabilitySource.java` — 提供 `capability.ping@1.0.0` 定义;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/builtin/PingCapabilityExecutor.java` — 返回固定状态、requestId、Clock 时间;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/main/java/com/mdframe/forge/plugin/capability/config/CapabilityAutoConfiguration.java` — 聚合 Source/Executor 构建 Registry;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/test/java/com/mdframe/forge/plugin/capability/builtin/PingCapabilityExecutorTest.java`;
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-capability/src/test/java/com/mdframe/forge/plugin/capability/config/CapabilityAutoConfigurationTest.java`。
- **关键签名**:
```java
public CapabilityResult invoke(
CapabilityDefinition definition,
CapabilityInvocation invocation) { }
Clock,禁止测试 sleep;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/main/java/com/mdframe/forge/plugin/mcp/config/ForgeMcpServerConfiguration.java — 仅 Streamable WebMVC 配置;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/main/java/com/mdframe/forge/plugin/mcp/security/McpCallerContextResolver.java、McpTransportContextExtractor.java — 可信主体到 caller context;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/main/java/com/mdframe/forge/plugin/mcp/adapter/McpCapabilityAdapter.java、McpToolSchemaProjector.java、McpCapabilityResultMapper.java;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/test/java/com/mdframe/forge/plugin/mcp/McpStreamableProtocolIntegrationTest.java;forge-server/forge-framework/forge-plugin-parent/forge-plugin-mcp/src/test/java/com/mdframe/forge/plugin/mcp/security/McpCallerContextIsolationTest.java。public McpSchema.CallToolResult call(
McpSyncServerExchange exchange,
McpSchema.CallToolRequest request) { }
```
contextExtractor 只携带已验证主体,不信任裸 X-Tenant-Id/X-User-Id;测试 Resolver 只放 test scope;tools/call 每次重新检查 canInvoke,并映射安全 requestId/errorCode/isError;/mcp 完成三段协议闭环,身份不可伪造;动态目录能力与限制都有可执行证据,不虚报支持。forge-server/forge-framework/forge-dependencies/pom.xml — 管理两个 Forge 插件依赖版本;forge-server/forge-admin-server/pom.xml — 仅 Admin 聚合 forge-plugin-mcp;forge-server/forge-admin-server/src/main/resources/application.yml 与 application-dev.example.yml — 默认关闭并显式 STREAMABLE;forge-admin-ui/src/views/ai/agent.vue — 隐藏硬编码高风险 MCP 选项或显示只读预留提示;forge-server/forge-admin-server/src/test/java/com/mdframe/forge/admin/ForgeMcpAdminAssemblyTest.java — 默认禁用/显式启用装配测试。/mcp,启用但缺 Resolver 时启动失败;/mcp,Flow/Report/App 不因 AI 插件依赖被动出现端点;database_query/http_request/file_reader/code_executor 等未实现值;历史值只读显示“预留/不可用”,不自动丢失或映射成 ping;code-copilot/changes/forge-ai-hub-foundation/spec.md、tasks.md、test-spec.md、execution-log.md;docs/Forge-AI中枢战略与技术选型方案.md;docs/Forge-AI中枢落地架构与阶段路线图.md;code-copilot/memory/decisions.md;code-copilot/memory/pitfalls.md(只有产生可复用踩坑时更新)。-am test/package 和 Admin -am package -DskipTests;dependency:tree 并检查 Spring AI/MCP SDK/Boot 单版本;SseServerTransport、WebMvcSseServerTransportProvider、/sse、sse-message-endpoint、旧 SSE starter/config;git diff --check,记录全部命令、输出摘要、警告、跳过项和服务清理;