dflow-sdd-ddd 0.3.0 → 0.5.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 (39) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README.en.md +7 -9
  3. package/README.md +10 -12
  4. package/TEMPLATE-COVERAGE.md +1 -1
  5. package/bin/dflow.js +11 -5
  6. package/docs/evaluating-dflow.en.md +2 -5
  7. package/docs/evaluating-dflow.md +1 -3
  8. package/docs/examples-by-stack.md +516 -0
  9. package/docs/migrating-to-dflow-v1.md +1 -1
  10. package/docs/release-versioning-policy.md +13 -0
  11. package/docs/using-with-claude-code.en.md +38 -8
  12. package/docs/using-with-claude-code.md +33 -7
  13. package/docs/using-with-codex.en.md +31 -5
  14. package/docs/using-with-codex.md +28 -5
  15. package/docs/using-with-github-copilot.en.md +29 -5
  16. package/docs/using-with-github-copilot.md +28 -5
  17. package/lib/init.js +437 -46
  18. package/package.json +1 -1
  19. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +42 -3
  20. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +25 -15
  21. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +1 -1
  22. package/templates/brownfield/scaffolding/Git-principles-trunk.md +1 -1
  23. package/templates/brownfield/scaffolding/_conventions.md +1 -1
  24. package/templates/brownfield/scaffolding/_overview.md +40 -29
  25. package/templates/brownfield/templates/CLAUDE.md +25 -17
  26. package/templates/brownfield/templates/context-definition.md +4 -4
  27. package/templates/brownfield/templates/context-map.md +1 -1
  28. package/templates/brownfield/templates/lightweight-spec.md +3 -1
  29. package/templates/brownfield/templates/models.md +1 -1
  30. package/templates/brownfield/templates/phase-spec.md +10 -8
  31. package/templates/brownfield/templates/tech-debt.md +2 -2
  32. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +42 -3
  33. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +7 -6
  34. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +2 -2
  35. package/templates/greenfield/scaffolding/Git-principles-trunk.md +2 -2
  36. package/templates/greenfield/scaffolding/_overview.md +29 -11
  37. package/templates/greenfield/templates/CLAUDE.md +5 -5
  38. package/docs/using-with-gemini-cli.en.md +0 -200
  39. package/docs/using-with-gemini-cli.md +0 -184
