docs(agent-core-dev): add commit-align workflow, drop DI dependency map

- add commit-align.md subskill: triage one main-branch commit against v2
  (aligned / partial / missing / not-applicable) and link it from SKILL.md
- delete docs/di-scope-domains.puml and the rendered svg, and drop the
  keep-the-map-in-sync requirement from verify.md, align.md, commit-align.md,
  and packages/agent-core-v2/AGENTS.md
This commit is contained in:
haozhe.yang 2026-07-11 16:42:37 +08:00
parent f67de05008
commit c879b49f4e
7 changed files with 82 additions and 441 deletions

View file

@ -1,6 +1,6 @@
---
name: agent-core-dev
description: Use when developing in packages/agent-core-v2 (the DI × Scope agent engine) — adding or modifying a domain Service, choosing a LifecycleScope, wiring DI dependencies, splitting a domain across scopes, owning or migrating a config section, gating behavior behind an experimental flag, raising coded errors, working on the permission system, writing DI/Scope tests, porting business logic from agent-core (v1) to v2, or exposing a v2 domain over server-v2 while keeping the wire contract compatible with packages/server. Self-contained guide organized by development stage (orient → design → implement → test → verify) plus align workflows for v1→v2 migration and server-v2 wire exposure; each file carries the rules, examples, and red lines for its step.
description: Use when developing in packages/agent-core-v2 (the DI × Scope agent engine) — adding or modifying a domain Service, choosing a LifecycleScope, wiring DI dependencies, splitting a domain across scopes, owning or migrating a config section, gating behavior behind an experimental flag, raising coded errors, working on the permission system, writing DI/Scope tests, porting business logic from agent-core (v1) to v2, triaging a main-branch commit against v2, or exposing a v2 domain over server-v2 while keeping the wire contract compatible with packages/server. Self-contained guide organized by development stage (orient → design → implement → test → verify) plus align workflows for v1→v2 migration, main-branch commit triage, and server-v2 wire exposure; each file carries the rules, examples, and red lines for its step.
---
# agent-core-dev
@ -28,6 +28,7 @@ Stages are ordered but not strictly linear: a test failure (stage 4) that reveal
End-to-end procedures that span the stages. Reach for these before reading the stage files individually.
- [Align (port `agent-core` → `agent-core-v2`)](align.md): split a v1 class into semantic units, fix each unit's domain / scope / Service / dependencies, then migrate the logic and tests. Use when the task is "move feature X from v1 to v2" or "port `IXxxService` to v2".
- [Commit align (triage a `main` commit against v2)](commit-align.md): given one `main` commit hash + a short note, find the v1 logic it changed, check whether v2 already has the corresponding implementation, bucket it (aligned / partial / missing / not-applicable), and recommend a minimal fix. Use in the `kimi-code-v2`-catching-up-to-`main` phase, for one commit at a time; escalate to [align.md](align.md) if the gap is a whole domain.
- [Server align (expose `agent-core-v2` over `server-v2`)](server-align.md): wire a v2 domain into `packages/kap-server` over `/api/v2` (native) and `/api/v1` (v1-compatible mirror), keep the wire schema byte-compatible with `packages/server` by sharing the `@moonshot-ai/protocol` schema, and isolate v1-only behavior in a `<domain>Legacy` edge adapter instead of distorting the native v2 Service. Use when the task is "expose the new v2 Service on the server", "port the v1 `/api/v1` routes to server-v2", or "keep server-v2 wire-compatible with `packages/server`".
## Stages
@ -45,7 +46,7 @@ End-to-end procedures that span the stages. Reach for these before reading the s
- Topic: [Permission](permission.md) — composable chain-of-responsibility kernel, policy registry + composer, `modes`/`agentTypes` metadata, `resolveExecution`/`accesses`.
- Topic: [Telemetry](telemetry.md) — emitting events via `ITelemetryService`, context propagation, and appender destinations (`ConsoleAppender` / `CloudAppender`).
- [Stage 4 — Test](test.md): resolve the system under test by interface, pick `TestInstantiationService` vs `createScopedTestHost`, shared stubs, service groups, teardown.
- [Stage 5 — Verify & submit](verify.md): `lint:domain`, `typecheck`, `test`, updating the DI × Scope dependency map, and the pre-submit checklist.
- [Stage 5 — Verify & submit](verify.md): `lint:domain`, `typecheck`, `test`, and the pre-submit checklist.
## How to use this skill

View file

@ -223,7 +223,6 @@ Before submitting a port:
- [ ] Registrations use `registerScopedService` with an explicit scope and domain name; no `registerSingleton` remains.
- [ ] Imports use the `#/...` alias; no v1 relative (`../../di`, `../../errors`) imports remain.
- [ ] Errors are co-located coded errors; flags go through `IFlagService`.
- [ ] The DI × Scope dependency map (`.puml` + regenerated `.svg`) is updated for any new Service or changed dependency (verify.md).
- [ ] Tests resolve the SUT by interface; scope behavior is asserted via `createScopedTestHost`; teardown goes through one `DisposableStore`.
- [ ] v1 bootstrap overrides (`services.set(...)`) are preserved at the v2 composition root.

View file

