You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/agent-core-dev/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ End-to-end procedures that span the stages. Reach for these before reading the s
33
33
34
34
## Stages
35
35
36
-
-[Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the four`LifecycleScope` tiers and visibility, and the no-comment convention. Read before touching business code.
36
+
-[Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the three`LifecycleScope` tiers and visibility, the separate workspace program lifetime, and the no-comment convention. Read before touching business code.
37
37
-[Stage 2 — Design a service](design.md): pick a scope, split a domain across scopes, choose a calling style (direct call vs event vs hook), and direct dependencies. Decide *where things live and who knows whom* before coding.
38
38
- Topic: [Domain boundaries vs Scope](domain-boundaries.md) — keep `session` / `agent` / `turn` from becoming god objects; data-ownership test and their split conclusions.
39
39
- Topic: [Persistence layering](persistence.md) — the three-layer `Store → Storage → backend` model, naming Stores by access pattern, and which layer business code should depend on.
└─ App services @App direct — persistence, config, telemetry, events
266
236
```
267
237
268
-
How the three lenses shaped it:
238
+
The App-scoped `IWorkspaceInstanceManager` owns `WorkspaceInstance` objects. Each instance owns a
239
+
`Program`. The Program constructs workspace resources and creates a `SessionLifecycleService`
240
+
with them. That service creates real `LifecycleScope.Session` children, and each session creates
241
+
`LifecycleScope.Agent` children. There is no workspace `IScopeHandle` and no Workspace value in
242
+
`LifecycleScope`.
269
243
270
-
-**Scope (§2)** → the live registry of one workspace's session scopes is per-handler, so it is Workspace-scoped; the process-wide handler registry lives in the App-scoped `workspaceLifecycle`; per-session data stays in Session-scoped services, reached through the handle's `accessor`.
271
-
-**Dependency direction (§5)** → `sessionLifecycle` is consumed by the edge via `accessor` borrows; it never imports the edge. Every downward arrow lands on a peer or a more foundational Service.
272
-
-**Extension points (§4)** → new per-session behavior plugs into the Session-scoped services (`sessionMetadata`, `agentLifecycle`, `sessionActivity`); new transports stay at the edge. Neither edits `sessionLifecycle`.
244
+
How the three lenses shape it:
273
245
246
+
-**Lifetime (§2)** → workspace state belongs to the Program; per-session state belongs to Session
247
+
scopes; per-agent state belongs to Agent scopes.
248
+
-**Dependency direction (§5)** → the Program receives App dependencies and passes workspace
249
+
resources into the session controller; business code does not import the edge.
250
+
-**Extension points (§4)** → new per-session behavior belongs in Session-scoped services; new
251
+
transports stay at the edge.
274
252
For a multi-scope split, the `exposes` block fills more than one scope — see the `records` pattern in §3.
| Open session scope registry |`sessionLifecycle`|Workspace-scope live handles, one registry per workspace handler (the process-wide handler registry is `workspaceLifecycle`); not the persisted entity table |
85
+
| Open session scope registry |`sessionLifecycle`|Program-owned controller with live Session handles; each workspace Program creates it from current workspace resources; not the persisted entity table |
86
86
| Session commands such as `archive()`|`session`| Orchestrates metadata, agent teardown, and events |
87
87
| Persisted session list / get / count |`sessionIndex`| Backend-neutral read model |
88
88
| Running / idle / awaiting status |`sessionActivity`| Derived from interactions and active turns; owns no state |
- The dispatcher resolves the **scope** from the URL, the **Service** from an `actionMap`, calls the method, wraps the result.
32
+
- The original dispatcher design resolves an address from the URL, selects a Service from an `actionMap`, calls the method, and wraps the result. A workspace URL identifies a program-owned resource; Workspace is not a `LifecycleScope` value.
33
33
34
34
```ts
35
35
// actionMap — the allowlist; hides internal domain names.
Copy file name to clipboardExpand all lines: .agents/skills/agent-core-dev/orient.md
+11-11Lines changed: 11 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,28 +12,28 @@ When writing business code you declare three things; the container handles the r
12
12
13
13
Classes talk only to interfaces and never care how an implementation is constructed.
14
14
15
-
## The four`LifecycleScope` tiers
15
+
## The three`LifecycleScope` tiers
16
16
17
-
Lifetimes form a tree, from longest to shortest:
17
+
DI lifetimes form a tree, from longest to shortest:
18
18
19
19
```text
20
20
App process-wide, single global instance
21
-
└── Workspace one workspace handler (a materialized workspace root)
22
-
└── Session one session
23
-
└── Agent one agent
21
+
└── Session one session
22
+
└── Agent one agent
24
23
```
25
24
26
25
```ts
27
-
// src/app/scopes.ts — the business layer declares the tiers and their order;
28
-
// the DI kernel only knows opaque string kinds plus the declared topology.
29
26
exportenumLifecycleScope {
30
27
App='app',
31
-
Workspace='workspace',
32
28
Session='session',
33
29
Agent='agent',
34
30
}
35
31
```
36
32
33
+
Workspace resources have a separate lifetime. The App-scoped `IWorkspaceInstanceManager`
34
+
materializes one `WorkspaceInstance` per workspace. Its `Program` constructs and disposes the
35
+
workspace services. `Workspace` is a domain identity, not a `LifecycleScope` value.
36
+
37
37
- Later in the topology = shorter life = closer to a leaf.
38
38
- "Singleton" means **one per scope**: `ILogService` is global once; each `Session` scope has its own `ISessionMetadata`.
39
39
-`kind` must advance along the declared topology in the parent→child direction.
@@ -49,7 +49,7 @@ A child scope sees its ancestors; a parent never sees its children. Resolution w
49
49
50
50
### Disposal order
51
51
52
-
Deterministic: **child scopes die first; within one scope, teardown runs in strict reverse registration order, one entry at a time.** The mechanism is the Ledger (`src/_base/lifecycle/`): ordered effect bookkeeping, dual-track (sync + async disposers), serial reverse-order teardown (never parallel), with the teardown reason (`'scope-close' | 'cascade' | 'unload'`) passed through to every disposer. `Disposable` / `DisposableStore` (`src/_base/di/lifecycle.ts`) delegate to it — "reverse construction order" is a Ledger property, not a container convention. Business code declares which tier it lives in and never disposes by hand.
52
+
Deterministic: **child scopes die first; within one scope, teardown runs in strict reverse registration order, one entry at a time.** The mechanism is the Ledger (`src/_base/lifecycle/`): ordered effect bookkeeping, dual-track (sync + async disposers), serial reverse-order teardown (never parallel), with the teardown reason (`'scope-close' | 'cascade' | 'unload'`) passed through to every disposer. `Disposable` / `DisposableStore` (`src/_base/di/lifecycle.ts`) delegate to it — "reverse construction order" is a Ledger property, not a container convention. Scoped business code declares its DI tier. Workspace programs explicitly own their manually constructed resources.
53
53
54
54
## Dynamic DI: units and cascades
55
55
@@ -68,10 +68,10 @@ There is no domain-layer numbering — a domain may import any other domain, gui
68
68
69
69
## Comment convention
70
70
71
-
`packages/agent-core-v2/AGENTS.md` bans comments: no file headers, no section banners, no statement-level narration— the code is the source of truth. The only exception is JSDoc attached to exported symbols, which flows into the generated `.d.ts` and the consumers' IDE hover. Tooling directives (`eslint-disable`, `@ts-expect-error`, …) are banned too: fix the underlying lint/type problem instead, and put negative type-safety cases in compiler-asserted fixtures. Scope is carried by the filename: `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no prefix = App (see service-authoring.md).
71
+
`packages/agent-core-v2/AGENTS.md` bans comments entirely: no file headers, no section banners, no statement-level narration, no JSDoc (not even on exported symbols) — the code is the source of truth. The only exception is a load-bearing lint-suppression directive (`oxlint-disable` / `eslint-disable`) for a deliberate pattern; other tooling directives (`@ts-expect-error`, …) are banned: fix the underlying lint/type problem instead, and put negative type-safety cases in compiler-asserted fixtures. DI scope is carried by registration: `LifecycleScope.App`, `LifecycleScope.Session`, or `LifecycleScope.Agent`. A `workspace*` filename marks workspace-domain ownership, not a DI scope (see service-authoring.md).
72
72
73
73
## Red lines (this stage)
74
74
75
75
- Import via the `#/...` alias (mapped to `src/`); never reach into another domain's internals by relative path.
76
76
- Short-lived may inject long-lived; never the reverse.
77
-
- No comments — not file headers, not beside statements; exported-symbol JSDoc is the only exception.
77
+
- No comments — not file headers, not beside statements, not JSDoc; a load-bearing lint-suppression directive is the only exception.
0 commit comments