dsh-env-manager-plugin 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -2
  3. package/client.js +2581 -0
  4. package/cordis.patch.yml +4 -0
  5. package/docs/00-project/current-state.md +246 -0
  6. package/docs/00-project/glossary.md +215 -0
  7. package/docs/00-project/project-brief.md +114 -0
  8. package/docs/00-project/roadmap.md +89 -0
  9. package/docs/01-architecture/DSH_Environment_Service_Memory_Skill_Brainstorm.md +493 -0
  10. package/docs/01-architecture/api-verification.md +416 -0
  11. package/docs/01-architecture/architecture-overview.md +222 -0
  12. package/docs/01-architecture/data-model.md +930 -0
  13. package/docs/01-architecture/decisions/ADR-0001-plugin-as-bundle.md +29 -0
  14. package/docs/01-architecture/decisions/ADR-0002-file-based-storage.md +25 -0
  15. package/docs/01-architecture/decisions/ADR-0003-skill-router-over-search.md +25 -0
  16. package/docs/01-architecture/decisions/ADR-0004-typescript-host-js-client.md +31 -0
  17. package/docs/01-architecture/decisions/ADR-0005-layered-rule-resolution.md +36 -0
  18. package/docs/01-architecture/decisions/ADR-0006-credentials-as-references.md +30 -0
  19. package/docs/01-architecture/decisions/ADR-0007-session-scoped-default-environment.md +28 -0
  20. package/docs/01-architecture/decisions/ADR-0008-memory-bridge-not-second-store.md +31 -0
  21. package/docs/01-architecture/decisions/ADR-0009-client-host-http-transport.md +87 -0
  22. package/docs/01-architecture/decisions/ADR-0010-environment-plane-model.md +87 -0
  23. package/docs/01-architecture/decisions/ADR-0011-k8s-node-execution-model.md +92 -0
  24. package/docs/01-architecture/design.md +666 -0
  25. package/docs/01-architecture/detailed-design.md +961 -0
  26. package/docs/01-architecture/implementation-plan.md +323 -0
  27. package/docs/01-architecture/module-boundaries.md +306 -0
  28. package/docs/01-architecture/security-model.md +227 -0
  29. package/docs/01-architecture/storage-contract.md +224 -0
  30. package/docs/01-architecture/tool-contract.md +438 -0
  31. package/docs/01-architecture/ui-design.md +587 -0
  32. package/docs/02-harness/agent-behavior.md +36 -0
  33. package/docs/02-harness/change-snapshot-policy.md +29 -0
  34. package/docs/02-harness/client-ui-integration.md +110 -0
  35. package/docs/02-harness/context-policy.md +43 -0
  36. package/docs/02-harness/harness-standard.md +91 -0
  37. package/docs/02-harness/task-execution-policy.md +26 -0
  38. package/docs/02-harness/verification-policy.md +97 -0
  39. package/docs/03-openspec/archive-rule.md +25 -0
  40. package/docs/03-openspec/bugfix-rule.md +30 -0
  41. package/docs/03-openspec/design-rule.md +33 -0
  42. package/docs/03-openspec/openspec-usage-guide.md +31 -0
  43. package/docs/03-openspec/proposal-rule.md +70 -0
  44. package/docs/03-openspec/spec-rule.md +33 -0
  45. package/docs/03-openspec/tasks-rule.md +31 -0
  46. package/docs/04-development/coding-style.md +67 -0
  47. package/docs/04-development/dependency-policy.md +43 -0
  48. package/docs/04-development/development-guide.md +85 -0
  49. package/docs/04-development/directory-convention.md +105 -0
  50. package/docs/04-development/local-run-guide.md +55 -0
  51. package/docs/04-development/testing-guide.md +102 -0
  52. package/docs/05-domain/deployment-template.md +76 -0
  53. package/docs/05-domain/environment-template.md +165 -0
  54. package/docs/05-domain/operation-binding-template.md +55 -0
  55. package/docs/05-domain/operation-record-template.md +55 -0
  56. package/docs/05-domain/prompt-template.md +90 -0
  57. package/docs/05-domain/rule-template.md +73 -0
  58. package/docs/05-domain/service-template.md +39 -0
  59. package/docs/06-operations/deployment-guide.md +54 -0
  60. package/docs/06-operations/release.md +188 -0
  61. package/docs/06-operations/security-policy.md +53 -0
  62. package/docs/06-operations/troubleshooting.md +91 -0
  63. package/docs/07-templates/adr-template.md +21 -0
  64. package/docs/07-templates/bugfix-template.md +11 -0
  65. package/docs/07-templates/case-template.md +15 -0
  66. package/docs/07-templates/design-template.md +29 -0
  67. package/docs/07-templates/proposal-template.md +19 -0
  68. package/docs/07-templates/spec-template.md +15 -0
  69. package/docs/07-templates/tasks-template.md +12 -0
  70. package/docs/99-archive/README.md +13 -0
  71. package/docs/README.md +142 -0
  72. package/icon.svg +4 -0
  73. package/index.js +8 -0
  74. package/lib/app/app.d.ts +67 -0
  75. package/lib/app/app.js +494 -0
  76. package/lib/app/app.js.map +1 -0
  77. package/lib/config.d.ts +55 -0
  78. package/lib/config.js +42 -0
  79. package/lib/config.js.map +1 -0
  80. package/lib/domain/constants.d.ts +21 -0
  81. package/lib/domain/constants.js +59 -0
  82. package/lib/domain/constants.js.map +1 -0
  83. package/lib/domain/errors.d.ts +20 -0
  84. package/lib/domain/errors.js +22 -0
  85. package/lib/domain/errors.js.map +1 -0
  86. package/lib/domain/schemas.d.ts +28 -0
  87. package/lib/domain/schemas.js +445 -0
  88. package/lib/domain/schemas.js.map +1 -0
  89. package/lib/domain/types.d.ts +412 -0
  90. package/lib/domain/types.js +2 -0
  91. package/lib/domain/types.js.map +1 -0
  92. package/lib/index.d.ts +18 -0
  93. package/lib/index.js +89 -0
  94. package/lib/index.js.map +1 -0
  95. package/lib/logger.d.ts +8 -0
  96. package/lib/logger.js +13 -0
  97. package/lib/logger.js.map +1 -0
  98. package/lib/memory/bridge.d.ts +18 -0
  99. package/lib/memory/bridge.js +13 -0
  100. package/lib/memory/bridge.js.map +1 -0
  101. package/lib/registry/integrity.d.ts +10 -0
  102. package/lib/registry/integrity.js +204 -0
  103. package/lib/registry/integrity.js.map +1 -0
  104. package/lib/registry/registry.d.ts +14 -0
  105. package/lib/registry/registry.js +182 -0
  106. package/lib/registry/registry.js.map +1 -0
  107. package/lib/resolver/merge.d.ts +23 -0
  108. package/lib/resolver/merge.js +90 -0
  109. package/lib/resolver/merge.js.map +1 -0
  110. package/lib/resolver/resolve.d.ts +18 -0
  111. package/lib/resolver/resolve.js +288 -0
  112. package/lib/resolver/resolve.js.map +1 -0
  113. package/lib/resolver/template.d.ts +10 -0
  114. package/lib/resolver/template.js +42 -0
  115. package/lib/resolver/template.js.map +1 -0
  116. package/lib/router/params.d.ts +3 -0
  117. package/lib/router/params.js +83 -0
  118. package/lib/router/params.js.map +1 -0
  119. package/lib/router/router.d.ts +11 -0
  120. package/lib/router/router.js +204 -0
  121. package/lib/router/router.js.map +1 -0
  122. package/lib/session/session.d.ts +16 -0
  123. package/lib/session/session.js +64 -0
  124. package/lib/session/session.js.map +1 -0
  125. package/lib/skill.d.ts +17 -0
  126. package/lib/skill.js +56 -0
  127. package/lib/skill.js.map +1 -0
  128. package/lib/storage/atomic.d.ts +10 -0
  129. package/lib/storage/atomic.js +107 -0
  130. package/lib/storage/atomic.js.map +1 -0
  131. package/lib/storage/paths.d.ts +10 -0
  132. package/lib/storage/paths.js +50 -0
  133. package/lib/storage/paths.js.map +1 -0
  134. package/lib/storage/records.d.ts +16 -0
  135. package/lib/storage/records.js +112 -0
  136. package/lib/storage/records.js.map +1 -0
  137. package/lib/storage/sessions.d.ts +17 -0
  138. package/lib/storage/sessions.js +65 -0
  139. package/lib/storage/sessions.js.map +1 -0
  140. package/lib/tools/tools.d.ts +14 -0
  141. package/lib/tools/tools.js +472 -0
  142. package/lib/tools/tools.js.map +1 -0
  143. package/lib/transport/http.d.ts +3 -0
  144. package/lib/transport/http.js +217 -0
  145. package/lib/transport/http.js.map +1 -0
  146. package/locale/en.json +6 -0
  147. package/locale/zh.json +6 -0
  148. package/package.json +97 -4
