archspec 1.0.2 → 1.3.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/index.js +2 -23
- package/lib/createFolderWithFiles.js +22 -0
- package/lib/init.js +9 -0
- package/lib/templates/architecture.js +380 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const path = require("path");
|
|
3
|
+
const init = require("./lib/init");
|
|
5
4
|
|
|
6
5
|
const command = process.argv[2];
|
|
7
6
|
|
|
8
7
|
if (command === "init") {
|
|
9
8
|
init();
|
|
10
9
|
} else {
|
|
11
|
-
console.log("Usage:
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function init() {
|
|
15
|
-
createFolder("architecture");
|
|
16
|
-
createFolder("governance");
|
|
17
|
-
createFolder("implementation");
|
|
18
|
-
createFolder("execution");
|
|
19
|
-
|
|
20
|
-
console.log("Governance structure initialized.");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function createFolder(name) {
|
|
24
|
-
const dirPath = path.resolve(process.cwd(), name);
|
|
25
|
-
|
|
26
|
-
if (!fs.existsSync(dirPath)) {
|
|
27
|
-
fs.mkdirSync(dirPath);
|
|
28
|
-
console.log(`Created folder: ${name}`);
|
|
29
|
-
} else {
|
|
30
|
-
console.log(`Folder already exists: ${name}`);
|
|
31
|
-
}
|
|
10
|
+
console.log("Usage: archspec init");
|
|
32
11
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
function createFolderWithFiles(folderName, files) {
|
|
5
|
+
const folderPath = path.resolve(process.cwd(), folderName);
|
|
6
|
+
|
|
7
|
+
if (!fs.existsSync(folderPath)) {
|
|
8
|
+
fs.mkdirSync(folderPath);
|
|
9
|
+
console.log(`Created folder: ${folderName}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Object.entries(files).forEach(([fileName, content]) => {
|
|
13
|
+
const filePath = path.join(folderPath, fileName);
|
|
14
|
+
|
|
15
|
+
if (!fs.existsSync(filePath)) {
|
|
16
|
+
fs.writeFileSync(filePath, content);
|
|
17
|
+
console.log(`Created file: ${folderName}/${fileName}`);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = createFolderWithFiles;
|
package/lib/init.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const createFolderWithFiles = require("./createFolderWithFiles");
|
|
2
|
+
const architectureTemplates = require("./templates/architecture");
|
|
3
|
+
|
|
4
|
+
function init() {
|
|
5
|
+
createFolderWithFiles("architecture", architectureTemplates);
|
|
6
|
+
console.log("Architecture folder initialized.");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
module.exports = init;
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
const architectureTemplates = {
|
|
2
|
+
"README.md": `# Architecture Governance
|
|
3
|
+
|
|
4
|
+
This directory defines how architecture is created and maintained.
|
|
5
|
+
|
|
6
|
+
## Source of Truth
|
|
7
|
+
- \`architecture.decisions.md\` is the ONLY source of truth.
|
|
8
|
+
- \`architecture.md\` is a GENERATED artifact and must never be edited manually.
|
|
9
|
+
|
|
10
|
+
## Core Rules
|
|
11
|
+
1. All architectural changes are expressed as Decisions.
|
|
12
|
+
2. Each Decision belongs to exactly ONE layer.
|
|
13
|
+
3. Only Decisions with \`Status: approved\` are applied.
|
|
14
|
+
4. Agents may NOT edit \`architecture.md\`.
|
|
15
|
+
5. \`architecture.md\` can be deleted and regenerated at any time.
|
|
16
|
+
|
|
17
|
+
## Layers (Fixed)
|
|
18
|
+
The system uses a bottom-up, layered architecture:
|
|
19
|
+
|
|
20
|
+
1. Infra
|
|
21
|
+
2. DAL
|
|
22
|
+
3. Services
|
|
23
|
+
4. Controllers
|
|
24
|
+
5. Routes
|
|
25
|
+
6. API Service
|
|
26
|
+
7. FE Services
|
|
27
|
+
8. Context
|
|
28
|
+
9. Components
|
|
29
|
+
|
|
30
|
+
These layers are fixed and must not be renamed or reordered.
|
|
31
|
+
|
|
32
|
+
## Workflow
|
|
33
|
+
1. Layer agent proposes a Decision (\`Status: proposed\`)
|
|
34
|
+
2. Human reviews and approves the Decision
|
|
35
|
+
3. Writer agent regenerates \`architecture.md\` from decisions
|
|
36
|
+
|
|
37
|
+
If it is not a Decision, it is not architecture.
|
|
38
|
+
|
|
39
|
+
## Operation
|
|
40
|
+
|
|
41
|
+
For daily usage and workflow, see:
|
|
42
|
+
|
|
43
|
+
- \`flow.md\` – Implementation decision lifecycle
|
|
44
|
+
- \`agent-prompts.md\` – Agent definitions
|
|
45
|
+
- \`init.md\` – Initial setup instructions
|
|
46
|
+
`,
|
|
47
|
+
|
|
48
|
+
"flow.md": `## The daily workflow (this is the loop)
|
|
49
|
+
|
|
50
|
+
### Step A – Propose
|
|
51
|
+
|
|
52
|
+
* Run a **layer agent**
|
|
53
|
+
* It appends a \`Status: proposed\` decision to \`architecture.decisions.md\`
|
|
54
|
+
|
|
55
|
+
### Step B – Validate
|
|
56
|
+
|
|
57
|
+
* Run **Architect Agent**
|
|
58
|
+
* Fix or clarify decision if blocked
|
|
59
|
+
|
|
60
|
+
### Step C – Approve (YOU)
|
|
61
|
+
|
|
62
|
+
* Change **one word**:
|
|
63
|
+
|
|
64
|
+
Status: approved
|
|
65
|
+
|
|
66
|
+
### Step D – Generate
|
|
67
|
+
|
|
68
|
+
* Run **Writer Agent**
|
|
69
|
+
* \`architecture.md\` is regenerated fully
|
|
70
|
+
|
|
71
|
+
That’s it.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Hard rules (do not break these)
|
|
76
|
+
|
|
77
|
+
* ❌ No agent edits \`architecture.md\`
|
|
78
|
+
* ❌ No decision spans multiple layers
|
|
79
|
+
* ❌ No prose inside decisions
|
|
80
|
+
* ❌ No incremental edits to architecture.md
|
|
81
|
+
* ✅ Delete + regenerate is always safe
|
|
82
|
+
|
|
83
|
+
If these rules hold → system is deterministic.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Mental model (for Cursor usage)
|
|
88
|
+
|
|
89
|
+
* \`architecture.decisions.md\` = config
|
|
90
|
+
* Writer agent = compiler
|
|
91
|
+
* \`architecture.md\` = build artifact
|
|
92
|
+
* You = approver of intent
|
|
93
|
+
* Cursor = execution environment
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### Final checkpoint
|
|
98
|
+
|
|
99
|
+
If you can:
|
|
100
|
+
|
|
101
|
+
* delete \`architecture.md\`
|
|
102
|
+
* regenerate it
|
|
103
|
+
* get the same result
|
|
104
|
+
|
|
105
|
+
✅ You’ve set it up correctly.
|
|
106
|
+
`,
|
|
107
|
+
|
|
108
|
+
"init.md": `
|
|
109
|
+
# Cursor Setup: Deterministic Bottom-Up Architecture
|
|
110
|
+
|
|
111
|
+
## 1. Create the files (once)
|
|
112
|
+
|
|
113
|
+
In your repo root:
|
|
114
|
+
|
|
115
|
+
/architecture
|
|
116
|
+
├─ architecture.decisions.md ← ONLY editable truth
|
|
117
|
+
├─ architecture.md ← GENERATED, read-only
|
|
118
|
+
└─ README.md ← rules
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 2. Initialize \`architecture.decisions.md\`
|
|
123
|
+
|
|
124
|
+
Paste this exactly, until the line \`-- END OF PASTING --\`:
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# Architecture Decisions
|
|
128
|
+
|
|
129
|
+
## Rules
|
|
130
|
+
- Decisions are the ONLY source of truth
|
|
131
|
+
- architecture.md is generated, never edited
|
|
132
|
+
- Every decision belongs to exactly ONE layer
|
|
133
|
+
- Only decisions with Status: approved are applied
|
|
134
|
+
|
|
135
|
+
## Layers (fixed)
|
|
136
|
+
- Infra
|
|
137
|
+
- DAL
|
|
138
|
+
- Services
|
|
139
|
+
- Controllers
|
|
140
|
+
- Routes
|
|
141
|
+
- API Service
|
|
142
|
+
- FE Services
|
|
143
|
+
- Context
|
|
144
|
+
- Components
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Infra
|
|
149
|
+
|
|
150
|
+
## DAL
|
|
151
|
+
|
|
152
|
+
## Services
|
|
153
|
+
|
|
154
|
+
## Controllers
|
|
155
|
+
|
|
156
|
+
## Routes
|
|
157
|
+
|
|
158
|
+
## API Service
|
|
159
|
+
|
|
160
|
+
## FE Services
|
|
161
|
+
|
|
162
|
+
## Context
|
|
163
|
+
|
|
164
|
+
## Components
|
|
165
|
+
|
|
166
|
+
-- END OF PASTING --
|
|
167
|
+
|
|
168
|
+
This file is **the system state**.
|
|
169
|
+
|
|
170
|
+
Mapping for creating identical prompts from agents-prompts.md:
|
|
171
|
+
- DAL → \`D-DAL-XXX\`
|
|
172
|
+
- Services → \`D-SVC-XXX\`
|
|
173
|
+
- Controllers → \`D-CTL-XXX\`
|
|
174
|
+
- Routes → \`D-RTE-XXX\`
|
|
175
|
+
- API Service → \`D-API-XXX\`
|
|
176
|
+
- FE Services → \`D-FES-XXX\`
|
|
177
|
+
- Context → \`D-CTX-XXX\`
|
|
178
|
+
- Components → \`D-CMP-XXX\`
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 3. Make \`architecture.md\` read-only (discipline rule)
|
|
183
|
+
|
|
184
|
+
* Never manually edit it
|
|
185
|
+
* Treat it like \`dist/\` or \`build/\`
|
|
186
|
+
* If needed, add a comment at the top:
|
|
187
|
+
<!-- GENERATED FILE – DO NOT EDIT -->
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 4. Create Cursor agents (THIS IS KEY)
|
|
192
|
+
|
|
193
|
+
- Create **one agent per layer**
|
|
194
|
+
- follow instructions in agents-prompts.md
|
|
195
|
+
`,
|
|
196
|
+
|
|
197
|
+
"agents-prompts.md": `# Architecture Agent Prompts
|
|
198
|
+
|
|
199
|
+
This document defines the **exact prompts** used to operate the architecture system in this repository.
|
|
200
|
+
|
|
201
|
+
These prompts are part of the architecture governance.
|
|
202
|
+
They must remain stable and should not be casually modified.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 1. Layer Architecture Agent (Template)
|
|
207
|
+
|
|
208
|
+
Use **one instance per layer**.
|
|
209
|
+
Duplicate this prompt and hard-code the layer name.
|
|
210
|
+
|
|
211
|
+
### Example: DAL Architecture Agent
|
|
212
|
+
|
|
213
|
+
You are the DAL Architecture Agent.
|
|
214
|
+
|
|
215
|
+
Rules:
|
|
216
|
+
- Read architecture/architecture.decisions.md
|
|
217
|
+
- Propose NEW decisions for the DAL layer ONLY
|
|
218
|
+
- Do NOT write prose
|
|
219
|
+
- Do NOT edit architecture.md
|
|
220
|
+
- Do NOT modify or replace decisions outside your layer
|
|
221
|
+
- Output ONLY a Decision block.
|
|
222
|
+
- If escalation is required, include the escalation bullet inside the Decision block as the final bullet.
|
|
223
|
+
- Each decision must be minimal and explicit
|
|
224
|
+
- If two decisions describe the same boundary, merge them
|
|
225
|
+
- Prefer definition over enforcement
|
|
226
|
+
- If the decision feels "obvious", defer it
|
|
227
|
+
- If structural invariants are required, include a Contracts section.
|
|
228
|
+
- Contracts define machine-checkable architectural invariants.
|
|
229
|
+
- Contracts must be explicit key: value pairs.
|
|
230
|
+
- Contracts must not contain prose or explanations.
|
|
231
|
+
- Contracts must be enforceable by simple structural matching.
|
|
232
|
+
|
|
233
|
+
Output format (exact):
|
|
234
|
+
|
|
235
|
+
[D-DAL-XXX]
|
|
236
|
+
Layer: DAL
|
|
237
|
+
Decision:
|
|
238
|
+
- bullet
|
|
239
|
+
- bullet
|
|
240
|
+
Contracts (optional, machine-checkable invariants):
|
|
241
|
+
- key: value
|
|
242
|
+
- key: value
|
|
243
|
+
Rationale:
|
|
244
|
+
- short
|
|
245
|
+
Confidence: High | Medium | Low
|
|
246
|
+
Status: proposed
|
|
247
|
+
|
|
248
|
+
### Layer name substitutions
|
|
249
|
+
|
|
250
|
+
Create identical prompts with only the layer name changed according to mapping in init.md
|
|
251
|
+
|
|
252
|
+
No other changes are allowed.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
## 2. Architect Validator Agent (Review Only)
|
|
256
|
+
|
|
257
|
+
<!-- This agent validates correctness and scope. It never writes state. -->
|
|
258
|
+
|
|
259
|
+
You are the Architect Validator Agent.
|
|
260
|
+
|
|
261
|
+
Rules:
|
|
262
|
+
|
|
263
|
+
- Read architecture/architecture.decisions.md ONLY
|
|
264
|
+
- Do NOT edit any files
|
|
265
|
+
- Do NOT propose new decisions
|
|
266
|
+
- Validate proposed decisions by checking:
|
|
267
|
+
- Layer correctness
|
|
268
|
+
- Conflicts with approved decisions
|
|
269
|
+
- Cross-layer violations
|
|
270
|
+
- Internal contradictions
|
|
271
|
+
- Ambiguous in bullets
|
|
272
|
+
- If a Contracts section exists, treat it as part of the decision and validate that:
|
|
273
|
+
- Contracts are explicit key-value pairs
|
|
274
|
+
- Contracts are layer-scoped
|
|
275
|
+
- Contracts do not contradict other approved decisions
|
|
276
|
+
|
|
277
|
+
Output format is STRICT.
|
|
278
|
+
|
|
279
|
+
You must output EXACTLY ONE of the following:
|
|
280
|
+
|
|
281
|
+
1) OK
|
|
282
|
+
|
|
283
|
+
OR
|
|
284
|
+
|
|
285
|
+
2) A bullet list of blocking issues.
|
|
286
|
+
|
|
287
|
+
Do NOT include:
|
|
288
|
+
- Explanations
|
|
289
|
+
- Summaries
|
|
290
|
+
- Validation traces
|
|
291
|
+
- Decision reviews
|
|
292
|
+
- Any text before or after the output
|
|
293
|
+
|
|
294
|
+
If there are no blocking issues, output ONLY:
|
|
295
|
+
|
|
296
|
+
OK
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 3. Writer Agent (Deterministic Generator)
|
|
301
|
+
|
|
302
|
+
<!-- ⚠️ This agent MUST be run in **Agent mode**, never in plan or explanation mode. -->
|
|
303
|
+
|
|
304
|
+
You are a deterministic document generator.
|
|
305
|
+
|
|
306
|
+
Input:
|
|
307
|
+
- architecture.decisions.md
|
|
308
|
+
|
|
309
|
+
Rules:
|
|
310
|
+
- Read ONLY architecture/architecture.decisions.md
|
|
311
|
+
- You must NOT read implementation/implementation.decisions.md
|
|
312
|
+
- You must write ONLY architecture.md
|
|
313
|
+
- You must NOT create, modify, or delete any other file
|
|
314
|
+
- Ignore any existing architecture.md
|
|
315
|
+
- Generate architecture.md from scratch
|
|
316
|
+
- Apply ONLY decisions with Status: approved
|
|
317
|
+
- Preserve bullet wording exactly
|
|
318
|
+
- Do NOT rephrase, summarize, or infer
|
|
319
|
+
- Sort layers in fixed order
|
|
320
|
+
- Use fixed layer order as specified in architecture/architecture.decisions.md
|
|
321
|
+
- Do NOT emit a "Layers" list; layers are represented only by section headers
|
|
322
|
+
- No creative language
|
|
323
|
+
|
|
324
|
+
Output:
|
|
325
|
+
- A complete architecture.md file
|
|
326
|
+
|
|
327
|
+
<!-- This agent is **pure compilation**. -->
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
`,
|
|
331
|
+
|
|
332
|
+
"architecture.decisions.md": `# Architecture Decisions
|
|
333
|
+
|
|
334
|
+
## Rules
|
|
335
|
+
- Decisions are the ONLY source of truth
|
|
336
|
+
- architecture.md is generated, never edited
|
|
337
|
+
- Every decision belongs to exactly ONE layer
|
|
338
|
+
- Only decisions with Status: approved are applied
|
|
339
|
+
|
|
340
|
+
## Layers (fixed)
|
|
341
|
+
- Infra
|
|
342
|
+
- DAL
|
|
343
|
+
- Services
|
|
344
|
+
- Controllers
|
|
345
|
+
- Routes
|
|
346
|
+
- API Service
|
|
347
|
+
- FE Services
|
|
348
|
+
- Context
|
|
349
|
+
- Components
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Infra
|
|
354
|
+
|
|
355
|
+
## DAL
|
|
356
|
+
|
|
357
|
+
## Services
|
|
358
|
+
|
|
359
|
+
## Controllers
|
|
360
|
+
|
|
361
|
+
## Routes
|
|
362
|
+
|
|
363
|
+
## API Service
|
|
364
|
+
|
|
365
|
+
## FE Services
|
|
366
|
+
|
|
367
|
+
## Context
|
|
368
|
+
|
|
369
|
+
## Components
|
|
370
|
+
`,
|
|
371
|
+
|
|
372
|
+
"architecture.md": `<!-- GENERATED FILE – DO NOT EDIT -->
|
|
373
|
+
|
|
374
|
+
# Architecture
|
|
375
|
+
|
|
376
|
+
This file is generated from architecture.decisions.md
|
|
377
|
+
`
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
module.exports = architectureTemplates;
|