@@ -0,0 +1,516 @@
1
+ # Examples by Stack
2
+
3
+ > A per-stack appendix to Dflow templates. Dflow itself is language- and
4
+ > framework-agnostic; this document shows what canonical placeholders
5
+ > (`{Language}` / `{Framework}` / `{Framework version}` / `{ORM / persistence}`
6
+ > / `{ORM version}` / `{Mediator}` / `{Test framework}`) and stack-neutral
7
+ > prose look like once filled in for common stacks.
8
+ >
9
+ > **How to use this**: after running `dflow init`, open
10
+ > `dflow/specs/shared/_overview.md` and your root `CLAUDE.md`. Replace
11
+ > placeholder rows / directory trees / dependency lists with the snippets
12
+ > from your stack's section below. Adapt as needed — these are starting
13
+ > points, not prescriptions.
14
+
15
+ ## Index
16
+
17
+ - [.NET / ASP.NET Core (Greenfield)](#net--aspnet-core-greenfield)
18
+ - [.NET / ASP.NET WebForms (Brownfield)](#net--aspnet-webforms-brownfield)
19
+ - [Java / Spring Boot (Greenfield)](#java--spring-boot-greenfield) — Kotlin/Spring same pattern
20
+ - [Node.js / TypeScript / NestJS (Greenfield)](#nodejs--typescript--nestjs-greenfield)
21
+ - [Python / FastAPI (Greenfield)](#python--fastapi-greenfield) — Django/Flask similar
22
+ - [Go / Gin (Greenfield)](#go--gin-greenfield)
23
+ - [PHP / Laravel (Brownfield migration)](#php--laravel-brownfield-migration)
24
+
25
+ Each section provides:
26
+
27
+ 1. **`_overview.md` stack table** — substituted canonical placeholders
28
+ 2. **Project layout** — idiomatic directory / package convention
29
+ 3. **Domain purity check** — the stack's equivalent of "no delivery-framework references" (used in Git-principles checklist)
30
+ 4. **Test framework** — what `{Test framework}` resolves to
31
+
32
+ ---
33
+
34
+ ## .NET / ASP.NET Core (Greenfield)
35
+
36
+ ### `_overview.md` stack table
37
+
38
+ ```markdown
39
+ | Item | Choice |
40
+ |------|--------|
41
+ | Language | C# 12 |
42
+ | Framework | ASP.NET Core 9 |
43
+ | ORM / persistence | Entity Framework Core 9 |
44
+ | Mediator | MediatR 12 |
45
+ | Test framework | xUnit |
46
+ | Database | PostgreSQL 16 |
47
+ | Auth | JWT bearer / OIDC via Azure AD |
48
+ | Hosting | Azure App Service |
49
+ ```
50
+
51
+ ### Project layout
52
+
53
+ ```
54
+ src/
55
+ ├── {Project}.Domain/ # Aggregates, Value Objects, Domain Events
56
+ │ ├── Common/ # Entity, AggregateRoot, ValueObject base classes
57
+ │ ├── {BoundedContext}/
58
+ │ │ ├── Entities/
59
+ │ │ ├── ValueObjects/
60
+ │ │ ├── Events/
61
+ │ │ ├── Services/
62
+ │ │ └── Interfaces/ # Repository / external service interfaces
63
+ │ └── SharedKernel/
64
+ ├── {Project}.Application/ # CQRS handlers, validators, DTOs
65
+ │ ├── Common/
66
+ │ └── {BoundedContext}/
67
+ │ ├── Commands/
68
+ │ ├── Queries/
69
+ │ ├── DTOs/
70
+ │ └── EventHandlers/
71
+ ├── {Project}.Infrastructure/ # EF Core DbContext, repository impls
72
+ │ ├── Persistence/
73
+ │ ├── Repositories/
74
+ │ └── ExternalServices/
75
+ └── {Project}.WebAPI/ # Presentation: HTTP endpoints
76
+
77
+ tests/
78
+ ├── {Project}.Domain.UnitTests/
79
+ ├── {Project}.Application.UnitTests/
80
+ └── {Project}.Integration.Tests/
81
+ ```
82
+
83
+ ### Domain purity check
84
+
85
+ The Domain project's `.csproj` should have **zero** package references
86
+ outside the allow-list (typically just the `SharedKernel`). Specifically
87
+ forbid:
88
+
89
+ - `Microsoft.AspNetCore.*`, `System.Web`
90
+ - `Microsoft.EntityFrameworkCore.*` (Domain declares interfaces; Infrastructure references EF Core)
91
+ - `HttpContext`, `HttpRequest`, `ISession`
92
+ - `Newtonsoft.Json` / `System.Text.Json` attributes on Domain entities
93
+
94
+ CI check example: `dotnet list package` on Domain.csproj — fail if any
95
+ disallowed dependency appears.
96
+
97
+ ### Test framework
98
+
99
+ `xUnit` + `FluentAssertions` + `NSubstitute`. Run with `dotnet test`.
100
+
101
+ ---
102
+
103
+ ## .NET / ASP.NET WebForms (Brownfield)
104
+
105
+ ### `_overview.md` stack table
106
+
107
+ ```markdown
108
+ | Item | Current |
109
+ |------|---------|
110
+ | Language | C# 7 (.NET Framework 4.8) |
111
+ | Framework | ASP.NET WebForms 4.8 |
112
+ | ORM / persistence | Entity Framework 6 (or ADO.NET / Dapper) |
113
+ | Test framework | xUnit / NUnit |
114
+ | Database | SQL Server 2019 |
115
+ | UI | WebForms .aspx + Code-Behind + Bootstrap |
116
+ | Auth | Forms authentication / Windows auth |
117
+ | Hosting | IIS on-prem |
118
+ | Target architecture | ASP.NET Core 8 + Clean Architecture |
119
+ ```
120
+
121
+ ### Project layout
122
+
123
+ ```
124
+ src/
125
+ ├── Domain/ # Extracted domain logic (framework-pure)
126
+ │ ├── {BoundedContext}/
127
+ │ │ ├── Entities/
128
+ │ │ ├── ValueObjects/
129
+ │ │ └── Services/
130
+ │ └── SharedKernel/
131
+ └── WebForms/ # Existing .aspx + .aspx.cs (Code-Behind)
132
+ └── Pages/
133
+ ```
134
+
135
+ ### Domain purity check
136
+
137
+ The Domain assembly must not reference:
138
+
139
+ - `System.Web.*`, `System.Web.UI.*`
140
+ - `HttpContext.Current`, `Session[…]`, `ViewState[…]`
141
+ - Page lifecycle types (`Page`, `Control`)
142
+ - EF6 attributes on Domain entities (use Fluent API in a separate
143
+ configuration class outside Domain)
144
+
145
+ CI check: project reference analyzer on `src/Domain/Domain.csproj`.
146
+
147
+ ### Test framework
148
+
149
+ `xUnit` or `NUnit`. Run with `dotnet test` or `nunit3-console`.
150
+
151
+ ---
152
+
153
+ ## Java / Spring Boot (Greenfield)
154
+
155
+ > Same pattern applies to Kotlin/Spring with minor syntax differences.
156
+
157
+ ### `_overview.md` stack table
158
+
159
+ ```markdown
160
+ | Item | Choice |
161
+ |------|--------|
162
+ | Language | Java 21 |
163
+ | Framework | Spring Boot 3.3 |
164
+ | ORM / persistence | Spring Data JPA / Hibernate 6.5 |
165
+ | Mediator | (none — direct service injection; optional: Spring Modulith) |
166
+ | Test framework | JUnit 5 + AssertJ + Mockito |
167
+ | Database | PostgreSQL 16 |
168
+ | Auth | Spring Security + OAuth2 / OIDC |
169
+ | Hosting | Kubernetes / managed app platform |
170
+ ```
171
+
172
+ ### Project layout
173
+
174
+ ```
175
+ src/
176
+ ├── main/
177
+ │ └── java/com/example/{system}/
178
+ │ ├── domain/ # Aggregates, Value Objects, Domain Events
179
+ │ │ ├── common/ # Base classes (Entity, AggregateRoot, ValueObject)
180
+ │ │ ├── {boundedcontext}/
181
+ │ │ │ ├── entity/
182
+ │ │ │ ├── valueobject/
183
+ │ │ │ ├── event/
184
+ │ │ │ ├── service/
185
+ │ │ │ └── repository/ # Repository interfaces (NOT implementations)
186
+ │ │ └── sharedkernel/
187
+ │ ├── application/ # Command/Query handlers, DTOs
188
+ │ │ ├── command/
189
+ │ │ ├── query/
190
+ │ │ └── dto/
191
+ │ ├── infrastructure/ # JPA repositories, external clients
192
+ │ │ ├── persistence/
193
+ │ │ └── client/
194
+ │ └── web/ # Controllers, REST endpoints
195
+ └── test/
196
+ └── java/com/example/{system}/
197
+ ├── domain/ # Unit tests
198
+ ├── application/
199
+ └── web/ # @SpringBootTest integration
200
+ ```
201
+
202
+ Multi-module Maven/Gradle layouts (one module per layer) are also common
203
+ and recommended for stricter dependency enforcement.
204
+
205
+ ### Domain purity check
206
+
207
+ The Domain package must not import:
208
+
209
+ - `org.springframework.*` (no Spring annotations on Domain entities)
210
+ - `jakarta.persistence.*` / `javax.persistence.*` (no JPA annotations on
211
+ Domain entities; use a separate JPA mapping class in Infrastructure)
212
+ - `jakarta.servlet.*` (no HTTP types)
213
+ - `com.fasterxml.jackson.*` (no serialization annotations on Domain)
214
+
215
+ CI check: ArchUnit rule `noClasses().that().resideInAPackage("..domain..")
216
+ .should().dependOnClassesThat().resideInAnyPackage("org.springframework..", "jakarta.persistence..")`.
217
+
218
+ ### Test framework
219
+
220
+ `JUnit 5` (`org.junit.jupiter`). Run with `./mvnw test` or `./gradlew test`.
221
+
222
+ ---
223
+
224
+ ## Node.js / TypeScript / NestJS (Greenfield)
225
+
226
+ ### `_overview.md` stack table
227
+
228
+ ```markdown
229
+ | Item | Choice |
230
+ |------|--------|
231
+ | Language | TypeScript 5.4 |
232
+ | Framework | NestJS 10 |
233
+ | ORM / persistence | Prisma 5 (or TypeORM / MikroORM) |
234
+ | Mediator | (none — NestJS providers; optional: nestjs-cqrs module) |
235
+ | Test framework | Vitest (or Jest) + supertest |
236
+ | Database | PostgreSQL 16 |
237
+ | Auth | Passport (JWT, OAuth2) |
238
+ | Hosting | Containerized (Docker / Kubernetes / Fly.io) |
239
+ ```
240
+
241
+ ### Project layout
242
+
243
+ ```
244
+ src/
245
+ ├── domain/ # Aggregates, Value Objects, Domain Events
246
+ │ ├── common/ # Base classes
247
+ │ ├── {bounded-context}/
248
+ │ │ ├── entities/
249
+ │ │ ├── value-objects/
250
+ │ │ ├── events/
251
+ │ │ ├── services/
252
+ │ │ └── repositories/ # Interfaces only
253
+ │ └── shared-kernel/
254
+ ├── application/ # Use cases, command/query handlers
255
+ │ ├── commands/
256
+ │ ├── queries/
257
+ │ └── dtos/
258
+ ├── infrastructure/ # Prisma client, external API clients
259
+ │ ├── persistence/
260
+ │ └── external/
261
+ └── presentation/ # NestJS controllers, modules
262
+ └── http/
263
+
264
+ test/
265
+ ├── domain/
266
+ ├── application/
267
+ └── e2e/
268
+ ```
269
+
270
+ ### Domain purity check
271
+
272
+ `src/domain/` files must not import:
273
+
274
+ - `@nestjs/*` (no `@Injectable`, `@Module`, decorators on Domain)
275
+ - `@prisma/client` (Prisma generated client lives in Infrastructure only)
276
+ - `express` / `fastify` types
277
+ - `class-transformer` / `class-validator` (use plain TS types; validation
278
+ in Application layer)
279
+
280
+ CI check: ESLint rule `no-restricted-imports` scoped to `src/domain/**` or
281
+ `dependency-cruiser` rule forbidding cross-layer imports.
282
+
283
+ ### Test framework
284
+
285
+ `Vitest` (or `Jest`). Run with `npm test` or `pnpm test`.
286
+
287
+ ---
288
+
289
+ ## Python / FastAPI (Greenfield)
290
+
291
+ > Django and Flask follow the same layered pattern with framework-specific
292
+ > presentation conventions. Django: views/templates as presentation;
293
+ > Flask: blueprints; FastAPI: routers.
294
+
295
+ ### `_overview.md` stack table
296
+
297
+ ```markdown
298
+ | Item | Choice |
299
+ |------|--------|
300
+ | Language | Python 3.12 |
301
+ | Framework | FastAPI 0.115 |
302
+ | ORM / persistence | SQLAlchemy 2.0 + Alembic (or SQLModel) |
303
+ | Mediator | (none — typed dependency injection via FastAPI Depends) |
304
+ | Test framework | pytest + pytest-asyncio |
305
+ | Database | PostgreSQL 16 |
306
+ | Auth | OAuth2 via fastapi.security (PasswordBearer / JWT) |
307
+ | Hosting | Containerized (Docker / Kubernetes / Fly.io) |
308
+ ```
309
+
310
+ ### Project layout
311
+
312
+ ```
313
+ src/
314
+ ├── domain/ # Aggregates, Value Objects, Domain Events
315
+ │ ├── common/
316
+ │ ├── {bounded_context}/
317
+ │ │ ├── entities.py
318
+ │ │ ├── value_objects.py
319
+ │ │ ├── events.py
320
+ │ │ ├── services.py
321
+ │ │ └── repositories.py # Protocol / abstract base classes
322
+ │ └── shared_kernel/
323
+ ├── application/ # Use cases, DTOs
324
+ │ ├── commands/
325
+ │ ├── queries/
326
+ │ └── dtos/
327
+ ├── infrastructure/ # SQLAlchemy models, external clients
328
+ │ ├── persistence/
329
+ │ └── external/
330
+ └── presentation/ # FastAPI routers
331
+ └── api/
332
+
333
+ tests/
334
+ ├── domain/
335
+ ├── application/
336
+ └── integration/
337
+ ```
338
+
339
+ ### Domain purity check
340
+
341
+ `src/domain/` modules must not import:
342
+
343
+ - `fastapi` / `starlette`
344
+ - `sqlalchemy.*` (use Protocols / dataclasses in Domain; SQLAlchemy models
345
+ live in Infrastructure as separate mapping classes)
346
+ - `pydantic.BaseModel` for Domain entities (use `dataclass` or plain
347
+ classes; Pydantic models belong in DTO / API layer)
348
+
349
+ CI check: `import-linter` (`importlinter.org`) contract forbidding Domain
350
+ imports of presentation/infrastructure packages.
351
+
352
+ ### Test framework
353
+
354
+ `pytest`. Run with `pytest` or `python -m pytest`.
355
+
356
+ ---
357
+
358
+ ## Go / Gin (Greenfield)
359
+
360
+ ### `_overview.md` stack table
361
+
362
+ ```markdown
363
+ | Item | Choice |
364
+ |------|--------|
365
+ | Language | Go 1.22 |
366
+ | Framework | Gin 1.10 (or Echo / Chi) |
367
+ | ORM / persistence | GORM v2 (or sqlx / pgx) |
368
+ | Mediator | (none — interface-based dispatch) |
369
+ | Test framework | go test + testify |
370
+ | Database | PostgreSQL 16 |
371
+ | Auth | JWT middleware / OAuth2 |
372
+ | Hosting | Containerized (Docker / Kubernetes / Fly.io) |
373
+ ```
374
+
375
+ ### Project layout
376
+
377
+ ```
378
+ {module-root}/
379
+ ├── cmd/
380
+ │ └── api/main.go # Application entrypoint
381
+ ├── internal/
382
+ │ ├── domain/ # Aggregates, Value Objects, Domain Events
383
+ │ │ ├── common/
384
+ │ │ ├── {boundedcontext}/
385
+ │ │ │ ├── entity.go
386
+ │ │ │ ├── valueobject.go
387
+ │ │ │ ├── event.go
388
+ │ │ │ ├── service.go
389
+ │ │ │ └── repository.go # Interface only
390
+ │ │ └── sharedkernel/
391
+ │ ├── application/ # Use cases
392
+ │ │ ├── command/
393
+ │ │ └── query/
394
+ │ ├── infrastructure/ # GORM repo impls, external clients
395
+ │ │ ├── persistence/
396
+ │ │ └── external/
397
+ │ └── handler/ # HTTP handlers (Gin routes)
398
+ └── go.mod
399
+ ```
400
+
401
+ `internal/` enforces Go's import boundary — packages outside the module
402
+ cannot import from `internal/...`.
403
+
404
+ ### Domain purity check
405
+
406
+ `internal/domain/` packages must not import:
407
+
408
+ - `github.com/gin-gonic/gin` or any HTTP router package
409
+ - `gorm.io/gorm` (Domain declares repository interfaces; GORM lives in
410
+ Infrastructure)
411
+ - `net/http` types (`http.Request`, `http.ResponseWriter`)
412
+ - Encoding tags (e.g. `gorm:"primaryKey"`, `json:"..."`) on Domain
413
+ entities — keep tag-free, do encoding via separate Infrastructure
414
+ models
415
+
416
+ CI check: `go vet` plus a custom `go-arch-lint` or `golangci-lint` rule
417
+ forbidding `internal/domain` from importing the above.
418
+
419
+ ### Test framework
420
+
421
+ `go test` (standard library) + `stretchr/testify` for assertions.
422
+ Run with `go test ./...`.
423
+
424
+ ---
425
+
426
+ ## PHP / Laravel (Brownfield migration)
427
+
428
+ > Older PHP monoliths (Symfony 2/3, CodeIgniter, custom) follow similar
429
+ > extraction patterns; the snippets below are for a modern Laravel app
430
+ > already on Laravel 10+ that wants to introduce a Domain layer.
431
+
432
+ ### `_overview.md` stack table
433
+
434
+ ```markdown
435
+ | Item | Current |
436
+ |------|---------|
437
+ | Language | PHP 8.3 |
438
+ | Framework | Laravel 11 |
439
+ | ORM / persistence | Eloquent ORM (Active Record pattern — see Domain note) |
440
+ | Test framework | PHPUnit 11 (or Pest 2) |
441
+ | Database | MySQL 8 / MariaDB 10 |
442
+ | UI | Blade templates / Inertia + Vue / API-only |
443
+ | Auth | Laravel Breeze / Sanctum / Passport |
444
+ | Hosting | Laravel Forge / shared hosting / containerized |
445
+ | Target architecture | Same Laravel + extracted Domain layer + repository abstractions |
446
+ ```
447
+
448
+ ### Project layout
449
+
450
+ ```
451
+ app/
452
+ ├── Domain/ # Extracted domain logic (framework-pure)
453
+ │ ├── Common/
454
+ │ ├── {BoundedContext}/
455
+ │ │ ├── Entities/ # Plain PHP classes (NOT Eloquent models)
456
+ │ │ ├── ValueObjects/
457
+ │ │ ├── Events/
458
+ │ │ ├── Services/
459
+ │ │ └── Repositories/ # Interfaces only
460
+ │ └── SharedKernel/
461
+ ├── Application/ # Use cases, command/query handlers
462
+ │ ├── Commands/
463
+ │ └── Queries/
464
+ ├── Infrastructure/ # Eloquent repository implementations
465
+ │ ├── Persistence/
466
+ │ │ ├── Eloquent/ # Eloquent models live HERE, not in Domain
467
+ │ │ └── Repositories/
468
+ │ └── External/
469
+ ├── Http/ # Controllers, middleware (Laravel-managed)
470
+ │ ├── Controllers/
471
+ │ └── Middleware/
472
+ └── Providers/
473
+
474
+ tests/
475
+ ├── Unit/Domain/
476
+ ├── Feature/Application/
477
+ └── Feature/Http/
478
+ ```
479
+
480
+ ### Domain purity check
481
+
482
+ `app/Domain/` classes must not extend / use:
483
+
484
+ - `Illuminate\Database\Eloquent\Model` (Eloquent models are Infrastructure)
485
+ - `Illuminate\Http\Request` / `Response`
486
+ - `Illuminate\Support\Facades\*` (DB, Auth, Cache, etc.)
487
+ - Laravel attribute / trait magic on Domain entities
488
+
489
+ CI check: a Laravel-aware static analysis rule (Larastan / PHPStan with a
490
+ custom architecture rule) forbidding `app/Domain/` from referencing the
491
+ above.
492
+
493
+ ### Test framework
494
+
495
+ `PHPUnit` (`phpunit/phpunit`) or `Pest` (`pestphp/pest`). Run with
496
+ `./vendor/bin/phpunit` or `./vendor/bin/pest`.
497
+
498
+ ---
499
+
500
+ ## Adding your stack
501
+
502
+ If your stack isn't listed (Rust, Ruby/Rails, Kotlin native, Elixir, etc.),
503
+ the pattern is always the same:
504
+
505
+ 1. Identify your stack's **domain layer convention** (folder / package /
506
+ namespace where pure business code lives)
507
+ 2. Identify the **delivery / entrypoint layer** (controllers, handlers,
508
+ routes, CLI commands, message consumers, job runners)
509
+ 3. Identify the **persistence layer** (ORM, query builder, raw driver)
510
+ 4. Domain purity check = "no imports / usings / extends from delivery,
511
+ persistence, or framework runtime packages"
512
+ 5. Express the layer separation in a CI-enforceable rule appropriate to
513
+ the stack (ArchUnit, ESLint, import-linter, go-arch-lint, Larastan,
514
+ etc.)
515
+
516
+ Contributions of additional stacks via PR are welcome.
@@ -163,7 +163,7 @@ shell command instead.
163
163
  V1 separates the canonical project guide from each per-tool
164
164
  instruction file (PROPOSAL-020). The canonical guide lives at
165
165
  `dflow/specs/shared/AI-AGENT-GUIDE.md`. Per-tool files (`AGENTS.md`,
166
- `CLAUDE.md`, `GEMINI.md`, `.github/copilot-instructions.md`) are thin
166
+ `CLAUDE.md`, `.github/copilot-instructions.md`) are thin
167
167
  shims pointing at the canonical guide.
168
168
 
169
169
  If your project's `CLAUDE.md` (or equivalent) was generated by an
@@ -44,6 +44,19 @@ Examples:
44
44
  - Changing command behavior in a way that invalidates existing docs.
45
45
  - Replacing a workflow contract that AI agents rely on.
46
46
 
47
+ Counter-examples (NOT breaking):
48
+
49
+ - Replacing stack-specific framing with stack-neutral umbrella terms when
50
+ the architectural meaning is unchanged (e.g., "Code-Behind" →
51
+ "delivery/entrypoint code") — adopter's existing files are not
52
+ rewritten by Dflow.
53
+ - Renaming an init placeholder if the previous name still resolves via a
54
+ backward-compat alias and the substituted value is identical (e.g.,
55
+ `{ASP.NET Core version}` continuing to resolve while `{Framework version}`
56
+ becomes canonical).
57
+ - Adding a new optional placeholder; existing templates that don't use it
58
+ are unaffected.
59
+
47
60
  ## Release Ownership
48
61
 
49
62
  Dflow currently has four release surfaces:
@@ -81,9 +81,9 @@ custom project instructions you already had.
81
81
 
82
82
  ## Using Dflow Slash Commands in Claude Code
83
83
 
84
- Dflow's `/dflow:*` slash commands are workflow names recognized by the AI
85
- through the workflow table in `AI-AGENT-GUIDE.md`, not Claude Code's
86
- built-in slash command system. You type them as plain chat:
84
+ By default, Dflow's canonical `/dflow:*` slash commands are workflow names
85
+ recognized by the AI through the workflow table in `AI-AGENT-GUIDE.md`, not
86
+ Claude Code's built-in slash command system. You type them as plain chat:
87
87
 
88
88
  ```text
89
89
  /dflow:new-feature
@@ -131,6 +131,27 @@ If you forget a command name, ask Claude Code "what dflow workflows are
131
131
  available?" — the answer comes from the workflow table it already has
132
132
  loaded.
133
133
 
134
+ ### Optional Command Adapters
135
+
136
+ If you want Claude Code to expose tool-native command entries, run this in an
137
+ initialized project:
138
+
139
+ ```bash
140
+ dflow configure-agents --command-adapters
141
+ ```
142
+
143
+ After you select Claude Code, Dflow projects thin wrappers from the command
144
+ registry inside the canonical guide:
145
+
146
+ - `.claude/commands/dflow/dflow-<id>.md`
147
+
148
+ These wrappers use adapter-native names, for example `/dflow-new-feature`.
149
+ Their body only points to the canonical `/dflow:new-feature` workflow and
150
+ `dflow/specs/shared/AI-AGENT-GUIDE.md`; it does not copy workflow steps.
151
+ Dflow v1 does not promise that Claude Code's menu will expose the exact
152
+ colon form `/dflow:new-feature`. The canonical name remains in the guide and
153
+ wrapper body.
154
+
134
155
  ## Differences vs Other AI Tools
135
156
 
136
157
  The canonical guide (`dflow/specs/shared/AI-AGENT-GUIDE.md`) is identical
@@ -140,7 +161,6 @@ across tools. Only the root-level shim differs:
140
161
  |---|---|---|
141
162
  | Claude Code | `CLAUDE.md` | `@dflow/specs/shared/AI-AGENT-GUIDE.md` Markdown import |
142
163
  | Codex / Copilot coding agent | `AGENTS.md` | Reads file content directly when starting |
143
- | Gemini CLI | `GEMINI.md` | `@dflow/specs/shared/AI-AGENT-GUIDE.md` Markdown import |
144
164
  | GitHub Copilot | `.github/copilot-instructions.md` | Reads file content directly |
145
165
 
146
166
  You can run `dflow configure-agents` later to add another tool's shim without
@@ -158,10 +178,20 @@ spec locations, or SDD constraints to `CLAUDE.md`, those belong in
158
178
  `dflow/specs/shared/AI-AGENT-GUIDE.md` instead. The shim stays small so
159
179
  that other tools' shims don't drift away from it.
160
180
 
161
- **`/dflow:*` is not a Claude Code Skill installation.** `init` does not
162
- install anything into Claude Code's skill system. The slash commands are
163
- plain text patterns the AI recognizes from the workflow table. You can use
164
- them immediately after `init` without any Claude Code configuration.
181
+ **Default `/dflow:*` is not a Claude Code Skill installation.** `init` does
182
+ not install anything into Claude Code's skill system. The slash commands are
183
+ plain text patterns the AI recognizes from the workflow table. If you later
184
+ run `dflow configure-agents --command-adapters`, the added files are thin
185
+ command wrappers, not a second workflow definition.
186
+
187
+ **Choose either legacy Claude skills or the installed adapter.** If the
188
+ project still has legacy `.claude/skills/sdd-ddd-*` skills, choose either
189
+ those skills or `--command-adapters`. If they must temporarily coexist, use
190
+ Claude Code skill override / `disable-model-invocation` settings to prevent
191
+ the legacy skill from auto-triggering. Otherwise the same `/dflow:*` intent
192
+ may trigger both the legacy skill and the installed adapter. Installed
193
+ adapter wrappers must stay thin pointers and should not copy workflow
194
+ semantics.
165
195
 
166
196
  **Permission gates and Dflow workflow gates are separate.** Claude Code may
167
197
  ask permission to run a tool (e.g., write a file). Dflow's workflows have
@@ -73,9 +73,9 @@ source-of-truth 檔案路徑,以及核心 SDD/DDD 規則。`CLAUDE.md` shim
73
73
 
74
74
  ## 在 Claude Code 中使用 Dflow Slash Commands
75
75
 
76
- Dflow 的 `/dflow:*` slash commands 是 AI 透過 `AI-AGENT-GUIDE.md` 中的
77
- workflow 表識別的 workflow 名稱,不是 Claude Code 內建的 slash command 系統。
78
- 你以普通對話方式輸入它們:
76
+ 預設情況下,Dflow 的 canonical `/dflow:*` slash commands 是 AI 透過
77
+ `AI-AGENT-GUIDE.md` 中的 workflow 表識別的 workflow 名稱,不是 Claude Code
78
+ 內建的 slash command 系統。你以普通對話方式輸入它們:
79
79
 
80
80
  ```text
81
81
  /dflow:new-feature
@@ -120,6 +120,25 @@ skill 檔案來執行它們。
120
120
  如果你忘了指令名稱,問 Claude Code「what dflow workflows are available?」
121
121
  即可 —— 答案會從它已載入的 workflow 表中給出。
122
122
 
123
+ ### 選配 Command Adapters
124
+
125
+ 如果想讓 Claude Code 看到工具原生的命令入口,可在已初始化的專案中執行:
126
+
127
+ ```bash
128
+ dflow configure-agents --command-adapters
129
+ ```
130
+
131
+ 選擇 Claude Code 後,Dflow 會從 canonical guide 內的 command registry
132
+ 投影產生薄 wrapper:
133
+
134
+ - `.claude/commands/dflow/dflow-<id>.md`
135
+
136
+ 這些 wrapper 使用 adapter-native 命名,例如 `/dflow-new-feature`。Wrapper
137
+ 內容只指向 canonical `/dflow:new-feature` workflow 與
138
+ `dflow/specs/shared/AI-AGENT-GUIDE.md`,不複製 workflow 步驟。Dflow v1 不承諾
139
+ Claude Code 選單中一定會出現 exact `/dflow:new-feature` colon 形式;canonical
140
+ 名稱仍保留在 guide 與 wrapper body 中。
141
+
123
142
  ## 與其他 AI 工具的差異
124
143
 
125
144
  canonical 指南(`dflow/specs/shared/AI-AGENT-GUIDE.md`)在各工具之間是相同的。
@@ -129,7 +148,6 @@ canonical 指南(`dflow/specs/shared/AI-AGENT-GUIDE.md`)在各工具之間
129
148
  |---|---|---|
130
149
  | Claude Code | `CLAUDE.md` | `@dflow/specs/shared/AI-AGENT-GUIDE.md` Markdown import |
131
150
  | Codex / Copilot coding agent | `AGENTS.md` | 啟動時直接讀取檔案內容 |
132
- | Gemini CLI | `GEMINI.md` | `@dflow/specs/shared/AI-AGENT-GUIDE.md` Markdown import |
133
151
  | GitHub Copilot | `.github/copilot-instructions.md` | 直接讀取檔案內容 |
134
152
 
135
153
  你可以之後執行 `dflow configure-agents` 來新增另一個工具的 shim,而不需要重跑
@@ -146,9 +164,17 @@ SDD 約束加入 `CLAUDE.md`,這些內容應該放到
146
164
  `dflow/specs/shared/AI-AGENT-GUIDE.md`。shim 保持精簡,其他工具的 shim 才不會
147
165
  與它產生漂移(drift)。
148
166
 
149
- **`/dflow:*` 不是安裝 Claude Code Skill。** `init` 不會在 Claude Code 的 skill
150
- 系統中安裝任何東西。Slash commands 是 AI 從 workflow 表識別的純文字模式。
151
- 你在 `init` 之後就可以立即使用它們,不需要任何 Claude Code 設定。
167
+ **預設 `/dflow:*` 不是安裝 Claude Code Skill。** `init` 不會在 Claude Code 的
168
+ skill 系統中安裝任何東西。Slash commands 是 AI 從 workflow 表識別的純文字模式。
169
+ 若你之後執行 `dflow configure-agents --command-adapters`,新增的是薄 command
170
+ wrapper,不是 workflow 的第二份定義。
171
+
172
+ **legacy Claude skill 與 installed adapter 擇一。** 如果專案仍保留舊的
173
+ `.claude/skills/sdd-ddd-*` skill,請在 legacy skill 與 `--command-adapters`
174
+ 之間擇一使用。若必須暫時共存,請用 Claude Code 的 skill override /
175
+ `disable-model-invocation` 設定避免 legacy skill 自動觸發,否則同一個
176
+ `/dflow:*` 意圖可能同時觸發 legacy skill 與 installed adapter。Installed
177
+ adapter wrapper 必須保持薄指標,不應複製 workflow 語義。
152
178
 
153
179
  **Permission gates 與 Dflow workflow gates 是分開的。** Claude Code 可能會詢問
154
180
  執行某個工具的權限(例如寫入檔案)。Dflow 的 workflow 有自己的審核關卡(例如