@@ -0,0 +1,323 @@
1
+ # Implementation Plan (V1)
2
+
3
+ > Status: ordered, executable plan for the V1 scope defined in
4
+ > [`design.md`](design.md) and [`detailed-design.md`](detailed-design.md).
5
+ > Every task ends with a build, its tests, and a documentation touch where behavior
6
+ > changed. Do not reorder P1–P4: each later phase imports the previous one's types.
7
+ >
8
+ > Implementation snapshot (2026-11-01): T01, T03–T22 are implemented; `npm run build` and
9
+ > 34 Vitest tests pass. The bundle is installed in the `desktop` profile and live-verified
10
+ > for tools, HTTP API and slot registration. T02 live approval/credential probes, visual
11
+ > panel QA and the final smoke checklist remain. See
12
+ > [`current-state.md`](../00-project/current-state.md).
13
+
14
+ ## 1. Deliverable
15
+
16
+ A DSH bundle that:
17
+
18
+ 1. registers ten `env_*` tools;
19
+ 2. stores an environment/service/deployment/rule/binding registry as YAML files;
20
+ 3. resolves layered rules with provenance;
21
+ 4. routes operations to Skills without executing them;
22
+ 5. exposes a same-origin HTTP API and a Web/Desktop management panel;
23
+ 6. keeps session defaults isolated per session.
24
+
25
+ ## 2. Foundations
26
+
27
+ ### T01 — Build skeleton
28
+
29
+ Files:
30
+
31
+ - `package.json`: scripts, dependencies, `files`, `exports`, `dsh`.
32
+ - `tsconfig.json`: `target ES2022`, `module NodeNext`, `moduleResolution NodeNext`,
33
+ `strict`, `declaration`, `outDir lib`, `rootDir src`, `sourceMap false`.
34
+ - `.gitignore`: add `data/`, `lib/`, `*.tsbuildinfo`.
35
+ - `index.js`: `export * from './lib/index.js'`.
36
+ - `src/index.ts`: minimal `apply` that logs the resolved data dir.
37
+
38
+ Scripts:
39
+
40
+ ```json
41
+ {
42
+ "build": "tsc -p tsconfig.json",
43
+ "build:watch": "tsc -p tsconfig.json --watch",
44
+ "test": "vitest run",
45
+ "test:watch": "vitest",
46
+ "check:client": "node --check client.js"
47
+ }
48
+ ```
49
+
50
+ Dependencies:
51
+
52
+ | Package | Kind | Version |
53
+ |---|---|---|
54
+ | `@deepseek-ai/dsh-tools` | peer + dev | `0.2.1-rc.5` |
55
+ | `@deepseek-ai/dsh-llm` | peer + dev | `0.2.1-rc.5` |
56
+ | `@deepseek-ai/cordis` | peer + dev (type-only) | `~4.0.5` |
57
+ | `@deepseek-ai/schemastery` | dependency | `^3.18.5` |
58
+ | `zod` | dependency | `^4` |
59
+ | `yaml` | dependency | `^2` |
60
+ | `typescript`, `vitest`, `@types/node` | dev | latest compatible |
61
+
62
+ Acceptance: `npm install && npm run build && node --check client.js` succeeds; `lib/index.js`
63
+ exists; no `data/` is tracked.
64
+
65
+ Risk: npm publishes `0.2.1-rc.5` under a non-`latest` tag (verify with
66
+ `npm view <pkg> versions`). If a peer cannot be resolved, fall back to local ambient
67
+ declarations in `src/types/dsh.d.ts` and keep runtime imports unchanged.
68
+
69
+ ### T02 — Runtime probes
70
+
71
+ Verify `api-verification.md` §4 V1–V8 against a live profile, in this order:
72
+
73
+ 1. `profileContext.dir` and write permission.
74
+ 2. `slots.register` with `main`/`key`.
75
+ 3. `fetch('/env-manager/api')` from the panel (after T18).
76
+ 4. `approval.request` from a tool body.
77
+ 5. Output schema with `additionalProperties: true`.
78
+ 6. `CredentialRef` accepting a plain string.
79
+ 7. Windows directory behavior (no watcher required in V1).
80
+ 8. `/env-manager/api` prefix not claimed by the shell.
81
+
82
+ Record the outcome in `api-verification.md` §4 (replace "verify" with the result).
83
+ Acceptance: each item has a pass/fail note and, on failure, the fallback is applied.
84
+
85
+ ## 3. Domain and storage
86
+
87
+ ### T03 — Domain model
88
+
89
+ Files: `src/domain/types.ts`, `src/domain/schemas.ts`, `src/domain/constants.ts`,
90
+ `src/domain/errors.ts`.
91
+
92
+ Include: enums, record interfaces, Zod schemas, `parseRecord`, `ErrorCode` union,
93
+ `EnvManagerError`, `normalizeId`, `nowIso`.
94
+
95
+ Tests (`tests/domain/schemas.test.ts`): valid records from the docs; unknown keys
96
+ (rejected on save, preserved on read); bad id; bad timestamp; `location.kind` mismatch;
97
+ empty `deployModes`.
98
+
99
+ Acceptance: every YAML example in `docs/05-domain/*.md` parses.
100
+
101
+ ### T04 — Storage
102
+
103
+ Files: `src/storage/paths.ts`, `atomic.ts`, `records.ts`, `sessions.ts`, `layout.ts`.
104
+
105
+ Behavior: data dir resolution (§4.1), id/path guards, atomic write with backup
106
+ rotation, read with diagnostics, delete, session read/write, startup `.tmp` cleanup.
107
+
108
+ Tests (`tests/storage/*.test.ts`): round trip; missing file; invalid YAML; traversal
109
+ rejection; backup cap; concurrent writes serialize; session corrupt fallback.
110
+
111
+ Acceptance: no write leaves a partial file; a killed write leaves only a `.tmp`.
112
+
113
+ ## 4. Registry
114
+
115
+ ### T05 — Loader and snapshot
116
+
117
+ Files: `src/registry/registry.ts`, `src/registry/aliases.ts`.
118
+
119
+ Behavior: scan five directories, parse, skip invalid with diagnostics, duplicate id,
120
+ alias map, deterministic ordering, in-flight dedupe, reload per request.
121
+
122
+ Tests: empty dirs; mixed valid/invalid; duplicate id; alias collision; reload after
123
+ write.
124
+
125
+ ### T06 — Integrity
126
+
127
+ Files: `src/registry/integrity.ts`.
128
+
129
+ Behavior: table in `detailed-design.md` §6.3, diagnostics only.
130
+
131
+ Tests: each reference kind missing; a completely consistent fixture yields zero
132
+ errors.
133
+
134
+ ## 5. Resolver
135
+
136
+ ### T07 — Template engine
137
+
138
+ Files: `src/resolver/template.ts`, `src/resolver/graph.ts`.
139
+
140
+ Behavior: scanner (§7.1), ref graph, iterative DFS, cycle path, undefined refs.
141
+
142
+ Tests: literals; multiple refs; malformed `${`; `}` alone; cycle A→B→A; self-cycle;
143
+ undefined; 2048-char cap.
144
+
145
+ ### T08 — Layers, merge, context
146
+
147
+ Files: `src/resolver/layers.ts`, `merge.ts`, `context.ts`, `provenance.ts`.
148
+
149
+ Behavior: ordered layers, field-level merge, shadowed list, eager field selection,
150
+ runtime-specific log source and class location, path traversal check, provenance.
151
+
152
+ Tests: the worked example from `design.md` §6.9; environment override changes a
153
+ dependent path while `definedBy` stays at the service layer; deployment variables win;
154
+ missing optional deployment.
155
+
156
+ Acceptance: AC-03 and AC-04 pass.
157
+
158
+ ## 6. Router
159
+
160
+ ### T09 — Matching and selection
161
+
162
+ Files: `src/router/match.ts`, `src/router/router.ts`.
163
+
164
+ Behavior: eligibility, level derivation, top-level selection, same-level conflict with
165
+ all candidates.
166
+
167
+ Tests: each level; higher level wins; disabled binding ignored; conflict; no binding.
168
+
169
+ ### T10 — Skills, policy, parameters
170
+
171
+ Files: `src/router/skills.ts`, `policy.ts`, `parameters.ts`.
172
+
173
+ Behavior: `SkillDirectory` adapter over `ctx.skills` (`snapshot`, `complete`), source
174
+ and provider checks, write-operation approval defaults, production denial, template
175
+ parameters.
176
+
177
+ Tests: fake directory for present/missing/incomplete/source mismatch/provider
178
+ mismatch; production denial; parameter failure on unresolved ref; 50-parameter cap.
179
+
180
+ Acceptance: AC-05…AC-07 pass.
181
+
182
+ ## 7. Session and application
183
+
184
+ ### T11 — Session store
185
+
186
+ Files: `src/session/session-context.ts`.
187
+
188
+ Tests: set/get/clear; two sessions isolated; corrupt file; unwritable dir →
189
+ `persisted: false`.
190
+
191
+ ### T12 — Application service
192
+
193
+ Files: `src/app/app.ts`, `src/app/actor.ts`.
194
+
195
+ Behavior: `meta/list/get/find/save/saveYaml/remove/validate/resolve/route` and context
196
+ access, actor policy, dry-run validation, record cap.
197
+
198
+ Tests: save→get; delete referenced; dry-run writes nothing; UI production denial;
199
+ `find` by alias.
200
+
201
+ Acceptance: AC-01, AC-02, AC-08 pass at this layer.
202
+
203
+ ## 8. Tools
204
+
205
+ ### T13 — Tool scaffolding
206
+
207
+ Files: `src/tools/define.ts`, `src/tools/envelope.ts`, `src/tools/approval.ts`.
208
+
209
+ Shared schemas, `render` helpers, `EnvManagerError` mapping, approval helper.
210
+
211
+ ### T14 — Read tools
212
+
213
+ Files: `src/tools/read.ts` (`env_list`, `env_get`, `env_find`, `env_get_context`).
214
+
215
+ Tests: output matches schema for each; invalid id code; empty registry; context with
216
+ and without a default.
217
+
218
+ ### T15 — Resolve and route tools
219
+
220
+ Files: `src/tools/resolve.ts` (`env_resolve`, `env_resolve_operation`).
221
+
222
+ Tests: session default fallback; ambiguous deployment; conflict; skill unavailable;
223
+ production denial.
224
+
225
+ ### T16 — Write tools
226
+
227
+ Files: `src/tools/write.ts` (`env_set_context`, `env_save`, `env_delete`).
228
+
229
+ Tests: create/update; dry-run; approval grant and denial; production save approval;
230
+ delete referenced → `RECORD_IN_USE`; delete approved removes the file.
231
+
232
+ ### T17 — Validate tool
233
+
234
+ Files: `src/tools/validate.ts`.
235
+
236
+ Tests: clean fixture → `ok: true`; broken reference appears with file and code.
237
+
238
+ Acceptance: all ten tools are visible and match `tool-contract.md`.
239
+
240
+ ## 9. HTTP transport
241
+
242
+ ### T18 — Route
243
+
244
+ Files: `src/transport/route.ts`, `src/transport/auth.ts`, `src/transport/ops.ts`,
245
+ `src/transport/envelope.ts`.
246
+
247
+ Behavior: registration, header and origin checks, body limit, op table, status map,
248
+ actor `'ui'`, logging.
249
+
250
+ Tests (node http mocks): missing header 403; wrong origin 403; GET 405; oversize 413;
251
+ unknown op 400; not found 404; conflict 409; production write 403; happy path 200.
252
+
253
+ Acceptance: `curl` with the header returns `meta`; without it returns 403.
254
+
255
+ ## 10. Client
256
+
257
+ ### T19 — Module shell
258
+
259
+ Files: `client.js`.
260
+
261
+ Behavior: module loader wrapper, `inject`, locale registration (`en`/`zh`), sidebar
262
+ registration, `main` panel registration, `call()` helper, shared UI atoms.
263
+
264
+ Acceptance: panel appears; empty state renders; no console error.
265
+
266
+ ### T20 — Lists and editor
267
+
268
+ Behavior: Overview, record lists with search, YAML editor with validate/save/delete,
269
+ dirty guard, production banner.
270
+
271
+ Acceptance: manual QA items 1–8 in `ui-design.md` §12.
272
+
273
+ ### T21 — Context, operation, diagnostics
274
+
275
+ Behavior: provenance tables with expansion, binding selection with conflict card,
276
+ diagnostics table, bundle config page.
277
+
278
+ Acceptance: manual QA items 9–12.
279
+
280
+ ### T22 — Manual QA pass
281
+
282
+ Run the full checklist in `ui-design.md` §12 in Web and Desktop, light and dark, `en`
283
+ and `zh`. Record results in `current-state.md`.
284
+
285
+ ## 11. Packaging and release
286
+
287
+ ### T23 — Docs and state
288
+
289
+ Update `docs/00-project/current-state.md`, `docs/README.md` index if files moved, and
290
+ `README.md` status. No architecture change without an ADR.
291
+
292
+ ### T24 — Install smoke test
293
+
294
+ Install with `plugin_manager` (`install_bundle`, target = repository path), restart
295
+ DSH, run:
296
+
297
+ 1. `env_validate` → clean;
298
+ 2. `env_list` → includes a fixture created by `env_save`;
299
+ 3. open the panel → Overview counts match;
300
+ 4. set a session default with `env_set_context`, reopen the session, `env_get_context`
301
+ returns it;
302
+ 5. remove the fixture with `env_delete` (approval), confirm the file is gone.
303
+
304
+ ## 12. Cut line
305
+
306
+ If time runs short, ship in this order and stop at a green build:
307
+
308
+ 1. P0–P7 (Host complete, tools work through the agent).
309
+ 2. T18 + T19–T20 (read/write UI for environments and services).
310
+ 3. T21 (context/operation preview and diagnostics).
311
+ 4. T22 full QA.
312
+
313
+ Never cut: storage atomicity, resolver provenance, router conflict handling, approval
314
+ on delete, credential redaction.
315
+
316
+ ## 13. Definition of done
317
+
318
+ - [ ] `npm run build` clean.
319
+ - [ ] `npm test` green with the coverage in `detailed-design.md` §16.
320
+ - [ ] Ten tools registered and documented.
321
+ - [ ] Manual QA checklist complete.
322
+ - [ ] No plain-text credential; no `..` path escape; no auto-apply.
323
+ - [ ] `current-state.md` reflects what shipped and what did not.
@@ -0,0 +1,306 @@
1
+ # Module Boundaries
2
+
3
+ Status: normative for V1.
4
+
5
+ Modules are directories under `src/` (Host, TypeScript). The Client half is a single `client.js` module at the repository root.
6
+
7
+ Related: [design.md](./design.md) §3, [detailed-design.md](./detailed-design.md) §2, [storage-contract.md](./storage-contract.md), [tool-contract.md](./tool-contract.md).
8
+
9
+ ---
10
+
11
+ ## 1. Dependency direction
12
+
13
+ ```text
14
+ tools ────────┐
15
+ ├──▶ app ──▶ resolver ──▶ registry ──▶ storage ──▶ fs
16
+ transport ────┘ │ │ │
17
+ │ └──▶ domain ◀┘
18
+ ├──▶ router ──▶ resolver (context only)
19
+ ├──▶ session ──▶ storage
20
+ └──▶ memory-bridge ──▶ (external contract)
21
+
22
+ client ──▶ transport (HTTP) ──▶ app
23
+ ```
24
+
25
+ Rules:
26
+
27
+ - `domain` has no dependencies.
28
+ - `storage` depends on `domain`.
29
+ - `registry` depends on `storage` and `domain`.
30
+ - `resolver` and `router` depend on `domain` and `registry` types, never on `storage` or `tools`.
31
+ - `app` composes storage, registry, resolver, router, session and config; it is the only
32
+ module that knows all of them.
33
+ - `tools` and `transport` depend on `app` and `domain`; neither contains business logic
34
+ and neither imports the other.
35
+ - No module imports `tools` or `transport` except the Host entry point (`src/index.ts`).
36
+ - `client.js` depends on the HTTP API, never on `src/` modules.
37
+
38
+ Cycles are forbidden. A cycle means the boundary is wrong.
39
+
40
+ ---
41
+
42
+ ## 2. `domain`
43
+
44
+ Owns the shapes.
45
+
46
+ Allowed:
47
+
48
+ - TypeScript interfaces and type guards for all records, results and diagnostics.
49
+ - Zod schemas that mirror the interfaces.
50
+ - Enums and constants (operation ids, categories, runtime modes).
51
+ - Pure helpers that operate on the types.
52
+
53
+ Forbidden:
54
+
55
+ - File I/O.
56
+ - Tool registration.
57
+ - Resolution or routing logic.
58
+ - Importing any other project module.
59
+
60
+ ---
61
+
62
+ ## 3. `storage`
63
+
64
+ Owns bytes on disk.
65
+
66
+ Responsibilities:
67
+
68
+ - Resolve `dataDir` and create directories.
69
+ - Read, parse, validate and write one record file.
70
+ - Atomic write protocol.
71
+ - Rolling backups.
72
+ - Session state files.
73
+ - Surface storage errors as typed errors with codes.
74
+
75
+ Forbidden:
76
+
77
+ - Cross-record validation (registry owns it).
78
+ - Template resolution.
79
+ - Skill matching.
80
+ - Credential access.
81
+
82
+ ---
83
+
84
+ ## 4. `registry`
85
+
86
+ Owns the in-memory view.
87
+
88
+ Responsibilities:
89
+
90
+ - Load all record directories into maps.
91
+ - Reload affected entries after writes.
92
+ - Enforce id uniqueness and filename/id agreement.
93
+ - Enforce referential integrity (data-model §12).
94
+ - Provide lookups: by id, by alias, list by category, deployments by service, deployments by environment.
95
+ - Produce load diagnostics.
96
+
97
+ Forbidden:
98
+
99
+ - Writing files (uses `storage`).
100
+ - Running templates.
101
+ - Registering tools.
102
+ - Holding mutable session state.
103
+
104
+ ---
105
+
106
+ ## 5. `resolver`
107
+
108
+ Owns context and rule resolution.
109
+
110
+ Responsibilities:
111
+
112
+ - Select the deployment binding (explicit id or unique match).
113
+ - Merge rule layers with field-level precedence.
114
+ - Resolve templates with cycle detection and undefined-variable detection.
115
+ - Validate resolved paths.
116
+ - Build `ServiceContext` with provenance.
117
+ - Build `ProvenanceEntry[]`.
118
+
119
+ Forbidden:
120
+
121
+ - File I/O.
122
+ - Tool registration.
123
+ - Credential resolution (status is injected by the caller).
124
+ - Skill matching.
125
+
126
+ Purity is required: all inputs are passed in, no globals, no clocks, no randomness.
127
+
128
+ ---
129
+
130
+ ## 6. `router`
131
+
132
+ Owns operation-to-Skill matching.
133
+
134
+ Responsibilities:
135
+
136
+ - Classify each binding's match level.
137
+ - Filter by eligibility.
138
+ - Detect same-level conflicts.
139
+ - Verify Skill references through an injected `SkillDirectory` interface.
140
+ - Evaluate approval and production policy.
141
+ - Map parameters with the resolver's template engine.
142
+ - Build `OperationResolution` with diagnostics.
143
+
144
+ Forbidden:
145
+
146
+ - Executing Skills.
147
+ - Reading files.
148
+ - Accessing credentials.
149
+ - Choosing a fallback binding.
150
+
151
+ `SkillDirectory` is an interface, so tests use a fake and the Host adapter uses the real registry when available.
152
+
153
+ ---
154
+
155
+ ## 7. `session`
156
+
157
+ Owns per-session default environment.
158
+
159
+ Responsibilities:
160
+
161
+ - `get(sessionId)`, `set(sessionId, environmentId | null)`.
162
+ - Persist through `storage` (or the DSH session API when available).
163
+ - Expose `{ environmentId, persisted }` to tools.
164
+
165
+ Forbidden:
166
+
167
+ - Mutating registry records.
168
+ - Reading other sessions' state.
169
+ - Deciding policy.
170
+
171
+ ---
172
+
173
+ ## 8. `app`
174
+
175
+ Owns the use cases. One function per tool and per HTTP operation.
176
+
177
+ Responsibilities:
178
+
179
+ - Compose storage, registry, resolver, router and session for a request.
180
+ - Apply the record cap, actor policy and dry-run.
181
+ - Reload the registry after a successful write.
182
+ - Return domain results or throw `EnvManagerError`.
183
+
184
+ Forbidden:
185
+
186
+ - Tool registration or HTTP parsing.
187
+ - Rendering text for the model or the UI.
188
+ - Re-implementing resolution, routing or persistence.
189
+
190
+ `app` is the only module both `tools` and `transport` call, so the two surfaces cannot
191
+ drift.
192
+
193
+ ---
194
+
195
+ ## 9. `memory-bridge`
196
+
197
+ Owns the optional P1 integration.
198
+
199
+ Responsibilities:
200
+
201
+ - Define `MemoryBridge`, `MemoryScope`, `OperationRecord`, proposal types.
202
+ - Provide a null adapter that reports `MEMORY_BRIDGE_UNAVAILABLE`.
203
+ - Redact and bound records before emission.
204
+
205
+ Forbidden:
206
+
207
+ - Writing registry files.
208
+ - Auto-applying proposals.
209
+ - Owning a second copy of environment facts.
210
+
211
+ ---
212
+
213
+ ## 10. `tools`
214
+
215
+ Owns the Agent-facing surface.
216
+
217
+ Responsibilities:
218
+
219
+ - Register `defineTool` definitions with `ctx.tools.register`.
220
+ - Declare parameter and output schemas.
221
+ - Apply approval gates for management writes.
222
+ - Map `app` results to the declared JSON value and `render` text.
223
+ - Throw `EnvManagerError` for expected failures.
224
+
225
+ Forbidden:
226
+
227
+ - Business logic beyond orchestration.
228
+ - Direct file access.
229
+ - Re-implementing resolution, routing or persistence.
230
+
231
+ ---
232
+
233
+ ## 11. `transport`
234
+
235
+ Owns the Client-facing HTTP surface.
236
+
237
+ Responsibilities:
238
+
239
+ - Register and dispose the `/env-manager/api` route.
240
+ - Enforce method, content type, request header, origin and body limits.
241
+ - Map `{ op, payload }` to `app` calls.
242
+ - Map `EnvManagerError` codes to status codes.
243
+ - Log writes with actor, op, kind, id and outcome.
244
+
245
+ Forbidden:
246
+
247
+ - Business logic.
248
+ - Reading credentials.
249
+ - CORS headers or cookie handling.
250
+ - Serving files or static assets.
251
+
252
+ ---
253
+
254
+ ## 12. `config`
255
+
256
+ Owns plugin configuration.
257
+
258
+ Responsibilities:
259
+
260
+ - Define the config schema (`dataDir`, limits).
261
+ - Validate at activation.
262
+ - Provide resolved defaults.
263
+
264
+ Forbidden:
265
+
266
+ - Reading registry files at config-validation time.
267
+ - Network access.
268
+
269
+ ---
270
+
271
+ ## 13. `client.js`
272
+
273
+ Owns the Web/Desktop surface.
274
+
275
+ Allowed:
276
+
277
+ - Render panels and forms.
278
+ - Call the plugin HTTP API.
279
+ - Use the client locale, slots and theme services.
280
+ - Register slots and clean up on unmount.
281
+
282
+ Forbidden:
283
+
284
+ - Reading or writing registry files.
285
+ - Re-implementing rule resolution or routing.
286
+ - Holding durable state outside the Host.
287
+ - Global side effects at module load.
288
+
289
+ ---
290
+
291
+ ## 14. Host entry
292
+
293
+ `src/index.ts` is the only place that wires modules together.
294
+
295
+ Responsibilities:
296
+
297
+ - Read config, build storage/registry/resolver/router/session/app.
298
+ - Register tools and their cleanup.
299
+ - Register the HTTP route and its cleanup.
300
+ - Register the Client module metadata.
301
+ - Log the resolved data directory once.
302
+
303
+ Forbidden:
304
+
305
+ - Business logic.
306
+ - Direct tool or transport implementations.