@ -0,0 +1,78 @@
# Subskill — Commit align (triage a `main` commit against v2)
Context: you are on the `kimi-code-v2` branch, in the phase of catching it up to **new commits that landed on `main`**. Those commits change `packages/agent-core` (v1); the job is to decide, for one commit at a time, whether v2 (`packages/agent-core-v2`) already has the corresponding logic — and if not, what the minimal fix is.
Use this when the user hands you **one commit hash plus a short description** ("look at `<commit>` — it fixed the steering race"). It is the small, per-commit sibling of [align.md](align.md): `align.md` ports a whole v1 domain into v2; this file triages a single `main` commit and says *port / adapt / skip*. If the triage reveals a whole missing domain, stop and switch to [align.md](align.md).
## The one-paragraph mental model
A `main` commit edits v1's singleton-container code. The same behavior in v2 lives behind a scoped Service, so a commit lands in one of four buckets: **already-aligned** (v2 has it, possibly by construction), **partial** (v2 has a nearby version whose semantics drift), **missing** (v2 has nothing), or **not-applicable** (the v2 architecture removed the very problem the commit fixes). Your output is a bucket assignment plus evidence, then a fix sized to that bucket — never a blind port of the diff.
## The workflow
```text
Read the commit + the user's note → Locate the v1 logic → Map to a v2 domain
→ Check v2 for a corresponding implementation → Bucket it → Recommend a fix → Verify
```
### 1. Read the commit and the note
**Goal:** know exactly what changed in v1 and *why*. The user's one-liner gives the intent; the diff gives the facts.
Actions:
- Inspect the change scoped to v1: `git show <commit> -- packages/agent-core` (and `--stat` first to see the blast radius).
- From the diff, list: touched files, changed functions/methods, and the observable behavior delta (before → after).
- Reconcile with the user's note: is this a bugfix, a semantic correction, new behavior, or a refactor? The *why* decides whether v2 even needs the change.
Do not skim the user's sentence and guess — the diff is the spec for what "aligned" means here.
### 2. Locate the v1 logic
Pin the change to a v1 place: the contract (`<domain>/<domain>.ts`) + impl (`<domain>/<domain>Service.ts`), or the helper/handler the commit touched. Note which state it reads/writes and which other v1 services it calls — this is the same inventory as [align.md](align.md) §1, scoped to the commit's footprint.
### 3. Map to a v2 domain
Use the v1 → v2 domain table in [align.md](align.md) §3 as a starting point, then **verify against the current `packages/agent-core-v2/src/` tree** — it is the source of truth. Identify the candidate v2 Service(s) that would own this behavior, and their `LifecycleScope`.
### 4. Check v2 and assign a bucket
Search the candidate domain in v2 (Grep the method name, the state field, the error code). For each piece of the commit's behavior delta, decide:
- **Already-aligned** — v2 produces the same observable result (sometimes for free, because the v2 design never had the bug). Cite the v2 file:line.
- **Partial** — v2 has a near miss: same method, different guard/ordering/error; or the state lives at a different scope. Name the exact drift.
- **Missing** — no v2 Service owns this behavior. Confirm it is a single-Service gap, not a whole-domain gap (latter → [align.md](align.md)).
- **Not-applicable** — the v2 architecture removed the condition the commit fixes (e.g. the scope tree already serializes what v1 patched with a lock). Explain why, so a reviewer trusts the skip.
Every claim needs a citation (`path:line`) on both sides; "I couldn't find it" is a finding only after you name where you looked.
### 5. Recommend a fix (sized to the bucket)
- **Already-aligned** — say so and stop; reference the v2 location. No code change.
- **Partial** — propose the smallest edit that closes the drift: which Service, which method, which guard. Stay inside v2 rules — scope/domain direction, no `Map<sessionId, …>` at `App` (see [align.md](align.md) §6§7 red lines).
- **Missing** — sketch the port at commit granularity: target domain + scope, the Service/method to add or extend, the dependency direction, and which [align.md](align.md) §7 conversions apply (registration, `#/…` imports, co-located coded error, `IFlagService` for any gate). If it needs a new scope or a wire change, flag it.
- **Not-applicable** — recommend no v2 change, but call out any test worth adding so the gap stays closed.
Keep the recommendation to the commit's footprint. If it keeps growing, that is the signal to hand off to [align.md](align.md) for a full domain port.
### 6. Verify
Point at the checks that cover the fix, per [verify.md](verify.md): `lint:domain`, `typecheck`, and the relevant `test`. Note the expected outcome rather than asserting you ran it if you did not.
## Output shape
When triaging, answer in this order so the user can act on it directly:
1. **Commit + intent** — one line restating what the commit changed and why (from the note + diff).
2. **v1 location** — file(s) and the behavior delta.
3. **v2 status** — one of the four buckets, with `path:line` evidence on both sides.
4. **Recommendation** — the concrete fix (or the justified skip), scoped to the commit; name the target Service / scope / dependency direction.
5. **Verify** — which checks should pass, and whether to escalate to [align.md](align.md).
## Red lines (this subskill)
- Read the diff and the note before judging v2; never infer "aligned" from the description alone.
- Do not copy a v1 diff into v2. Decide the bucket first; a bugfix commit often maps to **not-applicable** because the v2 design already removed the defect.
- Cite `path:line` on both sides. A recommendation without evidence is a guess.
- Stay in the commit's footprint. Growing scope means "switch to [align.md](align.md)", not "keep porting here".
- Do not break v2 invariants to chase v1 parity — scope direction, domain direction, and no `Map<sessionId, …>` at `App` still hold ([align.md](align.md) red lines).

