@llblab/pi-kit 0.3.1 → 0.4.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.
- package/AGENTS.md +3 -3
- package/BACKLOG.md +1 -1
- package/CHANGELOG.md +10 -0
- package/README.md +19 -10
- package/node_modules/@llblab/pi-actors/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +6 -0
- package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +16 -6
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/SKILL.md +3 -3
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/genapps/music-player.mjs +6 -4
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback.mjs +85 -18
- package/node_modules/@llblab/pi-actors/dist/skills/swarm/SKILL.md +2 -6
- package/node_modules/@llblab/pi-actors/dist/skills/swarm/references/development-swarm.md +2 -31
- package/node_modules/@llblab/pi-actors/docs/recipe-library.md +1 -1
- package/node_modules/@llblab/pi-actors/package.json +1 -1
- package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +16 -6
- package/node_modules/@llblab/pi-actors/skills/music-player/SKILL.md +3 -3
- package/node_modules/@llblab/pi-actors/skills/music-player/genapps/music-player.mjs +6 -4
- package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback.mjs +85 -18
- package/node_modules/@llblab/pi-actors/skills/swarm/SKILL.md +2 -6
- package/node_modules/@llblab/pi-actors/skills/swarm/references/development-swarm.md +2 -31
- package/node_modules/@llblab/pi-clean-room/AGENTS.md +5 -0
- package/node_modules/@llblab/pi-clean-room/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-clean-room/CHANGELOG.md +15 -0
- package/node_modules/@llblab/pi-clean-room/README.md +61 -0
- package/node_modules/@llblab/pi-clean-room/banner.jpg +0 -0
- package/node_modules/@llblab/pi-clean-room/index.ts +178 -0
- package/node_modules/@llblab/pi-clean-room/package.json +53 -0
- package/node_modules/@llblab/pi-grow-loop/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -0
- package/node_modules/@llblab/pi-grow-loop/package.json +1 -1
- package/node_modules/@llblab/pi-grow-loop/skills/grow-loop/SKILL.md +3 -17
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +28 -0
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +79 -0
- package/node_modules/@llblab/pi-state-flow/README.md +197 -0
- package/node_modules/@llblab/pi-state-flow/index.ts +4 -0
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +88 -0
- package/node_modules/@llblab/pi-state-flow/lib/episode.ts +29 -0
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +238 -0
- package/node_modules/@llblab/pi-state-flow/lib/json.ts +78 -0
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +38 -0
- package/node_modules/@llblab/pi-state-flow/lib/session.ts +49 -0
- package/node_modules/@llblab/pi-state-flow/lib/skills.ts +58 -0
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +103 -0
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +20 -0
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +16 -0
- package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +148 -0
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +47 -0
- package/node_modules/@llblab/pi-state-flow/lib/validation.ts +27 -0
- package/node_modules/@llblab/pi-state-flow/package.json +55 -0
- package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +2 -0
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +16 -0
- package/node_modules/@llblab/pi-telegram/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +17 -5
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +3 -3
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +2 -0
- package/node_modules/@llblab/pi-telegram/index.ts +9 -0
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +29 -18
- package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +15 -6
- package/node_modules/@llblab/pi-telegram/lib/bus.ts +11 -4
- package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +34 -2
- package/node_modules/@llblab/pi-telegram/lib/outbound.ts +4 -1
- package/node_modules/@llblab/pi-telegram/lib/routing.ts +89 -32
- package/node_modules/@llblab/pi-telegram/lib/sync.ts +74 -15
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +32 -1
- package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +17 -0
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +123 -15
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/SKILL.md +1 -1
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/diagnosis.md +4 -2
- package/node_modules/@llblab/skills/abcd-context/AGENTS.md +40 -0
- package/node_modules/@llblab/skills/abcd-context/BACKLOG.md +3 -0
- package/node_modules/@llblab/skills/abcd-context/CHANGELOG.md +19 -0
- package/node_modules/@llblab/skills/abcd-context/README.md +30 -0
- package/node_modules/@llblab/skills/abcd-context/SKILL.md +122 -0
- package/node_modules/@llblab/skills/abcd-context/docs/README.md +9 -0
- package/node_modules/@llblab/skills/abcd-context/docs/protocols.md +199 -0
- package/node_modules/@llblab/skills/abcd-context/docs/templates.md +194 -0
- package/node_modules/@llblab/skills/abcd-context/docs/validation-design.md +117 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/AGENTS.md +10 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/BACKLOG.md +5 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/CHANGELOG.md +5 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/README.md +10 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/docs/README.md +7 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/docs/overview.md +3 -0
- package/node_modules/@llblab/skills/abcd-context/recipes/validate-context.json +7 -0
- package/node_modules/@llblab/skills/abcd-context/scripts/_self-test.mjs +244 -0
- package/node_modules/@llblab/skills/abcd-context/scripts/validate-context.mjs +497 -0
- package/node_modules/@llblab/skills/brain-storm/AGENTS.md +5 -0
- package/node_modules/@llblab/skills/brain-storm/SKILL.md +321 -0
- package/node_modules/@llblab/skills/coding-contract/SKILL.md +228 -0
- package/node_modules/@llblab/skills/domain-dag/AGENTS.md +6 -0
- package/node_modules/@llblab/skills/domain-dag/SKILL.md +257 -0
- package/node_modules/@llblab/skills/domain-dag/domain-dag.json +9 -0
- package/node_modules/@llblab/skills/domain-dag/recipes/validate-domain-dag.json +7 -0
- package/node_modules/@llblab/skills/domain-dag/scripts/validate-domain-dag.mjs +771 -0
- package/node_modules/@llblab/skills/domain-dag/scripts/validate-domain-dag.sh +4 -0
- package/node_modules/@llblab/skills/edge-tts/AGENTS.md +19 -0
- package/node_modules/@llblab/skills/edge-tts/SKILL.md +56 -0
- package/node_modules/@llblab/skills/edge-tts/recipes/say-edge.json +9 -0
- package/node_modules/@llblab/skills/edge-tts/scripts/say.mjs +1548 -0
- package/node_modules/@llblab/skills/edge-tts/scripts/say.sh +4 -0
- package/node_modules/@llblab/skills/extra-self/SKILL.md +229 -0
- package/node_modules/@llblab/skills/frontend-design/SKILL.md +78 -0
- package/node_modules/@llblab/skills/groq-stt/AGENTS.md +15 -0
- package/node_modules/@llblab/skills/groq-stt/SKILL.md +35 -0
- package/node_modules/@llblab/skills/groq-stt/recipes/transcribe-groq.json +10 -0
- package/node_modules/@llblab/skills/groq-stt/scripts/transcribe.mjs +190 -0
- package/node_modules/@llblab/skills/groq-stt/scripts/transcribe.sh +4 -0
- package/node_modules/@llblab/skills/mistral-stt/AGENTS.md +15 -0
- package/node_modules/@llblab/skills/mistral-stt/SKILL.md +35 -0
- package/node_modules/@llblab/skills/mistral-stt/recipes/transcribe-mistral.json +10 -0
- package/node_modules/@llblab/skills/mistral-stt/scripts/transcribe.mjs +191 -0
- package/node_modules/@llblab/skills/mistral-stt/scripts/transcribe.sh +4 -0
- package/node_modules/@llblab/skills/package.json +46 -0
- package/node_modules/@llblab/skills/re-review/SKILL.md +318 -0
- package/node_modules/@llblab/skills/release-flow/SKILL.md +456 -0
- package/node_modules/@llblab/skills/show-me/SKILL.md +144 -0
- package/package.json +20 -8
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback-client.mjs +0 -143
- package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback-client.mjs +0 -143
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: domain-dag
|
|
3
|
+
description: Validates and guides Domain DAG architecture for domain ownership, acyclic local dependency graphs, composition roots, boundary direction, public contracts, interface-surface pressure, and shared-bucket drift. Use when auditing, refactoring, or extending modular codebases across frontend, backend, extensions, CLIs, SDKs, and service packages.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Domain DAG
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Maintain source code as a directed acyclic graph of cohesive responsibility modules.
|
|
11
|
+
|
|
12
|
+
A Domain DAG keeps architecture readable by making every durable module answer four questions:
|
|
13
|
+
|
|
14
|
+
1. **What does this module own?**
|
|
15
|
+
2. **What does it explicitly not own?**
|
|
16
|
+
3. **Which lower or peer contracts may it depend on?**
|
|
17
|
+
4. **Where is live composition allowed to happen?**
|
|
18
|
+
|
|
19
|
+
The skill is not tied to one stack or folder style. It applies to frontend features, backend bounded contexts, extension hosts, SDK packages, CLIs, workers, and service adapters.
|
|
20
|
+
|
|
21
|
+
## Core Model
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
composition root / delivery surface
|
|
25
|
+
→ orchestration or use-case modules
|
|
26
|
+
→ domain capability modules
|
|
27
|
+
→ support/foundation modules
|
|
28
|
+
→ platform, runtime, standard library, external adapters
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The filesystem may be flat, layered, package-based, or mixed. The graph is architectural, not decorative: ownership lives in module boundaries, import direction, public contracts, and explicit composition points.
|
|
32
|
+
|
|
33
|
+
## Common Shapes
|
|
34
|
+
|
|
35
|
+
Domain DAG is a graph discipline, not one folder template.
|
|
36
|
+
|
|
37
|
+
- **Flat domain DAG**: one entrypoint plus flat domain files/packages. Best for extensions, CLIs, small services, and runtimes where deep folders would hide rather than clarify ownership.
|
|
38
|
+
- **Layered domain DAG**: routes/controllers/features/use-cases compose reusable domain and support modules. Best when delivery surfaces are numerous and entity capabilities are reused across screens or endpoints.
|
|
39
|
+
- **Package DAG**: apps depend on packages, packages depend on foundation or peer public contracts. Best for monorepos and SDKs.
|
|
40
|
+
- **Hexagonal/ports DAG**: use cases depend on ports/contracts while adapters live at composition boundaries. Best for backends, workers, queues, and external integrations.
|
|
41
|
+
- **Hybrid DAG**: different bounded contexts use different local shapes, but the global dependency direction stays acyclic and explicit.
|
|
42
|
+
|
|
43
|
+
Choose the smallest shape that explains the code. Do not force a layered tree onto a flat extension or flatten a product frontend that has earned route/feature/domain separation.
|
|
44
|
+
|
|
45
|
+
## Axioms
|
|
46
|
+
|
|
47
|
+
### A1: Domain Ownership
|
|
48
|
+
|
|
49
|
+
Each durable responsibility has one owning module or package. Types, constants, helpers, adapters, state, policies, and tests that define a responsibility live with that owner.
|
|
50
|
+
|
|
51
|
+
### A2: Explicit Non-Ownership
|
|
52
|
+
|
|
53
|
+
A strong boundary says what it does **not** own. This prevents accumulation of adjacent workflows, transport concerns, persistence policy, UI chrome, or runtime wiring just because the code is nearby.
|
|
54
|
+
|
|
55
|
+
### A3: Directed Imports
|
|
56
|
+
|
|
57
|
+
Local imports must form a DAG. Cycles are architecture bugs because they hide ownership and make change impact non-local.
|
|
58
|
+
|
|
59
|
+
### A4: Composition Root Boundary
|
|
60
|
+
|
|
61
|
+
Entrypoints wire live ports, configuration, adapters, routes, framework lifecycles, queues, and domain runtimes. Domain modules must not import composition roots.
|
|
62
|
+
|
|
63
|
+
### A5: Shared Bucket Resistance
|
|
64
|
+
|
|
65
|
+
Files or folders named `types`, `constants`, `utils`, `helpers`, `shared`, or `common` are suspect. Use them only when the responsibility is genuinely cross-domain and cannot belong to a more specific owner.
|
|
66
|
+
|
|
67
|
+
### A6: Public Contracts Over Reach-Through
|
|
68
|
+
|
|
69
|
+
When a module needs another module's behavior, depend on the smallest public contract that expresses the capability. Avoid importing internals, broad mutable runtime state, or sibling orchestration surfaces.
|
|
70
|
+
|
|
71
|
+
### A7: Progressive Disclosure
|
|
72
|
+
|
|
73
|
+
Start with the smallest useful graph. Add layers, public barrels, forbidden edges, header clauses, and custom checks only after real project constraints make them valuable.
|
|
74
|
+
|
|
75
|
+
### A8: Interface Surface Pressure
|
|
76
|
+
|
|
77
|
+
A very wide boundary can be as harmful as a wrong dependency. Many callbacks, parameters, exported knobs, or adapter methods are pressure to group related concepts into named contracts, ports, state objects, command objects, or smaller capabilities.
|
|
78
|
+
|
|
79
|
+
## Placement Heuristics
|
|
80
|
+
|
|
81
|
+
Use these questions when creating or moving code:
|
|
82
|
+
|
|
83
|
+
- **Survival test**: If the current route/screen/job/command disappeared, would this module still be useful? If yes, it likely belongs below the orchestration layer.
|
|
84
|
+
- **Noun vs journey**: Business nouns/capabilities belong in domain modules. User journeys, workflows, route handlers, modal/screen flows, jobs, and shell composition belong in orchestration/features/use cases.
|
|
85
|
+
- **Reuse pressure**: Peer orchestration modules should not import each other for shared behavior. Extract the reusable capability down to a domain/support module, or extract generic mechanics down to foundation/UI/platform.
|
|
86
|
+
- **Entrypoint shim pressure**: If executable scripts grow substantive behavior, keep the executable file as a thin runner and move the behavior into a named compiled domain module when reuse, testing, packaging, or runtime compatibility benefits are plausible. Do not extract self-contained app scripts whose logic has no expected second consumer; keep them standalone when the boundary would be theater.
|
|
87
|
+
- **Policy locality**: Persistence policy, transaction boundaries, routing, lifecycle registration, drag/drop registration, message acknowledgement, and external transport wiring usually remain in the owning composition/use-case layer unless they are themselves reusable policies.
|
|
88
|
+
- **Naming is not ownership**: A `cards` feature and a `cards` domain can coexist if one owns the journey and the other owns reusable card capabilities.
|
|
89
|
+
- **Public surface test**: Consumers should import what the owner deliberately exposes, not whatever file is easy to reach. Public barrels, package exports, ports, facades, or documented function groups are all valid contracts when they fit the ecosystem.
|
|
90
|
+
- **Flat-shape caution**: In a flat DAG, file count is not the main health metric. Cohesion, acyclicity, explicit headers, and absence of shared buckets matter more.
|
|
91
|
+
|
|
92
|
+
## Calibration Protocol
|
|
93
|
+
|
|
94
|
+
Before adding or enforcing rules, calibrate the project:
|
|
95
|
+
|
|
96
|
+
1. Identify the shape: flat, layered, package, hexagonal, or hybrid.
|
|
97
|
+
2. Find the true composition roots: app bootstrap, extension entrypoint, HTTP router, worker runner, CLI command, SDK facade, test harness.
|
|
98
|
+
3. Identify the project’s public-contract mechanism: barrels, package exports, interfaces, ports, route handlers, generated clients, or documented namespaces.
|
|
99
|
+
4. Run [validation](#validation) with generic defaults; treat warnings as leads, not facts.
|
|
100
|
+
5. Add [project-local configuration](#configuration) only where aliases, layers, or public boundaries are invisible to defaults, or a real boundary violation warrants a custom rule.
|
|
101
|
+
6. Apply the [Rule-Severity Ladder](#rule-severity-ladder).
|
|
102
|
+
|
|
103
|
+
## Extraction Protocol
|
|
104
|
+
|
|
105
|
+
When decomposing or extending a module:
|
|
106
|
+
|
|
107
|
+
1. Identify the host's real responsibility and write it down.
|
|
108
|
+
2. Find stable seams: repeated entity surfaces, reusable policy, narrow UI/control blocks, adapters, or pure transformations.
|
|
109
|
+
3. Extract only if the child has a clear owner and exclusion list.
|
|
110
|
+
4. Keep persistence, runtime lifecycle, routing, external effects, and screen/job orchestration in the host unless the extracted module explicitly owns that policy.
|
|
111
|
+
5. Replace cross-feature or cross-use-case reuse with lower-layer contracts rather than peer imports.
|
|
112
|
+
6. Run the validator and the project's normal checks.
|
|
113
|
+
7. Apply the [Stop Rules](#stop-rules) before extracting further.
|
|
114
|
+
|
|
115
|
+
## Stop Rules
|
|
116
|
+
|
|
117
|
+
Do **not** keep decomposing just because a file is large. Stop when:
|
|
118
|
+
|
|
119
|
+
- Remaining code is orchestration glue with high local context value.
|
|
120
|
+
- The module is a self-contained executable application and its behavior is unlikely to be imported by another domain.
|
|
121
|
+
- The next slice would have no reusable responsibility beyond “some markup from the host”.
|
|
122
|
+
- The extracted child would need most of the host state as props.
|
|
123
|
+
- The boundary would create a long flat callback list instead of a meaningful contract.
|
|
124
|
+
- Behavior risk exceeds architectural gain.
|
|
125
|
+
|
|
126
|
+
At this point, switch to review: check for misplaced ownership, too-wide contracts, stale imports, and validator gaps.
|
|
127
|
+
|
|
128
|
+
## Anti-Patterns
|
|
129
|
+
|
|
130
|
+
- **Folder theater**: creating layers or domain folders without changing dependency direction or ownership clarity.
|
|
131
|
+
- **Peer feature reach-through**: one workflow imports another workflow because it wants a reusable part.
|
|
132
|
+
- **Shared bucket gravity**: generic `types`, `utils`, or `constants` become the real hidden domain.
|
|
133
|
+
- **God facade**: a public contract exposes most internals and gives consumers no smaller capability boundary.
|
|
134
|
+
- **RPC child component/module**: a child boundary accepts dozens of callbacks or flags instead of a named contract.
|
|
135
|
+
- **Premature atomization**: many one-use files obscure the main control flow and make debugging harder.
|
|
136
|
+
- **Validator absolutism**: heuristic warnings are promoted to errors before the signal is proven stable.
|
|
137
|
+
|
|
138
|
+
## Validation
|
|
139
|
+
|
|
140
|
+
Run the bundled validator from a project root:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
SKILL_DIR=/path/to/domain-dag
|
|
144
|
+
bash "${SKILL_DIR}/scripts/validate-domain-dag.sh" --root .
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Useful flags:
|
|
148
|
+
|
|
149
|
+
- `--root <path>` — project root; defaults to the current directory
|
|
150
|
+
- `--config <path>` — JSON config; defaults to `domain-dag.json`, then `.domain-dag.json`
|
|
151
|
+
- `--strict` — treat warnings as failures
|
|
152
|
+
- `--json` — machine-readable output
|
|
153
|
+
|
|
154
|
+
The validator checks:
|
|
155
|
+
|
|
156
|
+
- Local source import graph has no cycles, including configured local import aliases
|
|
157
|
+
- Domain modules do not import configured entrypoints
|
|
158
|
+
- Optional domain headers are present
|
|
159
|
+
- Optional required header clauses are present
|
|
160
|
+
- Shared-bucket filenames and folders are reported
|
|
161
|
+
- Optional flat-root, layer-order, forbidden-edge, and surface-width rules hold
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
Add a project-local `domain-dag.json` when defaults are too broad or too narrow:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"sourceRoots": ["src", "lib"],
|
|
170
|
+
"sourceExtensions": [".ts", ".tsx", ".js", ".jsx", ".svelte"],
|
|
171
|
+
"entrypoints": ["src/main.ts", "src/app/bootstrap.ts"],
|
|
172
|
+
"importAliases": {
|
|
173
|
+
"@/*": "src/*",
|
|
174
|
+
"$lib/*": "src/lib/*"
|
|
175
|
+
},
|
|
176
|
+
"requireHeaders": true,
|
|
177
|
+
"headerPattern": "\\b(Domain|Domains|Zone|Zones|Owns):\\s*\\S",
|
|
178
|
+
"headerSeverity": "warn",
|
|
179
|
+
"headerRequiredClauses": ["Owns:", "Excludes:"],
|
|
180
|
+
"headerRequiredClausesSeverity": "warn",
|
|
181
|
+
"flatRoots": false,
|
|
182
|
+
"sharedBucketSeverity": "warn",
|
|
183
|
+
"allowedSharedBuckets": ["src/platform/shared/**"],
|
|
184
|
+
"surfaceRules": [
|
|
185
|
+
{
|
|
186
|
+
"name": "wide callback surface",
|
|
187
|
+
"files": ["src/features/**"],
|
|
188
|
+
"pattern": "\\b(on[A-Z][A-Za-z0-9_]*)\\b",
|
|
189
|
+
"max": 15,
|
|
190
|
+
"severity": "warn",
|
|
191
|
+
"message": "Wide callback surface; group related handlers into contract objects"
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
"forbiddenEdges": [
|
|
195
|
+
{
|
|
196
|
+
"from": "src/domain/**",
|
|
197
|
+
"to": "src/app/**",
|
|
198
|
+
"severity": "error",
|
|
199
|
+
"message": "Domain layer must not import app layer"
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"layers": [
|
|
203
|
+
{
|
|
204
|
+
"name": "foundation",
|
|
205
|
+
"rank": 0,
|
|
206
|
+
"files": ["src/platform/**"]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "domain",
|
|
210
|
+
"rank": 1,
|
|
211
|
+
"files": ["src/domain/**"]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"name": "composition",
|
|
215
|
+
"rank": 2,
|
|
216
|
+
"files": ["src/app/**", "src/main.ts"]
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Layer rule: lower ranks must not import higher ranks. Same-rank and downward imports are allowed.
|
|
223
|
+
|
|
224
|
+
`importAliases` lets the validator resolve local path aliases such as `@/*`, `$lib/*`, or package-internal aliases. Keep aliases project-local; the skill should not assume any particular bundler or language server convention.
|
|
225
|
+
|
|
226
|
+
Glob support is intentionally small and portable: `*`, `**`, and `?` are supported, but brace expansion such as `src/{a,b}/**` is not. Use multiple explicit glob entries or rules instead; the validator warns when configured globs contain unsupported braces.
|
|
227
|
+
|
|
228
|
+
`surfaceRules` are intentionally generic: by default they count unique regex matches in selected files, and with `metric: "lines"` they count file lines. Use them for local pressure signals such as too many callback props, too many exported commands, broad adapter methods, oversized widgets/modules, or other project-specific interface smells. Keep them warnings unless the signal is proven noise-free.
|
|
229
|
+
|
|
230
|
+
## Rule-Severity Ladder
|
|
231
|
+
|
|
232
|
+
Use severity deliberately:
|
|
233
|
+
|
|
234
|
+
- **Error**: objective graph break or proven boundary breach — cycles, reverse entrypoint import, configured forbidden edge, known-invalid layer direction.
|
|
235
|
+
- **Warning**: architectural pressure — shared bucket names, missing headers, wide interfaces, large modules, broad exports, suspicious reach-through.
|
|
236
|
+
- **Off / documented exception**: local shape intentionally violates a heuristic and the reason is durable.
|
|
237
|
+
|
|
238
|
+
A mature Domain DAG has few hard rules and good explanations. It does not need many rules to be strong.
|
|
239
|
+
|
|
240
|
+
## Operating Protocol
|
|
241
|
+
|
|
242
|
+
1. Apply the [Calibration Protocol](#calibration-protocol).
|
|
243
|
+
2. Map domain and support owners, public contracts, and explicit exclusions beneath the identified composition roots.
|
|
244
|
+
3. Fix hard failures before cosmetic refactors. Use [Placement Heuristics](#placement-heuristics) for misplaced responsibilities and [Extraction Protocol](#extraction-protocol) when decomposition is warranted.
|
|
245
|
+
4. Stop after the smallest behavior-preserving slice that improves the graph.
|
|
246
|
+
|
|
247
|
+
## Review Lens
|
|
248
|
+
|
|
249
|
+
A good Domain DAG review asks:
|
|
250
|
+
|
|
251
|
+
- Is every durable responsibility owned exactly once?
|
|
252
|
+
- Are public contracts smaller than the internals behind them?
|
|
253
|
+
- Are peer orchestration modules reusing each other instead of extracting a lower capability?
|
|
254
|
+
- Are shared buckets hiding ownership decisions?
|
|
255
|
+
- Are interface surfaces becoming RPC-style bags of callbacks or methods?
|
|
256
|
+
- Did decomposition improve change locality without hiding essential control flow?
|
|
257
|
+
- Are validator rules hard only where they are low-noise and project-earned?
|