laymos 0.0.9 → 0.0.11
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/README.md +259 -142
- package/dist/architecture-analysis-schema/module-source-schema.d.ts +4 -0
- package/dist/architecture-analysis-schema/module-source-schema.d.ts.map +1 -1
- package/dist/architecture-analysis-schema/module-source-schema.js +4 -0
- package/dist/change-set-schema/change-set-schema.js +2 -2
- package/dist/cli/run.d.ts +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +2 -0
- package/dist/cli/skills.d.ts +6 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/orchestrator/load-changes/index.d.ts +1 -1
- package/dist/orchestrator/load-changes/index.d.ts.map +1 -1
- package/dist/orchestrator/load-changes/index.js +1 -1
- package/dist/orchestrator/load-changes/load-changes.d.ts +4 -3
- package/dist/orchestrator/load-changes/load-changes.d.ts.map +1 -1
- package/dist/orchestrator/load-changes/load-changes.js +14 -9
- package/dist/orchestrator/load-source-files/index.d.ts +1 -1
- package/dist/orchestrator/load-source-files/index.d.ts.map +1 -1
- package/dist/orchestrator/load-source-files/index.js +1 -1
- package/dist/orchestrator/load-source-files/load-source-files.d.ts +20 -4
- package/dist/orchestrator/load-source-files/load-source-files.d.ts.map +1 -1
- package/dist/orchestrator/load-source-files/load-source-files.js +46 -7
- package/dist/services/git/changed-paths.d.ts +1 -0
- package/dist/services/git/changed-paths.d.ts.map +1 -1
- package/dist/services/git/changed-paths.js +8 -0
- package/dist/services/git/git.d.ts +1 -0
- package/dist/services/git/git.d.ts.map +1 -1
- package/dist/services/git/git.js +5 -1
- package/dist/skills-command/index.d.ts +2 -0
- package/dist/skills-command/index.d.ts.map +1 -0
- package/dist/skills-command/index.js +1 -0
- package/dist/skills-command/skills-command.d.ts +21 -0
- package/dist/skills-command/skills-command.d.ts.map +1 -0
- package/dist/skills-command/skills-command.js +64 -0
- package/dist/story/schema/index.d.ts +2 -2
- package/dist/story/schema/index.d.ts.map +1 -1
- package/dist/story/schema/index.js +1 -1
- package/dist/story/schema/story-report-schema.d.ts +264 -132
- package/dist/story/schema/story-report-schema.d.ts.map +1 -1
- package/dist/story/schema/story-report-schema.js +4 -4
- package/dist/story/story.d.ts +3 -1
- package/dist/story/story.d.ts.map +1 -1
- package/dist/story/story.js +4 -5
- package/package.json +18 -11
- package/schema.json +60 -55
- package/skills/deep-module/SKILL.md +55 -0
- package/skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/skills/domain-modeling/SKILL.md +74 -0
- package/skills/domain-modeling/agents/openai.yaml +3 -0
- package/skills/laymos/SKILL.md +130 -0
- package/skills/laymos/references/config.md +96 -0
- package/skills/laymos/references/design.md +166 -0
- package/skills/laymos/references/graphs.md +85 -0
- package/skills/laymos/references/visibility.md +60 -0
- package/skills/to-laymos/SKILL.md +60 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# laymos.config.json
|
|
2
|
+
|
|
3
|
+
Read this when writing or amending a config.
|
|
4
|
+
|
|
5
|
+
## What does a config look like?
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"$schema": "https://unpkg.com/laymos/schema.json",
|
|
10
|
+
"sourceRoots": ["src"],
|
|
11
|
+
"ignoredPaths": ["src/generated"],
|
|
12
|
+
"storiesPath": "stories",
|
|
13
|
+
"layers": {
|
|
14
|
+
"cli": {
|
|
15
|
+
"paths": ["src/cli"],
|
|
16
|
+
"description": "Command surface",
|
|
17
|
+
"modules": { "src/cli": {} }
|
|
18
|
+
},
|
|
19
|
+
"domain": {
|
|
20
|
+
"paths": ["src/domain"],
|
|
21
|
+
"modules": {
|
|
22
|
+
"src/domain/orders": { "exposed": true },
|
|
23
|
+
"src/domain/catalog": { "shared": true, "exposed": true }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"services": {
|
|
27
|
+
"paths": ["src/services"],
|
|
28
|
+
"moduleGraphs": {
|
|
29
|
+
"store": {
|
|
30
|
+
"path": "src/services/store",
|
|
31
|
+
"modules": {
|
|
32
|
+
"index.ts": { "exposed": true },
|
|
33
|
+
"engine": {},
|
|
34
|
+
"model": {}
|
|
35
|
+
},
|
|
36
|
+
"rules": { "index.ts": ["engine"], "engine": ["model"] }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"layerGraphs": {
|
|
42
|
+
"architecture": {
|
|
43
|
+
"rules": {
|
|
44
|
+
"cli": ["domain"],
|
|
45
|
+
"domain": ["services"],
|
|
46
|
+
"services": []
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The `$schema` key gives editors autocomplete and validation. Trust it over prose.
|
|
54
|
+
|
|
55
|
+
## What do the top-level keys do?
|
|
56
|
+
|
|
57
|
+
- `sourceRoots` — the files and folders Laymos analyzes.
|
|
58
|
+
- `ignoredPaths` — files and folders removed from analysis.
|
|
59
|
+
- `storiesPath` — an optional folder containing the executable Story tree; it
|
|
60
|
+
is implicitly ignored by architecture analysis.
|
|
61
|
+
- `layers` — each id maps to literal project-relative `paths`, plus an optional
|
|
62
|
+
`description`, and owns the modules declared within it. Layers partition every
|
|
63
|
+
supported file under `sourceRoots` and may not overlap.
|
|
64
|
+
- `layers.<id>.modules` — free-form modules, keyed by project-relative path.
|
|
65
|
+
`{}` means a module nobody may import. Add `shared` and `exposed` as needed.
|
|
66
|
+
- `layers.<id>.moduleGraphs` — bounded sets of modules with their own rules.
|
|
67
|
+
Read `graphs.md`.
|
|
68
|
+
- `layerGraphs` — named sets of `rules`. Each rule maps a layer id to the ids
|
|
69
|
+
it may _directly_ depend on.
|
|
70
|
+
|
|
71
|
+
A module is declared exactly once, either free-form in its layer or as a member
|
|
72
|
+
of one module graph.
|
|
73
|
+
|
|
74
|
+
## What is a layer graph?
|
|
75
|
+
|
|
76
|
+
A named group of rules for one responsibility — core architecture, test
|
|
77
|
+
boundaries, and so on. It is organizational, not an enforcement boundary.
|
|
78
|
+
|
|
79
|
+
All graphs combine into one effective graph. That combined graph is default-deny,
|
|
80
|
+
transitive, and must be acyclic. A project with no permitted cross-layer imports
|
|
81
|
+
declares `"layerGraphs": {}`.
|
|
82
|
+
|
|
83
|
+
Declare direct edges only. Transitive reach follows.
|
|
84
|
+
|
|
85
|
+
A layer graph _hosts_ the layers it declares rules from and _reaches_ the layers
|
|
86
|
+
it names as targets. Rules point to the real target layer. Each referenced layer
|
|
87
|
+
has one configured host; declaration order breaks ties. The view groups all
|
|
88
|
+
unreferenced layers under `other-layers`.
|
|
89
|
+
|
|
90
|
+
## Where are paths resolved from?
|
|
91
|
+
|
|
92
|
+
The config file's own directory. `--config` defaults to `./laymos.config.json`.
|
|
93
|
+
|
|
94
|
+
## Does consuming the config need a dependency?
|
|
95
|
+
|
|
96
|
+
No. It is plain JSON. Any tool can read it.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Module design
|
|
2
|
+
|
|
3
|
+
Read this when choosing boundaries, splitting or combining modules, declaring a
|
|
4
|
+
module graph, or designing orchestration. Concepts stay short; scenarios decide.
|
|
5
|
+
|
|
6
|
+
## Module boundary
|
|
7
|
+
|
|
8
|
+
A module owns one coherent capability and the design decisions most likely to
|
|
9
|
+
change behind it. Its door reveals the promise, not representation or sequence.
|
|
10
|
+
|
|
11
|
+
**Where do I split?**
|
|
12
|
+
Split where a part has its own promise, change reason, and independently testable door.
|
|
13
|
+
|
|
14
|
+
**Should processing steps become modules?**
|
|
15
|
+
Only when they hide independent decisions; runtime order alone is not a boundary.
|
|
16
|
+
|
|
17
|
+
**Where do data and its operations live?**
|
|
18
|
+
Together, behind the module that hides the representation.
|
|
19
|
+
|
|
20
|
+
**What if history shows two parts always change together?**
|
|
21
|
+
Treat co-change as evidence to combine them, never as the decision by itself.
|
|
22
|
+
|
|
23
|
+
## Deep module
|
|
24
|
+
|
|
25
|
+
A deep module absorbs substantially more complexity than its door exposes while
|
|
26
|
+
keeping its interior navigable. A narrow door does not excuse a tangled interior.
|
|
27
|
+
|
|
28
|
+
**How should a reader enter a directory module?**
|
|
29
|
+
Through its door, then its execution story; use the `deep-module` skill for shape.
|
|
30
|
+
|
|
31
|
+
**May a small capability be a module?**
|
|
32
|
+
Yes, when it hides a real policy behind a stable concept.
|
|
33
|
+
|
|
34
|
+
**Do several functions need a namespace object?**
|
|
35
|
+
Use one for a coherent caller concept; grouping alone does not create depth.
|
|
36
|
+
|
|
37
|
+
**The door is tiny but the orchestrator is huge. Is it deep?**
|
|
38
|
+
No. Group its independent concerns behind named internal capabilities.
|
|
39
|
+
|
|
40
|
+
## Readable execution story
|
|
41
|
+
|
|
42
|
+
An exposed module's `<name>.ts` fulfils its promise through named collaborators.
|
|
43
|
+
A reader follows one branch at a time while holding two or three concepts.
|
|
44
|
+
|
|
45
|
+
**The orchestrator handles more than three concepts at once. What now?**
|
|
46
|
+
Group related steps behind a named internal capability.
|
|
47
|
+
|
|
48
|
+
**The module has more than five direct collaborators. What now?**
|
|
49
|
+
Review the story and group its concerns; above ten, presume the boundary is wrong.
|
|
50
|
+
|
|
51
|
+
**Do those counts decide the boundary?**
|
|
52
|
+
No. They trigger review; capability, change, and cognitive load decide.
|
|
53
|
+
|
|
54
|
+
**Is file length the test?**
|
|
55
|
+
No. Test the number of responsibilities, state owners, and policy boundaries.
|
|
56
|
+
|
|
57
|
+
**Must the story be chronological?**
|
|
58
|
+
No. Event-driven code names each interaction and delegates its behavior.
|
|
59
|
+
|
|
60
|
+
## Split and combine
|
|
61
|
+
|
|
62
|
+
Split independently changing promises; combine coordination callers should not
|
|
63
|
+
manage. Private children may remain when they make the parent story clearer.
|
|
64
|
+
|
|
65
|
+
**Two modules require callers to know their order or shared state. What now?**
|
|
66
|
+
Combine them behind one useful operation.
|
|
67
|
+
|
|
68
|
+
**Two modules depend on each other. What now?**
|
|
69
|
+
Re-cut the responsibilities or split one into lower and higher parts.
|
|
70
|
+
|
|
71
|
+
**A folder is large. Should I split it?**
|
|
72
|
+
Only when the new parts pass the promise, change, and independent-door tests.
|
|
73
|
+
|
|
74
|
+
**Several files serve one private responsibility. What now?**
|
|
75
|
+
Make a nested deep module; configure a graph only when its dependencies matter.
|
|
76
|
+
|
|
77
|
+
## Module Graph
|
|
78
|
+
|
|
79
|
+
A Module Graph makes the responsibility and dependency story of one large
|
|
80
|
+
capability explicit. It normally has one exposed facade and private members.
|
|
81
|
+
|
|
82
|
+
**When does a module become a Module Graph?**
|
|
83
|
+
When two or more internal capabilities stand alone and their dependency direction matters.
|
|
84
|
+
|
|
85
|
+
**What must connect to the facade?**
|
|
86
|
+
Every private member must lie on a path from at least one exposed member.
|
|
87
|
+
|
|
88
|
+
**May a graph expose several members?**
|
|
89
|
+
Only for independently consumed doors hiding the same decision, such as providers.
|
|
90
|
+
|
|
91
|
+
**A member is disconnected. What now?**
|
|
92
|
+
Make it a separate module or graph, unless its independent door explains the exception.
|
|
93
|
+
|
|
94
|
+
**Does a private member need `index.ts`?**
|
|
95
|
+
Yes. Graph peers use its door; `exposed` only controls access from other layers.
|
|
96
|
+
|
|
97
|
+
**Should graph rules mirror runtime calls?**
|
|
98
|
+
No. Rules express correctness dependencies, not execution chronology.
|
|
99
|
+
|
|
100
|
+
**When should A depend on B?**
|
|
101
|
+
When B simplifies A, B stands without A, and A needs B to fulfil its promise.
|
|
102
|
+
|
|
103
|
+
## Orchestrator
|
|
104
|
+
|
|
105
|
+
An orchestrator is a module that adds workflow policy while coordinating lower
|
|
106
|
+
capabilities. It is a relative role, not a configured kind or mandatory layer.
|
|
107
|
+
|
|
108
|
+
**What belongs in an orchestrator?**
|
|
109
|
+
Workflow sequencing, interaction transitions, failure policy, lifetime, and composition.
|
|
110
|
+
|
|
111
|
+
**What stays below it?**
|
|
112
|
+
The domain decisions and detailed work owned by lower capabilities.
|
|
113
|
+
|
|
114
|
+
**May it import every transitively reachable module?**
|
|
115
|
+
Prefer the nearest capability that owns the behavior; permission is not encouragement.
|
|
116
|
+
|
|
117
|
+
**It only re-exports lower modules. Is it an orchestrator?**
|
|
118
|
+
No. It adds no broader capability and should usually disappear.
|
|
119
|
+
|
|
120
|
+
**Wiring obscures the workflow. What now?**
|
|
121
|
+
Separate the composition root that constructs dependencies from the orchestrator.
|
|
122
|
+
|
|
123
|
+
**Where do concrete implementations meet?**
|
|
124
|
+
At the entry or composition root; the orchestrator receives capability doors.
|
|
125
|
+
|
|
126
|
+
## Interactive module
|
|
127
|
+
|
|
128
|
+
An interactive module owns one path from user intent through transition and
|
|
129
|
+
derived state to rendering. Views emit intent and render results.
|
|
130
|
+
|
|
131
|
+
**Two views implement the same focus or visibility policy. What now?**
|
|
132
|
+
Move the policy to one pure owner and let both views consume it.
|
|
133
|
+
|
|
134
|
+
**One state value means different things in different modes. What now?**
|
|
135
|
+
Split it or model the alternatives as an explicit union.
|
|
136
|
+
|
|
137
|
+
**One action resets several unrelated state values. What now?**
|
|
138
|
+
Create a named transition in one interaction model.
|
|
139
|
+
|
|
140
|
+
**A primary action crosses several policy owners. What now?**
|
|
141
|
+
Reduce it to door, coordinator, and one focused capability path.
|
|
142
|
+
|
|
143
|
+
## Layer composition
|
|
144
|
+
|
|
145
|
+
A layer groups modules with the same dependency rights, not necessarily one
|
|
146
|
+
capability. Responsibility broadens upward as modules compose lower promises.
|
|
147
|
+
|
|
148
|
+
**Must a layer expose one facade?**
|
|
149
|
+
No. It may expose several independent capabilities; a Module Graph defaults to one.
|
|
150
|
+
|
|
151
|
+
**What should the outermost module expose?**
|
|
152
|
+
The smallest useful interface for the system's external consumer.
|
|
153
|
+
|
|
154
|
+
**What must a higher module add?**
|
|
155
|
+
A broader capability through workflow policy, never a pass-through re-export.
|
|
156
|
+
|
|
157
|
+
**What is at the bottom?**
|
|
158
|
+
Leaf capabilities depend on nothing; Laymos reports this observed shape as Terminal.
|
|
159
|
+
|
|
160
|
+
## Foundations
|
|
161
|
+
|
|
162
|
+
[Parnas 1972](https://doi.org/10.1145/361598.361623): information hiding.
|
|
163
|
+
[Parnas 1978](https://ocw.mit.edu/courses/16-355j-software-engineering-concepts-fall-2005/1c68d0f98909a126ec5eb6a0ff358ec7_parnas_ease.pdf):
|
|
164
|
+
uses hierarchies. [Parnas, Clements, and Weiss](https://doi.org/10.1109/TSE.1985.232209):
|
|
165
|
+
module versus runtime structure. [Ousterhout](https://web.stanford.edu/~ouster/CS349W/lectures/abstraction.html):
|
|
166
|
+
deep modules.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Module graphs
|
|
2
|
+
|
|
3
|
+
Read this when one capability outgrows a single module.
|
|
4
|
+
Read `design.md` first when deciding whether the graph is the right boundary.
|
|
5
|
+
|
|
6
|
+
## What is a module graph?
|
|
7
|
+
|
|
8
|
+
A named, bounded set of modules inside one layer, rooted at a directory,
|
|
9
|
+
whose connections are declared as rules. It describes one capability whose
|
|
10
|
+
parts need their own dependency direction — an interior the layer should not see.
|
|
11
|
+
|
|
12
|
+
A module graph is not a module. It owns no files directly, has no `index.ts`
|
|
13
|
+
of its own, and cannot contain another module graph.
|
|
14
|
+
|
|
15
|
+
Default to one exposed facade and a dependency path from it to every private
|
|
16
|
+
member. Several exposed doors are a design exception, not a config violation.
|
|
17
|
+
|
|
18
|
+
## What does it look like?
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
"orchestrator": {
|
|
22
|
+
"paths": ["src/orchestrator"],
|
|
23
|
+
"moduleGraphs": {
|
|
24
|
+
"project-orchestration": {
|
|
25
|
+
"description": "Loads a project once and derives every view of it.",
|
|
26
|
+
"path": "src/orchestrator",
|
|
27
|
+
"modules": {
|
|
28
|
+
"load-project": {},
|
|
29
|
+
"analyze-project": { "exposed": true },
|
|
30
|
+
"inspect": { "exposed": true }
|
|
31
|
+
},
|
|
32
|
+
"rules": {
|
|
33
|
+
"analyze-project": ["load-project"],
|
|
34
|
+
"inspect": ["analyze-project", "load-project"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Member keys are relative to `path`. Rules use those keys.
|
|
42
|
+
|
|
43
|
+
## What are the invariants?
|
|
44
|
+
|
|
45
|
+
- At least two members. A one-member graph is a module.
|
|
46
|
+
- At least one exposed member. A graph nobody can reach means nothing.
|
|
47
|
+
- Graph ids are unique across the whole project, not merely within one layer.
|
|
48
|
+
- Every file under `path` belongs to a member — module graph coverage.
|
|
49
|
+
A file beside member directories must itself be a declared root File Module.
|
|
50
|
+
- No member may be `shared`. Sharing is layer-wide and would let a peer bypass
|
|
51
|
+
the rules; declare anything that must be shared outside the graph.
|
|
52
|
+
- Rules must be acyclic, and reference only this graph's members.
|
|
53
|
+
|
|
54
|
+
## What may a member import?
|
|
55
|
+
|
|
56
|
+
Its own graph's members where a rule permits, free-form shared modules in its
|
|
57
|
+
layer, and exposed modules in layers it may reach. It may never import another
|
|
58
|
+
graph's member in the same layer.
|
|
59
|
+
|
|
60
|
+
Rules are the only way members connect, and a member no rule reaches and nothing
|
|
61
|
+
exposes is dead.
|
|
62
|
+
|
|
63
|
+
## How is this different from a layer graph?
|
|
64
|
+
|
|
65
|
+
Both are DAGs of nodes with declared rights, but they invert in three ways:
|
|
66
|
+
|
|
67
|
+
| | layer graph | module graph |
|
|
68
|
+
| ------------ | -------------------------------- | ---------------------------------------- |
|
|
69
|
+
| overlap | graphs share layers; rules union | disjoint units; never unioned |
|
|
70
|
+
| transitivity | transitive | **not** transitive — only declared edges |
|
|
71
|
+
| cycles | checked over the union | checked per graph |
|
|
72
|
+
|
|
73
|
+
Non-transitivity is deliberate. A graph is small enough that stating each edge is
|
|
74
|
+
cheap, and transitivity would silently permit imports across the very interior
|
|
75
|
+
the graph exists to describe.
|
|
76
|
+
|
|
77
|
+
## When is a module graph wrong?
|
|
78
|
+
|
|
79
|
+
- The members have no edges between them → they are independent peers.
|
|
80
|
+
Leave them flat.
|
|
81
|
+
- A member wants an interior graph of its own → it should have been a layer.
|
|
82
|
+
- Two graphs want to reach into each other → extract the common part up to the
|
|
83
|
+
layer as a free-form shared module.
|
|
84
|
+
- Members mirror runtime steps but hide no independent decisions → keep the
|
|
85
|
+
execution story inside one module.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Module visibility
|
|
2
|
+
|
|
3
|
+
Read this when deciding who may import a module.
|
|
4
|
+
|
|
5
|
+
## What are the two flags?
|
|
6
|
+
|
|
7
|
+
Every module declares two booleans, both defaulting to `false`.
|
|
8
|
+
They open layer-wide and cross-layer access; module graph rules separately grant
|
|
9
|
+
member-to-member access.
|
|
10
|
+
|
|
11
|
+
- `shared` — peers in the same layer may import it.
|
|
12
|
+
- `exposed` — other layers may import it, subject to layer rules.
|
|
13
|
+
|
|
14
|
+
That is the whole vocabulary. There is no `kind`, and no `subpaths`.
|
|
15
|
+
|
|
16
|
+
| you want | declare |
|
|
17
|
+
| ---------------------------------------------- | -------------------------------------- |
|
|
18
|
+
| a layer's public capability | `exposed` |
|
|
19
|
+
| a layer-internal helper its peers share | `shared` |
|
|
20
|
+
| both | `shared` and `exposed` |
|
|
21
|
+
| a graph-private capability | neither; grant graph rules to its door |
|
|
22
|
+
| a host-started root — a CLI, a route, a worker | neither |
|
|
23
|
+
|
|
24
|
+
## What follows from the flags?
|
|
25
|
+
|
|
26
|
+
A directory module needs an `index.ts` when `shared || exposed`, and every
|
|
27
|
+
directory module graph member needs one so permitted peers use its door. A
|
|
28
|
+
free-form module nobody may import needs no door and follows its host convention.
|
|
29
|
+
|
|
30
|
+
An unimported free-form private module is an intentional root when its layer has
|
|
31
|
+
no inbound rules — that is where hosts enter. In a module graph, a private member
|
|
32
|
+
with no incoming graph rule is dead. Laymos reports either invalid case.
|
|
33
|
+
|
|
34
|
+
## When is shared wrong?
|
|
35
|
+
|
|
36
|
+
Shared exists for a genuine layer-wide capability. Match the symptom, take the verdict.
|
|
37
|
+
|
|
38
|
+
- No same-layer user → it is not shared. Drop the flag.
|
|
39
|
+
Laymos reports this as an `unused-shared` violation.
|
|
40
|
+
- Exactly one same-layer user → either that user owns the code, or the two
|
|
41
|
+
modules should merge. Check before keeping shared.
|
|
42
|
+
- Several peers forming a chain → they are one capability with an interior.
|
|
43
|
+
Make them a module graph, where each edge is declared.
|
|
44
|
+
- A shared module importing another shared module → merge them, or move the
|
|
45
|
+
lower one into a layer with the right dependency policy.
|
|
46
|
+
|
|
47
|
+
Each verdict demands a stated reason. None of them decides the design alone.
|
|
48
|
+
|
|
49
|
+
## What if peers need common code?
|
|
50
|
+
|
|
51
|
+
Test three options before adding shared.
|
|
52
|
+
|
|
53
|
+
1. One peer already owns the capability. Let it own it.
|
|
54
|
+
2. The peers are one capability split in two. Merge them, or make them a graph.
|
|
55
|
+
3. The capability is stable and lower. Move it to a layer the peers may reach.
|
|
56
|
+
|
|
57
|
+
## When do I reach for a module graph?
|
|
58
|
+
|
|
59
|
+
When one capability is too large for one module and its parts need declared
|
|
60
|
+
connections. Read `graphs.md`.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: to-laymos
|
|
3
|
+
description: Turn a requirement into a high-level Laymos architecture proposal.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# to-laymos
|
|
8
|
+
|
|
9
|
+
Describe how the requirement should fit the project's architecture. Stop after
|
|
10
|
+
the proposal; implementation is a separate task.
|
|
11
|
+
|
|
12
|
+
Read the `/laymos` skill and
|
|
13
|
+
[`../laymos/references/design.md`](../laymos/references/design.md) completely. Inspect
|
|
14
|
+
`laymos.config.json` and the doors of the modules the requirement changes or
|
|
15
|
+
depends on. Read the applicable `CONTEXT.md`; use `CONTEXT-MAP.md` to find it
|
|
16
|
+
when the project has multiple contexts. Ask only when two answers would produce
|
|
17
|
+
different boundaries.
|
|
18
|
+
|
|
19
|
+
For each part of the requirement, decide whether to extend a module, add a
|
|
20
|
+
module, or form a Module Graph. Prefer the smallest change whose boundaries
|
|
21
|
+
follow the module, graph, and orchestration guidance in `design.md`.
|
|
22
|
+
|
|
23
|
+
Describe only the modules and Module Graphs that the requirement adds or
|
|
24
|
+
changes. For each one, explain what it is, what useful behavior it exposes, and
|
|
25
|
+
how it helps the requirement. Mention its layer only when that helps explain
|
|
26
|
+
its place in the architecture.
|
|
27
|
+
|
|
28
|
+
Write the proposal in ASD-STE100 Simplified Technical English. Treat the
|
|
29
|
+
`CONTEXT.md` Language entries as the approved project vocabulary. If no context
|
|
30
|
+
file applies, use the terms already established in the project.
|
|
31
|
+
|
|
32
|
+
## Proposal
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
## The change
|
|
36
|
+
|
|
37
|
+
<What becomes possible and the high-level architectural approach.>
|
|
38
|
+
|
|
39
|
+
## Modules
|
|
40
|
+
|
|
41
|
+
### `<full module or graph path>`
|
|
42
|
+
|
|
43
|
+
<In one short, conversational paragraph, explain what this module is, what it
|
|
44
|
+
lets callers do, and how it helps complete the requirement. Describe a Module
|
|
45
|
+
Graph as one capability. Name its facade and private modules only when they make
|
|
46
|
+
that capability easier to understand.>
|
|
47
|
+
|
|
48
|
+
## How the modules connect
|
|
49
|
+
|
|
50
|
+
<Explain the dependency direction and the end-to-end flow in simple terms.
|
|
51
|
+
Mention an unchanged module only when the flow cannot be understood without it.>
|
|
52
|
+
|
|
53
|
+
## Open questions
|
|
54
|
+
|
|
55
|
+
<Only unresolved choices that would change the architecture. Omit when empty.>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Keep it high-level and conversational. Explain the module promises and the
|
|
59
|
+
connections between them. Do not list files, implementation steps, tests, call
|
|
60
|
+
signatures, status labels, or unrelated architecture.
|