View file

@ -1,6 +1,6 @@
# Stage 5 — Verify & submit
Run the guards, keep the dependency map in sync, and re-scan the red lines before submitting.
Run the guards and re-scan the red lines before submitting.
## Commands
@ -10,13 +10,6 @@ Run from the package (or with `--filter @moonshot-ai/agent-core-v2`):
- `pnpm --filter @moonshot-ai/agent-core-v2 typecheck``tsc -p tsconfig.json --noEmit`.
- `pnpm --filter @moonshot-ai/agent-core-v2 test``vitest run`.
## Keep the DI × Scope dependency map in sync
The repo maintains a DI Scope × Domain dependency map. Node color = `LifecycleScope`; solid edges = constructor DI injection; dashed edges = `wireRecord` / event-driven.
- **When to update:** whenever you add a Service or change the dependency relationships between Services.
- **What to do:** edit `packages/agent-core-v2/docs/di-scope-domains.puml` and regenerate the rendered `di-scope-domains.svg`.
## Changesets (when the change ships through the CLI)
If the change is user-facing and ships through the CLI, generate a changeset with the repository's `gen-changesets` skill (root `AGENTS.md` workflow). `agent-core-v2` is an internal package; if its change enters the CLI bundle, the changeset lists `@moonshot-ai/kimi-code` and describes the real change — do not present an internal-only change as a user-facing feature. Never write a `major` bump without explicit user confirmation.
@ -29,13 +22,11 @@ Walk the stages you touched and confirm:
- **Implement** — no `new` on `@IService`-carrying classes; `@IX` on constructor params only (service params after static params); interface + impl carry `_serviceBrand`; decorator names unique; coded errors only; flags for unreleased behavior.
- **Test** — SUT resolved by interface; stubs under `test/`; scope tests re-register after `_clearScopedRegistryForTests()`; teardown through one `DisposableStore`.
- **Files** — header comments describe role + scope only; registration runs from the impl file's top level; the new domain is exported from `src/index.ts`.
- **Dependency map**`.puml` updated and `.svg` regenerated if Services or their relationships changed.
Then re-read the [global red lines](SKILL.md#global-red-lines) once — they catch most cross-stage mistakes in a single scan.
## Red lines (this stage)
- Do not skip `lint:domain` — it is the only automated check for the dependency-direction rules.
- Do not forget to regenerate the dependency-map `.svg` after editing the `.puml`.
- Do not list internal packages in a changeset when the change enters the CLI bundle — list `@moonshot-ai/kimi-code` and describe the real change.
- Never write a `major` changeset without explicit user confirmation.

View file

@ -50,4 +50,3 @@ Per-domain references live in `docs/`.
- [`docs/flag.md`](docs/flag.md) — Read **before gating behavior behind a feature flag**: declaring a flag in its owning domain and registering it at import time via `registerFlagDefinition`, checking `IFlagService.enabled(id)`, wiring the `[experimental]` config section, or deciding whether a flag is App-scope vs. per-session.
- [`docs/errors.md`](docs/errors.md) — Read **before raising errors from a domain**: defining a co-located `XxxError`, registering a code in `ErrorCodes`/`ERROR_INFO`, translating external errors (provider/HTTP, fs, MCP) at the boundary, or (de)serializing errors across RPC/SDK with `toErrorPayload`/`fromErrorPayload`.
- [`docs/di-testing.md`](docs/di-testing.md) — Read **before writing or touching any DI/Scope test**: picking the right harness (`InstantiationService` vs `TestInstantiationService` vs `createScopedTestHost`), declaring deps with `@IService`, stubbing collaborators, and teardown via `DisposableStore`.
- [`docs/di-scope-domains.puml`](docs/di-scope-domains.puml) — DI Scope × Domain dependency map (node color = `LifecycleScope`; solid edges = constructor DI injection, dashed edges = `wireRecord` / event-driven). **When adding a Service or changing the dependency relationships between Services, update this puml and regenerate `docs/di-scope-domains.svg`**.

View file

@ -1,426 +0,0 @@
@startuml di-scope-domains
top to bottom direction
skinparam shadowing false
skinparam nodesep 28
skinparam ranksep 55
legend right
<b>Scope = node color</b>
<back:#D6EAF8> </back> App (process-wide)
<back:#D5F5E3> </back> Session (per session)
<back:#FDEBD0> </back> Agent (per agent)
== Edges ==
<color:#34495E>solid</color> : DI injection (ctor @IX)
<color:#16A085>dashed</color> : event-driven (subscribe/emit)
direction: consumer ---> provider
== Notes ==
Generated from `node scripts/dep-graph.mjs` output;
`_base` / seed / options deps are omitted.
endlegend
package "App scope (process-wide)" #EAF3FB {
rectangle "<b>bootstrap</b>\n<size:9><i>App</i></size>\n IBootstrapService" as bootstrap #D6EAF8
rectangle "<b>log</b>\n<size:9><i>_base · App binding</i></size>\n ILogService" as log #D6EAF8
rectangle "<b>telemetry</b>\n<size:9><i>App</i></size>\n ITelemetryService" as telemetry #D6EAF8
rectangle "<b>event</b>\n<size:9><i>App</i></size>\n IEventService" as event #D6EAF8
rectangle "<b>storage</b>\n<size:9><i>App</i></size>\n IFileSystemStorageService\n IAppendLogStore\n IAtomicDocumentStore\n IAtomicTomlDocumentStore" as storage #D6EAF8
rectangle "<b>filestore</b>\n<size:9><i>App</i></size>\n IFileStore" as filestore #D6EAF8
rectangle "<b>gateway</b>\n<size:9><i>App</i></size>\n IRestGateway\n IWSGateway" as gateway #D6EAF8
rectangle "<b>sessionLifecycle</b>\n<size:9><i>App</i></size>\n ISessionLifecycleService" as session_lifecycle #D6EAF8
rectangle "<b>sessionExport</b>\n<size:9><i>App</i></size>\n ISessionExportService" as sessionExport #D6EAF8
rectangle "<b>sessionIndex</b>\n<size:9><i>App</i></size>\n ISessionIndex" as sessionIndex #D6EAF8
rectangle "<b>hostFs</b>\n<size:9><i>App</i></size>\n IHostFileSystem" as hostFs #D6EAF8
rectangle "<b>workspaceRegistry</b>\n<size:9><i>App</i></size>\n IWorkspaceRegistry" as workspaceRegistry #D6EAF8
rectangle "<b>workspaceLocalConfig</b>\n<size:9><i>App</i></size>\n IWorkspaceLocalConfigService" as workspaceLocalConfig #D6EAF8
rectangle "<b>hostFolderBrowser</b>\n<size:9><i>App</i></size>\n IHostFolderBrowser" as hostFolderBrowser #D6EAF8
rectangle "<b>hostEnvironment</b>\n<size:9><i>App</i></size>\n IHostEnvironment" as hostEnvironment #D6EAF8
rectangle "<b>hostProcess</b>\n<size:9><i>App</i></size>\n IHostProcessService" as hostProcess #D6EAF8
rectangle "<b>auth</b>\n<size:9><i>App</i></size>\n IOAuthService\n IAuthSummaryService\n IWebSearchProviderService" as auth #D6EAF8
rectangle "<b>web</b>\n<size:9><i>App</i></size>\n IWebFetchService" as web #D6EAF8
rectangle "<b>edit</b>\n<size:9><i>App</i></size>\n IFileEditService" as edit_app #D6EAF8
rectangle "<b>provider</b>\n<size:9><i>App</i></size>\n IProviderService" as provider #D6EAF8
rectangle "<b>platform</b>\n<size:9><i>App</i></size>\n IPlatformService" as platform #D6EAF8
rectangle "<b>flag</b>\n<size:9><i>App</i></size>\n IFlagService\n IFlagRegistry" as flag #D6EAF8
rectangle "<b>config</b>\n<size:9><i>App</i></size>\n IConfigRegistry\n IConfigService" as config #D6EAF8
rectangle "<b>plugin</b>\n<size:9><i>App</i></size>\n IPluginService" as plugin #D6EAF8
rectangle "<b>chatProvider</b>\n<size:9><i>App</i></size>\n IChatProviderFactory" as chatProvider #D6EAF8
rectangle "<b>model</b>\n<size:9><i>App</i></size>\n IModelService" as model #D6EAF8
rectangle "<b>modelCatalog</b>\n<size:9><i>App</i></size>\n IModelCatalogService" as modelCatalog #D6EAF8
rectangle "<b>agentProfileCatalog</b>\n<size:9><i>App</i></size>\n IAgentProfileCatalogService" as agentProfileCatalog #D6EAF8
rectangle "<b>skillCatalog</b>\n<size:9><i>App</i></size>\n ISkillDiscovery\n ISkillSource\n Builtin/UserSkillSource" as skillCatalog #D6EAF8
}
package "Session scope (per session)" #EAFAF1 {
rectangle "<b>sessionContext</b>\n<size:9><i>Session</i></size>\n ISessionContext (seed)" as session_context #D5F5E3
rectangle "<b>sessionMetadata</b>\n<size:9><i>Session</i></size>\n ISessionMetadata" as session_metadata #D5F5E3
rectangle "<b>sessionActivity</b>\n<size:9><i>Session</i></size>\n ISessionActivity" as session_activity #D5F5E3
rectangle "<b>agentLifecycle</b>\n<size:9><i>Session</i></size>\n IAgentLifecycleService" as agent_lifecycle #D5F5E3
rectangle "<b>sessionSwarm</b>\n<size:9><i>Session</i></size>\n ISessionSwarmService" as sessionSwarm #D5F5E3
rectangle "<b>interaction</b>\n<size:9><i>Session</i></size>\n IInteractionService" as interaction #D5F5E3
rectangle "<b>workspaceContext</b>\n<size:9><i>Session</i></size>\n IWorkspaceContext" as workspaceContext #D5F5E3
rectangle "<b>workspaceCommand</b>\n<size:9><i>Session</i></size>\n ISessionWorkspaceCommandService" as workspaceCommand #D5F5E3
rectangle "<b>sessionInit</b>\n<size:9><i>Session</i></size>\n ISessionInitService" as sessionInit #D5F5E3
rectangle "<b>sessionLog</b>\n<size:9><i>Session binding</i></size>\n ILogService" as sessionLog #D5F5E3
rectangle "<b>sessionSkillCatalog</b>\n<size:9><i>Session</i></size>\n ISessionSkillCatalog\n ISkillCatalogSink\n Workspace/PluginSkillSource" as sessionSkillCatalog #D5F5E3
rectangle "<b>externalHooks</b>\n<size:9><i>Session</i></size>\n ISessionExternalHooksService" as sessionExternalHooks #D5F5E3
rectangle "<b>sessionFs</b>\n<size:9><i>Session</i></size>\n ISessionFsService" as sessionFs #D5F5E3
rectangle "<b>approval</b>\n<size:9><i>Session</i></size>\n IApprovalService" as approval #D5F5E3
rectangle "<b>question</b>\n<size:9><i>Session</i></size>\n IQuestionService" as question #D5F5E3
rectangle "<b>process</b>\n<size:9><i>Session</i></size>\n IProcessRunner\n IProcess" as process #D5F5E3
rectangle "<b>terminal</b>\n<size:9><i>App</i></size>\n IHostTerminalService" as terminal_app #D6EAF8
rectangle "<b>sessionTerminal</b>\n<size:9><i>Session</i></size>\n ISessionTerminalService" as terminal_session #D5F5E3
rectangle "<b>modelProvider</b>\n<size:9><i>Session</i></size>\n IModelProvider (seed)" as modelProvider #D5F5E3
rectangle "<b>todo</b>\n<size:9><i>Session</i></size>\n ISessionTodoService" as todo #D5F5E3
}
package "Agent scope (per agent)" #FDF5E6 {
rectangle "<b>wireRecord</b>\n<size:9><i>Agent</i></size>\n IAgentWireRecordService (event hub)" as wireRecord #FDEBD0
rectangle "<b>wire</b>\n<size:9><i>Agent</i></size>\n IAgentWireService" as wire #FDEBD0
rectangle "<b>blobStore</b>\n<size:9><i>Agent</i></size>\n IAgentBlobStoreService" as blobStore #FDEBD0
rectangle "<b>contextMemory</b>\n<size:9><i>Agent</i></size>\n IAgentContextMemoryService" as contextMemory #FDEBD0
rectangle "<b>contextProjector</b>\n<size:9><i>Agent</i></size>\n IAgentContextProjectorService" as contextProjector #FDEBD0
rectangle "<b>contextInjector</b>\n<size:9><i>Agent</i></size>\n IAgentContextInjectorService" as contextInjector #FDEBD0
rectangle "<b>contextSize</b>\n<size:9><i>Agent</i></size>\n IAgentContextSizeService" as contextSize #FDEBD0
rectangle "<b>systemReminder</b>\n<size:9><i>Agent</i></size>\n IAgentSystemReminderService" as systemReminder #FDEBD0
rectangle "<b>profile</b>\n<size:9><i>Agent</i></size>\n IAgentProfileService" as profile #FDEBD0
rectangle "<b>prompt</b>\n<size:9><i>Agent</i></size>\n IAgentPromptService" as prompt #FDEBD0
rectangle "<b>promptLegacy</b>\n<size:9><i>Agent</i></size>\n IAgentPromptLegacyService" as promptLegacy #FDEBD0
rectangle "<b>turn</b>\n<size:9><i>Agent</i></size>\n IAgentTurnService" as turn #FDEBD0
rectangle "<b>loop</b>\n<size:9><i>Agent</i></size>\n IAgentLoopService" as loop #FDEBD0
rectangle "<b>llmRequester</b>\n<size:9><i>Agent</i></size>\n IAgentLLMRequesterService" as llmRequester #FDEBD0
rectangle "<b>toolRegistry</b>\n<size:9><i>Agent</i></size>\n IAgentToolRegistryService" as toolRegistry #FDEBD0
rectangle "<b>toolExecutor</b>\n<size:9><i>Agent</i></size>\n IAgentToolExecutorService" as toolExecutor #FDEBD0
rectangle "<b>toolResultTruncation</b>\n<size:9><i>Agent</i></size>\n IAgentToolResultTruncationService" as toolResultTruncation #FDEBD0
rectangle "<b>toolDedupe</b>\n<size:9><i>Agent</i></size>\n IAgentToolDedupeService" as toolDedupe #FDEBD0
rectangle "<b>toolSelect</b>\n<size:9><i>Agent</i></size>\n IAgentToolSelectService" as toolSelect #FDEBD0
rectangle "<b>toolSelectAnnouncements</b>\n<size:9><i>Agent</i></size>\n IAgentToolSelectAnnouncementsService" as toolSelectAnnouncements #FDEBD0
rectangle "<b>permissionGate</b>\n<size:9><i>Agent</i></size>\n IAgentPermissionGate" as permissionGate #FDEBD0
rectangle "<b>permissionMode</b>\n<size:9><i>Agent</i></size>\n IAgentPermissionModeService" as permissionMode #FDEBD0
rectangle "<b>permissionPolicy</b>\n<size:9><i>Agent</i></size>\n IAgentPermissionPolicyService" as permissionPolicy #FDEBD0
rectangle "<b>permissionRules</b>\n<size:9><i>Agent</i></size>\n IAgentPermissionRulesService" as permissionRules #FDEBD0
rectangle "<b>plan</b>\n<size:9><i>Agent</i></size>\n IAgentPlanService" as plan #FDEBD0
rectangle "<b>goal</b>\n<size:9><i>Agent</i></size>\n IAgentGoalService" as goal #FDEBD0
rectangle "<b>skill</b>\n<size:9><i>Agent</i></size>\n IAgentSkillService" as skill #FDEBD0
rectangle "<b>questionTools</b>\n<size:9><i>Agent</i></size>\n IAgentQuestionToolsService" as questionTools #FDEBD0
rectangle "<b>userTool</b>\n<size:9><i>Agent</i></size>\n IAgentUserToolService" as userTool #FDEBD0
rectangle "<b>task</b>\n<size:9><i>Agent</i></size>\n IAgentTaskService" as task #FDEBD0
rectangle "<b>cron</b>\n<size:9><i>Agent</i></size>\n IAgentCronService" as cron #FDEBD0
rectangle "<b>swarm</b>\n<size:9><i>Agent</i></size>\n IAgentSwarmService" as swarm #FDEBD0
rectangle "<b>mcp</b>\n<size:9><i>Agent</i></size>\n IAgentMcpService" as mcp #FDEBD0
rectangle "<b>fullCompaction</b>\n<size:9><i>Agent</i></size>\n IAgentFullCompactionService" as fullCompaction #FDEBD0
rectangle "<b>externalHooks</b>\n<size:9><i>Agent</i></size>\n IAgentExternalHooksService" as externalHooks #FDEBD0
rectangle "<b>usage</b>\n<size:9><i>Agent</i></size>\n IAgentUsageService" as usage #FDEBD0
rectangle "<b>rpc</b>\n<size:9><i>Agent</i></size>\n IAgentRPCService" as rpc #FDEBD0
rectangle "<b>fileTools</b>\n<size:9><i>Agent</i></size>\n Read/Write/Grep/Glob tools" as fileTools #FDEBD0
rectangle "<b>edit</b>\n<size:9><i>Agent</i></size>\n EditTool" as edit #FDEBD0
rectangle "<b>shellTools</b>\n<size:9><i>Agent</i></size>\n IAgentShellToolsService" as shellTools #FDEBD0
rectangle "<b>scopeContext</b>\n<size:9><i>Agent</i></size>\n IAgentScopeContext (seed)" as scopeContext #FDEBD0
}
' ---- DI injection (solid) ----
gateway --> session_lifecycle #34495E
gateway --> log #34495E
sessionIndex --> bootstrap #34495E
sessionIndex --> storage #34495E
session_lifecycle --> bootstrap #34495E
session_lifecycle --> hostEnvironment #34495E
session_lifecycle --> event #34495E
sessionExport --> bootstrap #34495E
sessionExport --> sessionIndex #34495E
sessionExport --> session_lifecycle #34495E
sessionExport --> workspaceRegistry #34495E
sessionExport --> log #34495E
workspaceLocalConfig --> bootstrap #34495E
workspaceLocalConfig --> hostFs #34495E
hostFolderBrowser --> hostFs #34495E
auth --> provider #34495E
auth --> platform #34495E
auth --> config #34495E
auth --> bootstrap #34495E
auth --> telemetry #34495E
auth --> log #34495E
auth --> event #34495E
provider --> config #34495E
flag --> bootstrap #34495E
flag --> config #34495E
config --> bootstrap #34495E
config --> log #34495E
config --> storage #34495E
plugin --> bootstrap #34495E
model --> config #34495E
modelCatalog --> provider #34495E
modelCatalog --> model #34495E
modelCatalog --> config #34495E
modelCatalog --> auth #34495E
workspaceContext --> session_context #34495E
workspaceCommand --> workspaceLocalConfig #34495E
workspaceCommand --> workspaceContext #34495E
workspaceCommand --> agent_lifecycle #34495E
sessionInit --> agent_lifecycle #34495E
sessionInit --> hostFs #34495E
sessionInit --> hostEnvironment #34495E
sessionInit --> bootstrap #34495E
sessionLog --> session_context #34495E
sessionSkillCatalog --> skillCatalog #34495E
sessionSkillCatalog --> plugin #34495E
sessionSkillCatalog --> workspaceContext #34495E
skillCatalog --> bootstrap #34495E
skillCatalog --> log #34495E
sessionFs --> workspaceContext #34495E
sessionFs --> process #34495E
process --> session_context #34495E
terminal_session --> terminal_app #34495E
terminal_session --> workspaceContext #34495E
terminal_session --> session_context #34495E
approval --> interaction #34495E
question --> interaction #34495E
modelProvider --> config #34495E
session_metadata --> session_context #34495E
session_metadata --> storage #34495E
session_metadata --> log #34495E
agent_lifecycle --> storage #34495E
session_activity --> agent_lifecycle #34495E
session_activity --> interaction #34495E
sessionSwarm --> agent_lifecycle #34495E
sessionSwarm --> agentProfileCatalog #34495E
sessionSwarm --> session_context #34495E
sessionSwarm --> session_metadata #34495E
sessionSwarm --> process #34495E
sessionSwarm --> log #34495E
wireRecord --> blobStore #34495E
wireRecord --> bootstrap #34495E
wireRecord --> storage #34495E
blobStore --> storage #34495E
blobStore --> environment #34495E
filestore --> storage #34495E
wire --> blobStore #34495E
contextMemory --> wire #34495E
contextInjector --> contextMemory #34495E
contextInjector --> turn #34495E
contextInjector --> loop #34495E
contextInjector --> systemReminder #34495E
contextSize --> contextMemory #34495E
contextSize --> wire #34495E
systemReminder --> contextMemory #34495E
profile --> wireRecord #34495E
profile --> wire #34495E
profile --> telemetry #34495E
profile --> config #34495E
profile --> modelProvider #34495E
profile --> chatProvider #34495E
prompt --> contextMemory #34495E
prompt --> turn #34495E
prompt --> loop #34495E
prompt --> wireRecord #34495E
promptLegacy --> prompt #34495E
promptLegacy --> turn #34495E
promptLegacy --> profile #34495E
promptLegacy --> permissionMode #34495E
promptLegacy --> session_metadata #34495E
promptLegacy --> event #34495E
promptLegacy --> session_context #34495E
promptLegacy --> auth #34495E
turn --> loop #34495E
turn --> wire #34495E
turn --> contextMemory #34495E
turn --> telemetry #34495E
loop --> contextMemory #34495E
loop --> llmRequester #34495E
loop --> event #34495E
loop --> toolExecutor #34495E
loop --> config #34495E
llmRequester --> contextMemory #34495E
llmRequester --> contextProjector #34495E
llmRequester --> toolRegistry #34495E
llmRequester --> toolSelect #34495E
llmRequester --> profile #34495E
llmRequester --> log #34495E
llmRequester --> telemetry #34495E
llmRequester --> usage #34495E
llmRequester --> modelProvider #34495E
llmRequester --> config #34495E
llmRequester --> wire #34495E
toolExecutor --> toolRegistry #34495E
toolExecutor --> wire #34495E
toolExecutor --> telemetry #34495E
toolExecutor --> toolResultTruncation #34495E
toolResultTruncation --> bootstrap #34495E
toolResultTruncation --> scopeContext #34495E
toolResultTruncation --> storage #34495E
toolDedupe --> telemetry #34495E
toolDedupe --> loop #34495E
toolDedupe --> toolExecutor #34495E
toolSelect --> toolRegistry #34495E
toolSelect --> profile #34495E
toolSelect --> contextMemory #34495E
toolSelect --> toolExecutor #34495E
toolSelect --> flag #34495E
toolSelect --> event #34495E
toolSelectAnnouncements --> loop #34495E
toolSelectAnnouncements --> systemReminder #34495E
toolSelectAnnouncements --> event #34495E
toolSelectAnnouncements --> toolSelect #34495E
permissionGate --> permissionMode #34495E
permissionGate --> permissionRules #34495E
permissionGate --> permissionPolicy #34495E
permissionGate --> telemetry #34495E
permissionGate --> toolExecutor #34495E
permissionPolicy --> plan #34495E
permissionPolicy --> swarm #34495E
permissionMode --> wire #34495E
permissionMode --> contextInjector #34495E
permissionRules --> wire #34495E
permissionRules --> config #34495E
plan --> contextMemory #34495E
plan --> hostFs #34495E
plan --> contextInjector #34495E
plan --> telemetry #34495E
plan --> wire #34495E
plan --> session_context #34495E
plan --> scopeContext #34495E
goal --> wireRecord #34495E
goal --> wire #34495E
goal --> systemReminder #34495E
goal --> telemetry #34495E
goal --> contextInjector #34495E
goal --> contextMemory #34495E
goal --> turn #34495E
goal --> loop #34495E
goal --> usage #34495E
goal --> toolRegistry #34495E
goal --> permissionMode #34495E
skill --> prompt #34495E
skill --> wire #34495E
skill --> telemetry #34495E
skill --> sessionSkillCatalog #34495E
questionTools --> question #34495E
questionTools --> toolRegistry #34495E
questionTools --> task #34495E
questionTools --> telemetry #34495E
userTool --> toolRegistry #34495E
userTool --> profile #34495E
userTool --> wire #34495E
task --> wireRecord #34495E
task --> telemetry #34495E
task --> prompt #34495E
task --> contextMemory #34495E
task --> contextInjector #34495E
task --> config #34495E
task --> storage #34495E
task --> session_context #34495E
cron --> prompt #34495E
cron --> wireRecord #34495E
cron --> turn #34495E
cron --> telemetry #34495E
cron --> toolRegistry #34495E
cron --> config #34495E
cron --> storage #34495E
swarm --> wire #34495E
swarm --> systemReminder #34495E
mcp --> toolRegistry #34495E
mcp --> wire #34495E
mcp --> toolExecutor #34495E
mcp --> telemetry #34495E
fullCompaction --> contextMemory #34495E
fullCompaction --> contextSize #34495E
fullCompaction --> llmRequester #34495E
fullCompaction --> profile #34495E
fullCompaction --> toolRegistry #34495E
fullCompaction --> toolSelect #34495E
fullCompaction --> telemetry #34495E
fullCompaction --> log #34495E
fullCompaction --> wireRecord #34495E
fullCompaction --> turn #34495E
fullCompaction --> loop #34495E
externalHooks --> config #34495E
externalHooks --> bootstrap #34495E
externalHooks --> plugin #34495E
externalHooks --> contextMemory #34495E
externalHooks --> session_context #34495E
sessionExternalHooks --> session_lifecycle #34495E
sessionExternalHooks --> agent_lifecycle #34495E
sessionExternalHooks --> config #34495E
sessionExternalHooks --> plugin #34495E
sessionExternalHooks --> session_context #34495E
todo --> agent_lifecycle #34495E
usage --> wire #34495E
rpc --> prompt #34495E
rpc --> turn #34495E
rpc --> profile #34495E
rpc --> permissionMode #34495E
rpc --> permissionGate #34495E
rpc --> plan #34495E
rpc --> swarm #34495E
rpc --> fullCompaction #34495E
rpc --> userTool #34495E
rpc --> toolRegistry #34495E
rpc --> task #34495E
rpc --> contextMemory #34495E
rpc --> contextSize #34495E
rpc --> skill #34495E
rpc --> questionTools #34495E
rpc --> usage #34495E
rpc --> telemetry #34495E
rpc --> goal #34495E
rpc --> plugin #34495E
rpc --> fileTools #34495E
rpc --> shellTools #34495E
fileTools --> toolRegistry #34495E
fileTools --> hostFs #34495E
fileTools --> hostEnvironment #34495E
fileTools --> hostProcess #34495E
fileTools --> workspaceContext #34495E
fileTools --> telemetry #34495E
edit --> toolRegistry #34495E
edit --> edit_app #34495E
edit --> hostEnvironment #34495E
edit --> workspaceContext #34495E
edit_app --> hostFs #34495E
shellTools --> toolRegistry #34495E
shellTools --> process #34495E
shellTools --> hostEnvironment
shellTools --> session_context #34495E
shellTools --> task #34495E
web --> toolRegistry #34495E
auth --> toolRegistry #34495E
' ---- event-driven (dashed) ----
flag ..> config #16A085 : onDidChangeConfiguration
permissionMode ..> wire #16A085 : permission.set_mode
userTool ..> wire #16A085 : tools.register_/unregister_user_tool
profile ..> wire #16A085 : config.update / tools.set_active_tools
profile ..> wire #16A085 : agent.status.updated / warning
contextMemory ..> wireRecord #16A085 : context.splice
cron ..> wireRecord #16A085 : cron.add / delete / cursor
todo ..> wire #16A085 : todo.set (main agent)
fullCompaction ..> wire #16A085 : full_compaction.begin/cancel/complete
fullCompaction ..> loop #16A085 : hooks.onError
permissionRules ..> wire #16A085 : permission.rules.add / record_approval_result
skill ..> wire #16A085 : skill.activate
goal ..> wireRecord #16A085 : goal.create/update/clear
goal ..> turn #16A085 : turn lifecycle hooks
goal ..> loop #16A085 : step hooks
goal ..> usage #16A085 : hooks.onDidRecord
goal ..> eventSink #16A085 : hook.result / goal.updated
swarm ..> wire #16A085 : swarm_mode.enter/exit
swarm ..> turn #16A085 : hooks.onEnded
task ..> wire #16A085 : task.started/terminated
task ..> contextMemory #16A085 : hooks.onSpliced
toolSelect ..> toolExecutor #16A085 : unavailable / missingToolDescriber
externalHooks ..> toolExecutor #16A085 : onWillExecuteTool / onDidExecuteTool
externalHooks ..> permissionGate #16A085 : approval hooks
externalHooks ..> turn #16A085 : prompt/end hooks
externalHooks ..> loop #16A085 : stop hook
externalHooks ..> fullCompaction #16A085 : compaction hooks
externalHooks ..> task #16A085 : notification hook
sessionExternalHooks ..> session_lifecycle #16A085 : SessionStart/End hooks
sessionExternalHooks ..> agent_lifecycle #16A085 : SubagentStart/Stop (observes run hooks)
usage ..> wire #16A085 : usage.record
turn ..> wire #16A085 : turn.launch
contextSize ..> wire #16A085 : context_size.measured
llmRequester ..> wire #16A085 : llm.tools_snapshot / request
loop ..> contextMemory #16A085 : hooks.onSpliced
loop ..> wireRecord #16A085 : hooks.onResumeEnded
plan ..> wire #16A085 : plan_mode.enter/cancel/exit
@enduml

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 286 KiB