Skip to content
Merged
26 changes: 25 additions & 1 deletion .agents/skills/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# GFramework Skills

公开入口目前包含 `gframework-doc-refresh` 与 `gframework-batch-boot`。
公开入口目前包含 `gframework-doc-refresh`、`gframework-batch-boot` 与 `gframework-multi-agent-batch`。

## 公开入口

Expand Down Expand Up @@ -66,6 +66,30 @@
/gframework-batch-boot keep refactoring repetitive source-generator tests in bounded batches
```

### `gframework-multi-agent-batch`

当用户希望主 Agent 负责拆分任务、派发互不冲突的 subagent 切片、核对进度、维护 `ai-plan`、验收结果并持续推进时,使用该入口。

适用场景:

- 复杂任务已经明确可以拆成多个互不冲突的写面
- 主 Agent 需要持续 review / integrate,而不是把执行权完全交给单个 worker
- 需要把 delegated scope、验证结果与下一恢复点同步写回 `ai-plan`
- 任务仍要受 branch diff、context budget 与 reviewability 边界约束

推荐调用:

```bash
/gframework-multi-agent-batch <task>
```

示例:

```bash
/gframework-multi-agent-batch continue the current cqrs optimization by delegating non-conflicting benchmark and runtime slices
/gframework-multi-agent-batch coordinate parallel subagents, keep ai-plan updated, and stop when reviewability starts to degrade
```

## 共享资源

- `_shared/DOCUMENTATION_STANDARDS.md`
Expand Down
4 changes: 4 additions & 0 deletions .agents/skills/gframework-batch-boot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Use this skill when `gframework-boot` is necessary but not sufficient because th
batches until a clear stop condition is met.

Treat `AGENTS.md` as the source of truth. This skill extends `gframework-boot`; it does not replace it.
If the task's defining requirement is that the main agent must keep acting as dispatcher, reviewer, `ai-plan` owner,
and final integrator for multiple parallel workers, prefer `gframework-multi-agent-batch` and use this skill's stop
condition guidance as a secondary reference.

Context budget is a first-class stop signal. Do not keep batching merely because a file-count threshold still has
headroom if the active conversation, loaded repo artifacts, validation output, and pending recovery updates suggest the
Expand All @@ -27,6 +30,7 @@ agent is approaching its safe working-context limit.
- the work is repetitive, sliceable, or likely to require multiple similar iterations
- each batch can be given an explicit ownership boundary
- a stop condition can be measured locally
- the task does not primarily need the orchestration-heavy main-agent workflow captured by `gframework-multi-agent-batch`
3. Before any delegation, define the batch objective in one sentence:
- warning family reduction
- repeated test refactor pattern
Expand Down
4 changes: 4 additions & 0 deletions .agents/skills/gframework-boot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ description: Repository-specific boot workflow for the GFramework repo. Use when

Use this skill to bootstrap work in the GFramework repository with minimal user prompting.
Treat `AGENTS.md` as the source of truth. Use this skill to enforce a startup sequence, not to replace repository rules.
If the task clearly requires the main agent to keep coordinating multiple parallel subagents while maintaining
`ai-plan` and reviewing each result, switch to `gframework-multi-agent-batch` after the boot context is established.

## Startup Workflow

Expand Down Expand Up @@ -45,6 +47,8 @@ Treat `AGENTS.md` as the source of truth. Use this skill to enforce a startup se
- Use `explorer` with `gpt-5.1-codex-mini` for narrow read-only questions, tracing, inventory, and comparisons
- Use `worker` with `gpt-5.4` only for bounded implementation tasks with explicit ownership
- Do not delegate purely for ceremony; delegate only when it materially shortens the task or controls context growth
- If the user explicitly wants the main agent to keep orchestrating multiple workers through several review/integration
cycles, prefer `gframework-multi-agent-batch` over ad-hoc delegation
13. Before editing files, tell the user what you read, how you classified the task, whether subagents will be used,
and the first implementation step.
14. Proceed with execution, validation, and documentation updates required by `AGENTS.md`.
Expand Down
114 changes: 114 additions & 0 deletions .agents/skills/gframework-multi-agent-batch/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
name: gframework-multi-agent-batch
description: Repository-specific multi-agent orchestration workflow for the GFramework repo. Use when the main agent should keep coordinating multiple parallel subagents, maintain ai-plan recovery artifacts, review subagent results, and continue bounded multi-agent waves until reviewability, context budget, or branch-diff limits say to stop.
---

# GFramework Multi-Agent Batch

## Overview

Use this skill when `gframework-boot` has already established repository context, and the task now benefits from the
main agent acting as the persistent coordinator for multiple parallel subagents.

Treat `AGENTS.md` as the source of truth. This skill expands the repository's multi-agent coordination rules; it does
not replace them.

This skill is for orchestration-heavy work, not for every task that merely happens to use one subagent. Prefer it when
the main agent must keep splitting bounded write slices, monitoring progress, updating `ai-plan`, validating accepted
results, and deciding whether another delegation wave is still safe.

## Use When

Adopt this workflow only when all of the following are true:

1. The task is complex enough that multiple parallel slices materially shorten the work.
2. The candidate write sets can be kept disjoint.
3. The main agent still needs to own review, validation, integration, and `ai-plan` updates.
4. Another wave is still likely to fit the branch-diff, context-budget, and reviewability budget.

Prefer `gframework-batch-boot` instead when the task is mainly repetitive bulk progress with a single obvious slice
pattern and little need for continuous multi-worker orchestration.

## Startup Workflow

1. Execute the normal `gframework-boot` startup sequence first:
- read `AGENTS.md`
- read `.ai/environment/tools.ai.yaml`
- read `ai-plan/public/README.md`
- read the mapped active topic `todos/` and `traces/`
2. Confirm that the active topic and current branch still match the work you are about to delegate.
3. Define the current wave in one sentence:
- benchmark-host alignment
- runtime hotspot reduction
- documentation synchronization
- other bounded multi-slice work
4. Identify the critical path and keep it local.
5. Split only the non-blocking work into disjoint ownership slices.
6. Estimate whether one more delegation wave is still safe:
- include current branch diff vs baseline
- loaded `ai-plan` context
- expected validation output
- expected integration overhead

## Worker Design Rules

For each `worker` subagent, specify:

- the concrete objective
- the exact owned files or subsystem
- files or areas the worker must not touch
- required validation commands
- expected output format
- a reminder that other agents may be editing the repo

Prefer `explorer` subagents when the result is read-only ranking, tracing, or candidate discovery.

Do not launch two workers whose write sets overlap unless the overlap is trivial and the main agent has already decided
how to serialize or reconcile that overlap.

## Main-Agent Loop

While workers run, the main agent should only do non-overlapping work:

- inspect the next candidate slices
- recompute branch-diff and context-budget posture
- review finished worker output
- queue follow-up validation
- keep `ai-plan/public/**` current when accepted scope or next steps change

After each completed worker task:

1. Review the reported ownership, validation, and changed files.
2. Confirm the worker stayed inside its boundary.
3. Run or rerun the required validation locally if the slice is accepted.
4. Record accepted delegated scope, validation milestones, and the next recovery point in the active `ai-plan` files.
5. Reassess whether another wave is still reviewable and safe.

## Stop Conditions

Stop the current multi-agent wave when any of the following becomes true:

- the next wave would likely push the main agent near or beyond a safe context budget
- the remaining work no longer splits into clean disjoint ownership slices
- branch diff vs baseline is approaching the current reviewability budget
- integrating another worker would degrade clarity more than it would save time
- validation failures show that the next step belongs on the critical path and should stay local

If a branch-size threshold is also in play, treat it as a coarse repository-scope signal, not the sole decision rule.

## Task Tracking

When this workflow is active, the main agent must keep the active `ai-plan` topic current with:

- delegated scope that has been accepted
- validation results
- current branch-diff posture if it affects stop decisions
- the next recommended resume step

The main agent should keep active entries concise enough that `boot` can still recover the current wave quickly.

## Example Triggers

- `Use $gframework-multi-agent-batch to coordinate non-conflicting subagents for this complex CQRS task.`
- `Keep delegating bounded parallel slices, update ai-plan, and verify each worker result before continuing.`
- `Run a multi-agent wave where the main agent owns review, validation, and integration.`
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "GFramework Multi-Agent Batch"
short_description: "Coordinate bounded parallel subagents with ai-plan tracking"
default_prompt: "Use $gframework-multi-agent-batch to coordinate multiple bounded parallel subagents in this GFramework repository while the main agent owns ai-plan updates, validation, review, and integration."
52 changes: 51 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ All AI agents and contributors must follow these rules when writing, reviewing,

## Repository Boot Skill

- The repository-maintained Codex boot skill lives at `.codex/skills/gframework-boot/`.
- The repository-maintained Codex boot skill lives at `.agents/skills/gframework-boot/`.
- The repository-maintained multi-agent coordination skill lives at `.agents/skills/gframework-multi-agent-batch/`.
- Prefer invoking `$gframework-boot` when the user uses short startup prompts such as `boot`、`continue`、`next step`、
`按 boot 开始`、`先看 AGENTS`、`继续当前任务`.
- Prefer invoking `$gframework-multi-agent-batch` when the user explicitly wants the main agent to delegate bounded
parallel work, track subagent progress, maintain `ai-plan`, verify subagent output, and keep coordinating until the
current multi-agent batch reaches a natural stop boundary.
- The boot skill is a startup convenience layer, not a replacement for this document. If the skill and `AGENTS.md`
diverge, follow `AGENTS.md` first and update the skill in the same change.
- The boot skill MUST read `AGENTS.md`、`.ai/environment/tools.ai.yaml`、`ai-plan/public/README.md` and the relevant
Expand All @@ -131,6 +135,52 @@ All AI agents and contributors must follow these rules when writing, reviewing,
- The main agent remains responsible for reviewing and integrating subagent output. Unreviewed subagent conclusions do
not count as final results.

### Multi-Agent Coordination Rules

The terms below describe the default guardrails for multi-agent batches and how they affect worker-launch decisions.

- `branch-diff budget`: the maximum acceptable branch diff size in files or lines before another worker wave becomes
harder to review as a single PR.
- `reviewability budget`: the cumulative complexity limit beyond which accepting more parallel slices would materially
reduce review quality, even if the raw file count still looks acceptable.
- `context-budget`: the main agent's remaining capacity to track active workers, validation, and integration state
without losing critical execution context.
- When any of these budgets approaches its safe limit, the main agent SHOULD stop launching more workers and close the
current wave first.
- `$gframework-multi-agent-batch` contains the fuller workflow and stop-condition guidance for applying these budgets in
practice.

- Prefer the repository's multi-agent coordination mode when the user explicitly wants the main agent to keep
orchestrating parallel subagents, or when the work naturally splits into `2+` disjoint write slices that can proceed
in parallel without blocking the next local step.
- In that mode, the main agent MUST keep ownership of:
- critical-path selection
- baseline and stop-condition tracking
- `ai-plan` updates
- validation planning and final validation
- review and acceptance of every subagent result
- the final integration and completion decision
- Before spawning any `worker` subagent, the main agent MUST:
- identify the immediate blocking step and keep it local
- define disjoint file or subsystem ownership for each worker
- state the required validation commands and expected output format
- check that the expected write set still fits the current branch-diff and reviewability budget
- While workers run, the main agent MUST avoid overlapping edits and focus on non-conflicting work such as:
- ranking the next candidate slices
- reviewing completed worker output
- recomputing branch-diff and context-budget posture
- keeping `ai-plan/public/**` recovery artifacts current
- Before accepting a worker result, the main agent MUST confirm:
- the worker stayed within its owned files or subsystem
- the reported validation is sufficient for that slice
- any accepted findings or follow-up scope are recorded in the active `ai-plan` todo or trace when the task is
complex or multi-step
- Do not continue launching workers merely because a file-count threshold still has room. Stop the current wave when
ownership boundaries start to overlap, reviewability materially degrades, or the context-budget signal says the main
agent should close the batch.
- When a complex task uses multiple workers, the main agent SHOULD prefer the public workflow documented by
`$gframework-multi-agent-batch` unless a more task-specific skill already provides stricter rules.

## Commenting Rules (MUST)

All generated or modified code MUST include clear and meaningful comments where required by the rules below.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using GFramework.Core.Abstractions.Logging;
using GFramework.Cqrs.Abstractions.Cqrs;
using Microsoft.Extensions.DependencyInjection;

[assembly: GFramework.Cqrs.CqrsHandlerRegistryAttribute(
typeof(GFramework.Cqrs.Benchmarks.Messaging.GeneratedRequestLifetimeBenchmarkRegistry))]

namespace GFramework.Cqrs.Benchmarks.Messaging;

/// <summary>
/// 为 request 生命周期矩阵 benchmark 提供 hand-written generated registry,
/// 以便在默认 generated-provider 宿主路径上比较不同 handler 生命周期的 dispatch 成本。
/// </summary>
public sealed class GeneratedRequestLifetimeBenchmarkRegistry :
GFramework.Cqrs.ICqrsHandlerRegistry,
GFramework.Cqrs.ICqrsRequestInvokerProvider,
GFramework.Cqrs.IEnumeratesCqrsRequestInvokerDescriptors
{
private static readonly GFramework.Cqrs.CqrsRequestInvokerDescriptor Descriptor =
new(
typeof(IRequestHandler<
RequestLifetimeBenchmarks.BenchmarkRequest,
RequestLifetimeBenchmarks.BenchmarkResponse>),
typeof(GeneratedRequestLifetimeBenchmarkRegistry).GetMethod(
nameof(InvokeBenchmarkRequestHandler),
BindingFlags.Public | BindingFlags.Static)
?? throw new InvalidOperationException("Missing generated request lifetime benchmark method."));

private static readonly IReadOnlyList<GFramework.Cqrs.CqrsRequestInvokerDescriptorEntry> Descriptors =
[
new GFramework.Cqrs.CqrsRequestInvokerDescriptorEntry(
typeof(RequestLifetimeBenchmarks.BenchmarkRequest),
typeof(RequestLifetimeBenchmarks.BenchmarkResponse),
Descriptor)
];

/// <summary>
/// 参与程序集注册入口,但不在这里直接写入 handler 生命周期。
/// </summary>
/// <param name="services">当前 generated registry 拥有的服务集合。</param>
/// <param name="logger">用于记录 generated registry 注册行为的日志器。</param>
/// <remarks>
/// 生命周期矩阵需要让 benchmark 主体显式控制 `Singleton / Transient` 变量。
/// 因此 registry 只负责暴露 generated descriptor,不在这里抢先注册 handler,避免把默认单例注册混入比较结果。
/// </remarks>
public void Register(IServiceCollection services, ILogger logger)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(logger);

logger.Debug("Registered generated request lifetime benchmark descriptors.");
}

/// <summary>
/// 返回当前 provider 暴露的全部 generated request invoker 描述符。
/// </summary>
/// <returns>当前 benchmark 需要的 request invoker 描述符集合。</returns>
public IReadOnlyList<GFramework.Cqrs.CqrsRequestInvokerDescriptorEntry> GetDescriptors()
{
return Descriptors;
}

/// <summary>
/// 为目标请求/响应类型对返回 generated request invoker 描述符。
/// </summary>
/// <param name="requestType">待匹配的请求类型。</param>
/// <param name="responseType">待匹配的响应类型。</param>
/// <param name="descriptor">命中时返回的 generated descriptor。</param>
/// <returns>命中当前 benchmark 的请求/响应类型对时返回 <see langword="true" />。</returns>
public bool TryGetDescriptor(
Type requestType,
Type responseType,
out GFramework.Cqrs.CqrsRequestInvokerDescriptor? descriptor)
{
if (requestType == typeof(RequestLifetimeBenchmarks.BenchmarkRequest) &&
responseType == typeof(RequestLifetimeBenchmarks.BenchmarkResponse))
{
descriptor = Descriptor;
return true;
}

descriptor = null;
return false;
}

/// <summary>
/// 模拟 generated request invoker provider 为生命周期矩阵 benchmark 产出的开放静态调用入口。
/// </summary>
/// <param name="handler">当前请求对应的 handler 实例。</param>
/// <param name="request">待分发的 request。</param>
/// <param name="cancellationToken">调用方传入的取消令牌。</param>
/// <returns>交给目标 request handler 处理后的响应任务。</returns>
public static ValueTask<RequestLifetimeBenchmarks.BenchmarkResponse> InvokeBenchmarkRequestHandler(
object handler,
object request,
CancellationToken cancellationToken)
{
var typedHandler = (IRequestHandler<
RequestLifetimeBenchmarks.BenchmarkRequest,
RequestLifetimeBenchmarks.BenchmarkResponse>)handler;
var typedRequest = (RequestLifetimeBenchmarks.BenchmarkRequest)request;
return typedHandler.Handle(typedRequest, cancellationToken);
}
}
Loading
Loading