yarramate 0.3.0 → 0.3.2
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.
|
@@ -4,7 +4,7 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { createHash, randomUUID } from 'node:crypto';
|
|
6
6
|
import Ajv2020Module from 'ajv/dist/2020.js';
|
|
7
|
-
import { isSeq, parseDocument } from 'yaml';
|
|
7
|
+
import { isMap, isSeq, parseDocument } from 'yaml';
|
|
8
8
|
import { isMainModule, resolveCliWorkspaceSources, } from '../cli-support.js';
|
|
9
9
|
import { compileWorkspace } from '../compiler.js';
|
|
10
10
|
import { adapterMappingLocation, loadAdapterMapping, validateAdapterMapping, } from '../adapter-mapping.js';
|
|
@@ -73,7 +73,7 @@ const publishFiles = (files) => {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
const usage = 'Usage:\n' +
|
|
76
|
-
' yarramate-likec4 map --sync <mapping.yaml> <workspace-or-source...>\n' +
|
|
76
|
+
' yarramate-likec4 map --sync [--prune] <mapping.yaml> <workspace-or-source...>\n' +
|
|
77
77
|
' yarramate-likec4 check <projection.yaml> <mapping.yaml> [--json] [--kinds <kind-mapping.yaml>] [--compare <from-state> <to-state>] <workspace-or-source...>\n' +
|
|
78
78
|
' yarramate-likec4 check <likec4-project.yaml> [--json] <workspace-or-source...>\n' +
|
|
79
79
|
' yarramate-likec4 export <projection.yaml> <mapping.yaml> [--kinds <kind-mapping.yaml>] [--compare <from-state> <to-state>] <workspace-or-source...>\n' +
|
|
@@ -91,7 +91,10 @@ const checkJson = (ok, diagnostics) => `${JSON.stringify({
|
|
|
91
91
|
const sameJson = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
92
92
|
const lowerCamel = (value) => value.replaceAll(/-([a-z0-9])/g, (_, character) => character.toUpperCase());
|
|
93
93
|
const runLikeC4MapSync = (args, cwd) => {
|
|
94
|
-
const
|
|
94
|
+
const sync = args[0];
|
|
95
|
+
const prune = args[1] === '--prune';
|
|
96
|
+
const mappingPath = args[prune ? 2 : 1];
|
|
97
|
+
const sourcePaths = args.slice(prune ? 3 : 2);
|
|
95
98
|
if (sync !== '--sync' ||
|
|
96
99
|
mappingPath === undefined ||
|
|
97
100
|
mappingPath.startsWith('-') ||
|
|
@@ -145,16 +148,23 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
145
148
|
stderr: '',
|
|
146
149
|
};
|
|
147
150
|
}
|
|
151
|
+
const graphSubjects = new Set(compilation.graph.subjects.map(({ id }) => id));
|
|
152
|
+
const staleCount = loaded.mapping.mappings.filter(({ native }) => !graphSubjects.has(native)).length;
|
|
148
153
|
const validation = validateAdapterMapping(compilation.graph, loaded.mapping);
|
|
149
|
-
|
|
154
|
+
const blockingDiagnostics = validation.ok
|
|
155
|
+
? []
|
|
156
|
+
: validation.diagnostics.filter(({ code }) => code !== 'YM601');
|
|
157
|
+
if (blockingDiagnostics.length > 0) {
|
|
150
158
|
return {
|
|
151
159
|
exitCode: 1,
|
|
152
|
-
stdout: diagnosticJson(
|
|
160
|
+
stdout: diagnosticJson(blockingDiagnostics),
|
|
153
161
|
stderr: '',
|
|
154
162
|
};
|
|
155
163
|
}
|
|
156
164
|
const mapped = new Set(loaded.mapping.mappings.map(({ native }) => native));
|
|
157
|
-
const claimedExternal = new Set(loaded.mapping.mappings
|
|
165
|
+
const claimedExternal = new Set(loaded.mapping.mappings
|
|
166
|
+
.filter(({ native }) => !prune || graphSubjects.has(native))
|
|
167
|
+
.map(({ external }) => external));
|
|
158
168
|
const architectureStates = new Set(compilation.graph.claims
|
|
159
169
|
.filter(({ predicate }) => predicate === 'yarramate/state/type')
|
|
160
170
|
.map(({ subject }) => subject));
|
|
@@ -180,18 +190,29 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
180
190
|
type: subject.type,
|
|
181
191
|
};
|
|
182
192
|
});
|
|
183
|
-
if (additions.length === 0) {
|
|
193
|
+
if (additions.length === 0 && (!prune || staleCount === 0)) {
|
|
184
194
|
return {
|
|
185
195
|
exitCode: 0,
|
|
186
|
-
stdout:
|
|
196
|
+
stdout: staleCount === 0
|
|
197
|
+
? `LikeC4 mapping ${mappingPath} is already synchronized\n`
|
|
198
|
+
: `LikeC4 mapping ${mappingPath} has ${staleCount} stale ${staleCount === 1 ? 'mapping' : 'mappings'} (use --prune)\n`,
|
|
187
199
|
stderr: '',
|
|
188
200
|
};
|
|
189
201
|
}
|
|
190
202
|
const document = parseDocument(original);
|
|
203
|
+
const mappings = document.getIn(['mappings'], true);
|
|
204
|
+
if (prune && isSeq(mappings)) {
|
|
205
|
+
const firstMappingWasPruned = mappings.items.length > 0 &&
|
|
206
|
+
isMap(mappings.items[0]) &&
|
|
207
|
+
!graphSubjects.has(String(mappings.items[0].get('native')));
|
|
208
|
+
mappings.items = mappings.items.filter((item) => !isMap(item) ||
|
|
209
|
+
graphSubjects.has(String(item.get('native'))));
|
|
210
|
+
if (firstMappingWasPruned)
|
|
211
|
+
mappings.commentBefore = undefined;
|
|
212
|
+
}
|
|
191
213
|
for (const addition of additions) {
|
|
192
214
|
document.addIn(['mappings'], addition);
|
|
193
215
|
}
|
|
194
|
-
const mappings = document.getIn(['mappings'], true);
|
|
195
216
|
if (isSeq(mappings))
|
|
196
217
|
mappings.flow = false;
|
|
197
218
|
const candidate = document.toString({ lineWidth: 0 });
|
|
@@ -207,10 +228,13 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
207
228
|
};
|
|
208
229
|
}
|
|
209
230
|
const candidateValidation = validateAdapterMapping(compilation.graph, candidateMapping.mapping);
|
|
210
|
-
|
|
231
|
+
const candidateBlockingDiagnostics = candidateValidation.ok
|
|
232
|
+
? []
|
|
233
|
+
: candidateValidation.diagnostics.filter(({ code }) => prune || code !== 'YM601');
|
|
234
|
+
if (candidateBlockingDiagnostics.length > 0) {
|
|
211
235
|
return {
|
|
212
236
|
exitCode: 1,
|
|
213
|
-
stdout: diagnosticJson(
|
|
237
|
+
stdout: diagnosticJson(candidateBlockingDiagnostics),
|
|
214
238
|
stderr: '',
|
|
215
239
|
};
|
|
216
240
|
}
|
|
@@ -223,7 +247,14 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
223
247
|
}
|
|
224
248
|
return {
|
|
225
249
|
exitCode: 0,
|
|
226
|
-
stdout:
|
|
250
|
+
stdout: prune
|
|
251
|
+
? additions.length > 0
|
|
252
|
+
? `Added ${additions.length} and pruned ${staleCount} stale LikeC4 ${staleCount === 1 ? 'mapping' : 'mappings'} in ${mappingPath}\n`
|
|
253
|
+
: `Pruned ${staleCount} stale LikeC4 ${staleCount === 1 ? 'mapping' : 'mappings'} from ${mappingPath}\n`
|
|
254
|
+
: `Added ${additions.length} LikeC4 ${additions.length === 1 ? 'mapping' : 'mappings'} to ${mappingPath}` +
|
|
255
|
+
(staleCount === 0
|
|
256
|
+
? '\n'
|
|
257
|
+
: `; left ${staleCount} stale ${staleCount === 1 ? 'mapping' : 'mappings'} (use --prune)\n`),
|
|
227
258
|
stderr: '',
|
|
228
259
|
};
|
|
229
260
|
}
|
package/package.json
CHANGED
|
@@ -52,19 +52,34 @@ document, projection, evidence, or architecture-state syntax is needed.
|
|
|
52
52
|
YAML directly when states or several related declarations make that clearer.
|
|
53
53
|
6. Add an evidence overlay only for existing subjects or stable claim IDs.
|
|
54
54
|
Evidence supports or challenges the proposal; it is not a second model.
|
|
55
|
-
7. Add
|
|
56
|
-
question.
|
|
57
|
-
|
|
55
|
+
7. Add the focused projections needed to answer the
|
|
56
|
+
repository-orientation question. Add a separate projection for every
|
|
57
|
+
ordered flow that needs a dynamic view, then include each intended view in
|
|
58
|
+
`.yarramate/integrations/likec4/project.yaml`.
|
|
59
|
+
8. Unless the user requested semantic-only output, create the optional LikeC4
|
|
60
|
+
mapping and project described in the authoring reference. Synchronize the
|
|
61
|
+
project mapping before every export, then run:
|
|
58
62
|
|
|
59
63
|
```sh
|
|
60
64
|
yarramate check .yarramate/workspace.yaml --json
|
|
65
|
+
yarramate compile .yarramate/workspace.yaml
|
|
61
66
|
yarramate evidence .yarramate/evidence/<evidence>.yaml .yarramate/workspace.yaml
|
|
62
67
|
yarramate reconcile .yarramate/workspace.yaml
|
|
63
68
|
yarramate context .yarramate/projections/<projection>.yaml .yarramate/workspace.yaml
|
|
64
69
|
yarramate view .yarramate/projections/<projection>.yaml .yarramate/workspace.yaml
|
|
70
|
+
yarramate-likec4 map --sync .yarramate/integrations/likec4/subject-mapping.yaml .yarramate/workspace.yaml
|
|
71
|
+
yarramate-likec4 export-project .yarramate/integrations/likec4/project.yaml .yarramate-out/likec4 .yarramate/workspace.yaml
|
|
65
72
|
```
|
|
66
73
|
|
|
67
|
-
9.
|
|
74
|
+
9. Audit rendering coverage before handoff. Answer these as reporting
|
|
75
|
+
questions, not Core correctness rules:
|
|
76
|
+
- Which concepts appear in no projection?
|
|
77
|
+
- Which ordered relationship chains have no dynamic view?
|
|
78
|
+
- Which projections are absent from the LikeC4 project?
|
|
79
|
+
Inspect compiled subjects, projection results, and the project definition;
|
|
80
|
+
state intentional omissions explicitly. A green check does not answer
|
|
81
|
+
these questions.
|
|
82
|
+
10. Present observations, reconciliation findings, interpretive proposals,
|
|
68
83
|
evidence gaps, and Git diff separately. Do not claim completeness from a
|
|
69
84
|
green check and do not automatically turn findings into edits.
|
|
70
85
|
|
|
@@ -84,17 +99,29 @@ yarramate view .yarramate/projections/<projection>.yaml .yarramate/workspace.yam
|
|
|
84
99
|
5. Create:
|
|
85
100
|
- an alternatives projection for the decision;
|
|
86
101
|
- a bounded target projection for implementation agents.
|
|
87
|
-
|
|
102
|
+
- one focused projection per ordered flow that needs a dynamic view.
|
|
103
|
+
Include every intended view in
|
|
104
|
+
`.yarramate/integrations/likec4/project.yaml`.
|
|
105
|
+
6. Synchronize the project mapping before every export, then run:
|
|
88
106
|
|
|
89
107
|
```sh
|
|
90
108
|
yarramate check .yarramate/workspace.yaml --json
|
|
109
|
+
yarramate compile .yarramate/workspace.yaml
|
|
91
110
|
yarramate context .yarramate/projections/<alternatives>.yaml .yarramate/workspace.yaml
|
|
92
111
|
yarramate context .yarramate/projections/<target>.yaml .yarramate/workspace.yaml
|
|
93
112
|
yarramate view .yarramate/projections/<target>.yaml .yarramate/workspace.yaml
|
|
94
|
-
yarramate
|
|
113
|
+
yarramate view .yarramate/projections/<flow>.yaml .yarramate/workspace.yaml
|
|
114
|
+
yarramate compare <document-id>#<baseline-state> <document-id>#<target-state> .yarramate/workspace.yaml
|
|
115
|
+
yarramate-likec4 map --sync .yarramate/integrations/likec4/subject-mapping.yaml .yarramate/workspace.yaml
|
|
116
|
+
yarramate-likec4 export-project .yarramate/integrations/likec4/project.yaml .yarramate-out/likec4 .yarramate/workspace.yaml
|
|
95
117
|
```
|
|
96
118
|
|
|
97
|
-
|
|
119
|
+
Skip the two adapter commands only when the user requested semantic-only
|
|
120
|
+
output, and report that no visual project was produced.
|
|
121
|
+
7. Audit rendering coverage using the same three reporting questions from
|
|
122
|
+
discovery. State which omissions are intentional; do not convert partial
|
|
123
|
+
coverage into a validation failure.
|
|
124
|
+
8. Present alternatives, selected intent, unresolved decisions, and bounded
|
|
98
125
|
implementation context. Do not generate code until the requested design
|
|
99
126
|
decision is reviewable.
|
|
100
127
|
|
|
@@ -102,6 +129,8 @@ yarramate compare <baseline-state> <target-state> .yarramate/workspace.yaml
|
|
|
102
129
|
|
|
103
130
|
- Treat `check` as deterministic correctness, never as architecture approval,
|
|
104
131
|
completeness, or quality scoring.
|
|
132
|
+
- Keep LikeC4 optional. Default to visual output for these guided journeys,
|
|
133
|
+
but respect an explicit request for tool-neutral semantic output only.
|
|
105
134
|
- Keep adapter fields outside native documents.
|
|
106
135
|
- Use globally qualified identities at CLI and projection boundaries.
|
|
107
136
|
- Preserve source-located diagnostics verbatim when asking the author to fix
|
|
@@ -119,7 +148,9 @@ Report:
|
|
|
119
148
|
- journey used and question answered;
|
|
120
149
|
- canonical files proposed or changed;
|
|
121
150
|
- observations and evidence results;
|
|
122
|
-
- projections produced
|
|
151
|
+
- projections and views produced, including the LikeC4 project and generated
|
|
152
|
+
output path;
|
|
153
|
+
- rendering coverage gaps and whether the generated output is current;
|
|
123
154
|
- validation commands and outcomes;
|
|
124
155
|
- unresolved architectural decisions;
|
|
125
156
|
- whether changes are merely proposed or already accepted in Git.
|
|
@@ -46,6 +46,9 @@ Discovery is minimally useful when:
|
|
|
46
46
|
- significant proposed subjects have traceable observations or are explicitly
|
|
47
47
|
identified as interpretation;
|
|
48
48
|
- a focused projection gives an agent useful repository context;
|
|
49
|
+
- intended projections are rendered through a current LikeC4 project;
|
|
50
|
+
- concepts outside all projections, ordered flows without dynamic views, and
|
|
51
|
+
projections absent from the project are reported as coverage gaps;
|
|
49
52
|
- evidence has not been promoted automatically.
|
|
50
53
|
|
|
51
54
|
Design is minimally useful when:
|
|
@@ -54,4 +57,6 @@ Design is minimally useful when:
|
|
|
54
57
|
- material alternatives remain reviewable;
|
|
55
58
|
- the selected target has explicit boundaries and relationships;
|
|
56
59
|
- a bounded target projection can guide implementation;
|
|
60
|
+
- intended projections are rendered through a current LikeC4 project;
|
|
61
|
+
- rendering coverage gaps are stated, including intentional omissions;
|
|
57
62
|
- missing detail is visible without becoming a Core correctness error.
|
|
@@ -172,6 +172,47 @@ Evidence evaluates an existing subject or stable claim ID. Results are
|
|
|
172
172
|
observed subject directly through evidence or mutate declared intent from an
|
|
173
173
|
evidence result.
|
|
174
174
|
|
|
175
|
+
## LikeC4 project
|
|
176
|
+
|
|
177
|
+
Keep visualization configuration outside native documents:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
format: yarramate/likec4-project/v1
|
|
181
|
+
id: delivery
|
|
182
|
+
version: "1.0"
|
|
183
|
+
title: Delivery architecture
|
|
184
|
+
mapping: .yarramate/integrations/likec4/subject-mapping.yaml
|
|
185
|
+
views:
|
|
186
|
+
- projection: .yarramate/projections/delivery-target.yaml
|
|
187
|
+
- id: submit-order
|
|
188
|
+
projection: .yarramate/projections/submit-order.yaml
|
|
189
|
+
dynamic:
|
|
190
|
+
steps:
|
|
191
|
+
- relationship: delivery#customer-triggers-submit
|
|
192
|
+
- relationship: delivery#submit-triggers-confirmation
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Give every ordered flow its own focused projection and dynamic view. A dynamic
|
|
196
|
+
view takes its title and description from its projection; reusing one broad
|
|
197
|
+
projection for several flows makes their rendered identities ambiguous.
|
|
198
|
+
Ensure every intended projection is listed in the project.
|
|
199
|
+
|
|
200
|
+
Start the referenced mapping as a valid empty mapping, then let sync populate
|
|
201
|
+
it:
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
format: yarramate/adapter-mapping/v1
|
|
205
|
+
id: delivery-likec4
|
|
206
|
+
version: "1.0"
|
|
207
|
+
adapter: likec4
|
|
208
|
+
mappings: []
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`export-project` writes `.yarramate-out/likec4/yarramate.generated.json` with
|
|
212
|
+
digests for generated files. It refuses to replace a generated file that was
|
|
213
|
+
hand-edited. Treat that refusal as drift to inspect; do not delete the marker
|
|
214
|
+
or overwrite the output manually.
|
|
215
|
+
|
|
175
216
|
## Stable commands
|
|
176
217
|
|
|
177
218
|
```sh
|
|
@@ -193,6 +234,20 @@ yarramate reconcile .yarramate/workspace.yaml
|
|
|
193
234
|
yarramate-likec4 map --sync \
|
|
194
235
|
.yarramate/integrations/likec4/subject-mapping.yaml \
|
|
195
236
|
.yarramate/workspace.yaml
|
|
237
|
+
yarramate-likec4 export-project \
|
|
238
|
+
.yarramate/integrations/likec4/project.yaml \
|
|
239
|
+
.yarramate-out/likec4 \
|
|
240
|
+
.yarramate/workspace.yaml
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Sync preserves and reports mappings for native subjects that no longer exist.
|
|
244
|
+
After confirming that those subjects were intentionally removed or renamed,
|
|
245
|
+
delete the stale entries while adding missing mappings with:
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
yarramate-likec4 map --sync --prune \
|
|
249
|
+
.yarramate/integrations/likec4/subject-mapping.yaml \
|
|
250
|
+
.yarramate/workspace.yaml
|
|
196
251
|
```
|
|
197
252
|
|
|
198
253
|
Treat exit `0` as successful execution, `1` as correctness diagnostics, and
|