@chrisdudek/yg 4.0.2 → 4.1.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/dist/bin.js CHANGED
@@ -28,6 +28,13 @@ You verify whether source code satisfies a requirement.
28
28
  Below is a node (component) with its source files and one aspect (rule set).
29
29
  Check every rule in the aspect against the source code.
30
30
 
31
+ If source code contains a comment with the marker yg-suppress(<aspect-id>) where
32
+ <aspect-id> matches the aspect you are checking, treat the suppressed code as satisfied.
33
+ The marker must include a reason after the closing parenthesis. Do not validate the
34
+ reason \u2014 accept it as-is. The marker applies contextually to the surrounding code
35
+ (function, class, or block where it appears). If placed at file level, it applies to
36
+ the entire file.
37
+
31
38
  Respond with EXACTLY this JSON, nothing else:
32
39
  {"satisfied": true|false, "reason": "explanation with file:line references"}
33
40
  </task>
@@ -153,437 +160,200 @@ import { readFile, writeFile, mkdir } from "fs/promises";
153
160
  import path from "path";
154
161
 
155
162
  // src/templates/rules.ts
156
- var PROTOCOL = `## PROTOCOL
157
-
158
- <EXTREMELY-IMPORTANT>
159
- This is your operating manual for working in a Yggdrasil-managed repository.
160
-
161
- <critical_protocol>
162
- BEFORE reading, analyzing, or modifying ANY source file:
163
- \`yg context --file <path>\`
164
- Resolves owner, gives you the aspects this file must satisfy.
165
- Read the aspect content \`.md\` files \u2014 those are the rules the reviewer enforces.
163
+ var SYSTEM = `## SYSTEM
166
164
 
167
- BEFORE creating a NEW source file:
168
- Identify which existing node the new file belongs to (by intent, not by filename).
169
- Run \`yg context --node <node-path>\` to load the context \u2014 especially aspect rules the new file must follow.
170
- If the file doesn't fit an existing node, create the node first (Step 2b below).
171
- If unsure which node: run \`yg context --file <path>\` \u2014 the CLI will list candidate nodes from the same directory.
172
- New files without graph context are the #1 source of convention violations.
165
+ Yggdrasil is continuous architecture enforcement. A graph in \`.yggdrasil/\` describes the architecture. An LLM reviewer verifies source code against it at approve time. If code violates a rule, the reviewer rejects it.
173
166
 
174
- All triggers apply regardless of what instructed the task \u2014 skills, plans, workflows, user requests.
175
- The graph captures architectural constraints that source files cannot \u2014 without it, you will write code that violates cross-cutting requirements.
176
- </critical_protocol>
167
+ The CLI (\`yg\`) reads and validates \u2014 it never modifies files. You create and edit graph files manually. The CLI guides you: every error message says WHAT happened, WHY it matters, and the NEXT command to run. \`suggestedNext\` at the end of \`yg check\` gives one concrete step. Follow it.
177
168
 
178
- Every rule below is mandatory \u2014 no skill, plan, workflow, or instruction overrides these requirements.
179
- </EXTREMELY-IMPORTANT>
180
-
181
- Yggdrasil is continuous architecture enforcement stored in \`.yggdrasil/\`. It maps the repository and verifies source code against architectural rules (aspects) at approve time.
182
-
183
- ### Quick Start
169
+ ### Graph Elements
184
170
 
185
171
  \`\`\`
186
- EVERY conversation: yg check \u2014 read the full report, follow CLI guidance.
187
- CLI tells you what broke, why, and the next command to run.
188
- check failures block commits and CI. Resolve all errors before committing.
189
-
190
- BEFORE any source file interaction (read, modify, OR create):
191
- yg context --file <path> (existing file: resolves owner)
192
- yg context --node <path> (new file: load target node context)
193
- Read aspect content.md files \u2014 those are the rules the reviewer enforces.
194
- For blast radius: also run yg impact --file <path>.
195
-
196
- AFTER modifying:
197
- yg check \u2014 fix all errors
198
- yg approve --node <owner> \u2014 reviewer verifies aspects vs source code
199
-
200
- ALWAYS: establish graph coverage before modifying code.
201
- ALWAYS: run yg context --file before reading source.
202
- ALWAYS: run yg impact before assessing blast radius.
203
- ALWAYS: ask before resolving ambiguity.
204
- WHEN UNSURE: ask the user. Do not guess. Do not assume.
205
-
206
- How CLI guides you:
207
- Every error message follows: WHAT happened \u2192 WHY it's a problem \u2192 NEXT command.
208
- suggestedNext at the end of check gives one concrete step + remaining scale.
209
- Follow it. Re-run check after each fix.
172
+ .yggdrasil/
173
+ yg-architecture.yaml \u2190 node type definitions, default aspects per type, allowed relations
174
+ yg-config.yaml \u2190 reviewer config, quality thresholds, parallelism
175
+ model/ \u2190 nodes: what exists \u2014 hierarchy, relations, file mappings
176
+ aspects/ \u2190 aspects: what must be satisfied \u2014 enforceable rules
177
+ flows/ \u2190 flows: business processes with node participation
178
+ schemas/ \u2190 YAML schemas \u2014 read before creating any graph element
179
+ .drift-state/ \u2190 generated by CLI; never edit manually
210
180
  \`\`\`
211
181
 
212
- ### Modify Source Code
213
-
214
- You are not allowed to edit or create source code without establishing graph coverage first.
215
-
216
- **Step 1** \u2014 Get context: \`yg context --file <path>\` (resolves owner automatically)
217
-
218
- **Step 2a** \u2014 Owner found: execute checklist:
219
-
220
- - [ ] 1. \`yg context --file <path>\` \u2014 note all aspects in "Must satisfy"
221
- - [ ] 2. **Read aspect content files.** For every aspect in "Must satisfy": open and read its content \`.md\` files. The aspect description is not sufficient \u2014 the content files contain the actual enforcement rules. \`yg approve\` (step 6) delegates to a reviewer that checks source code against these rules and rejects non-compliant code.
222
- - [ ] 3. Assess blast radius: \`yg impact --node <node_path>\`
223
- - [ ] 4. Modify source code \u2014 satisfy the aspect rules
224
- - [ ] 5. Run \`yg check\` \u2014 follow CLI's suggested next command (if unfixable after 3 attempts \u2192 stop, report to user)
225
- - [ ] 5b. If you split, merged, or renamed a node: run \`yg flows\` and update any flow \`nodes\` lists that referenced the old node path.
226
- - [ ] 5c. **Aspect check** \u2014 did you just apply a pattern that also exists in other files? If the node has no aspect for it and you saw the same pattern in 3+ files, create the aspect now.
227
- - [ ] 6. Run \`yg approve --node <node_path>\` \u2014 reviewer verifies aspects vs source code
228
-
229
- **Step 2b** \u2014 Owner not found: establish coverage first. Present options to the user:
182
+ **Nodes** \u2014 components. \`model/<path>/yg-node.yaml\` with name, type, description, mapping (source files), relations, aspects, ports. Nodes nest by directory \u2014 children inherit parent aspects.
230
183
 
231
- *Partially mapped* (file unmapped but inside a mapped module): ask whether to add to existing node or create new one.
184
+ **Aspects** \u2014 enforceable rules. \`aspects/<id>/yg-aspect.yaml\` + content \`.md\` files. The content files are what the reviewer checks against source code. An aspect can declare \`implies: [other-aspect]\` \u2014 implied aspects are included recursively (must be acyclic).
232
185
 
233
- *Existing code:*
186
+ **Flows** \u2014 business processes. \`flows/<name>/yg-flow.yaml\` with name, description, nodes (participants), aspects. Flow-level aspects propagate to all participants. Descendants of a declared participant are automatically included \u2014 adding a parent node to a flow covers all its children.
234
187
 
235
- - Option A \u2014 Proper node: create node(s), map files, write description in \`yg-node.yaml\`
236
- - Option B \u2014 Abort
188
+ **Relations** \u2014 typed dependencies between nodes. Six types: \`calls\`, \`uses\`, \`extends\`, \`implements\` (structural) and \`emits\`, \`listens\` (event-based). Event relations must be paired \u2014 if A emits to B, B must have a listens from A. Architecture controls which relation types are allowed between which node types.
237
189
 
238
- *Greenfield (new code):* Only Option A. Follow the graph-first workflow:
190
+ **Ports** \u2014 named entry points on a node with required aspects. A node declares ports to say "consumers of this endpoint must satisfy these aspects." Consumers reference ports via \`consumes\` on their relation. The consumed port's aspects become effective on the consumer (channel 6). If a target has ports, the consumer must declare which it consumes \u2014 otherwise check warns about missing port contracts.
239
191
 
240
- 1. Create aspects first (cross-cutting requirements the new code must satisfy)
241
- 2. Create flows if the code participates in a business process (with flow-level aspects)
242
- 3. Create nodes: \`yg-node.yaml\` with description, mapping, relations, aspects
243
- 4. Review the context package (\`yg context\`) \u2014 aspects are the specification
244
- 5. Implement code that satisfies aspect rules. Every source file must be mapped.
245
- 6. \`yg check\`, \`yg approve\`
192
+ **Architecture** \u2014 \`yg-architecture.yaml\` defines the vocabulary: node types, default aspects per type, allowed parent types, allowed relation targets per type. This is the foundation \u2014 read it when starting work on a new repo. Changes require user confirmation. Structure details in \`schemas/yg-architecture.yaml\`.
246
193
 
247
- **Node sizing rule:** One node per cohesive feature area, NOT per directory. If a node would map >10 source files or cover >3 distinct user workflows, split it into child nodes.
194
+ ### How Aspects Reach a Node \u2014 7 Channels
248
195
 
249
- **Why sizing matters for enforcement:** The reviewer verifies aspects against ALL source files in a node. A node with too many files forces the reviewer to evaluate aspects across too much code \u2014 it may reject compliant code because it lacks focused context. Smaller nodes (2-5 source files) give the reviewer enough context to verify accurately. Design nodes so that every mapped file is relevant to every aspect on that node.
250
-
251
- **\`wide-node\` warning:** \`yg check\` emits a \`wide-node\` warning when a node with aspects maps more source files than \`quality.max_mapping_source_files\` (default: 10). This warning means: the reviewer WILL struggle with this node. Split it before running \`yg approve\` \u2014 otherwise expect false rejections.
252
-
253
- After the user chooses, return to Step 1 and follow Step 2a.
254
-
255
- ### Working from External Specifications
256
-
257
- When the user provides external documents (specs, PRDs, design docs, reference docs) as input for implementation:
258
-
259
- 1. **Read ALL spec documents BEFORE writing any code.** Understand the full scope.
260
- 2. **Extract enforceable requirements as aspects FIRST** \u2014 these are the rules the reviewer will check.
261
- 3. **The graph enforces architecture; external docs are INPUT to the graph, not a parallel source of truth.**
262
- 4. **Non-enforceable knowledge** (business strategy, personas, pricing) is not captured in the graph. Enforceable rules go to aspects.
263
-
264
- ### Conversation Lifecycle
196
+ Aspects accumulate from multiple sources simultaneously. The reviewer checks ALL of them \u2014 the node must satisfy every aspect regardless of origin.
265
197
 
266
198
  \`\`\`
267
- START (every conversation, before any work):
268
- - [ ] 1. yg check \u2192 read full report
269
- - [ ] 2. Fix any errors before starting work
270
- No exceptions. You cannot know if a file is mapped without running yg.
271
-
272
- UNDERSTANDING any source file (questions, research, OR planning):
273
- - [ ] 1. yg context --file <path>
274
- Mapped \u2192 read structured text output. Aspect content files are listed with "read:" prefix \u2014 read them.
275
- Unmapped \u2192 use file analysis, state it is not graph-backed.
276
- Never use grep or raw file reads as primary understanding when graph coverage exists.
277
-
278
- BEFORE reasoning about source code, state which graph context you loaded:
279
- "graph: <node_path>" if mapped, "graph: unmapped" if not.
280
-
281
- WRAP-UP (user signals "done", "wrap up", "that's enough"):
282
- - [ ] 1. yg check \u2192 fix all errors
283
- - [ ] 2. Report: which nodes and files were changed
199
+ EXAMPLE: node "orders/handler" (type: command, child of "orders")
200
+
201
+ Channel 1: OWN \u2014 node.aspects: [input-validation]
202
+ Channel 2: ANCESTOR \u2014 parent "orders" has aspects: [audit-logging]
203
+ Channel 3: OWN TYPE \u2014 architecture says type "command" \u2192 [cli-command-contract]
204
+ Channel 4: ANCESTOR TYPE \u2014 parent "orders" type "module" \u2192 [] (no defaults here)
205
+ Channel 5: FLOWS \u2014 flow "order-processing" includes "orders" \u2192 flow aspects: [deterministic]
206
+ Channel 6: PORTS \u2014 relation to "payments/service" consumes port "charge" \u2192 [correlation-tracking]
207
+ Channel 7: IMPLIED \u2014 aspect "audit-logging" implies: [diagnostic-logging]
208
+
209
+ EFFECTIVE ASPECTS for "orders/handler":
210
+ input-validation \u2190 own
211
+ audit-logging \u2190 parent "orders"
212
+ cli-command-contract \u2190 architecture type "command"
213
+ deterministic \u2190 flow "order-processing" (via parent "orders")
214
+ correlation-tracking \u2190 port "charge" on "payments/service"
215
+ diagnostic-logging \u2190 implied by "audit-logging"
284
216
  \`\`\`
285
217
 
286
- ### Modify Graph
287
-
288
- - [ ] 1. Read the relevant schema from \`schemas/\` before touching any YAML
289
- - [ ] 2. Before changing an aspect or flow, check blast radius: \`yg impact --aspect <id>\` or \`yg impact --flow <name>\` \u2014 understand which nodes are affected before modifying shared rules or processes
290
- - [ ] 3. Make changes
291
- - [ ] 4. Run \`yg check\` immediately \u2014 fix all errors
292
- - [ ] 5. Verify affected source files are consistent \u2014 update if needed
293
- - [ ] 6. Run \`yg approve\` for affected nodes
294
-
295
- ### Architecture Ownership
296
-
297
- \`yg-architecture.yaml\` defines which node types exist, what each type means, and which relations are allowed between types. **Every change to this file requires user confirmation** \u2014 it defines the vocabulary and constraints for the entire graph.
298
-
299
- **On a new or empty repo:** Do NOT accept the defaults silently. Read \`yg-architecture.yaml\`, present the current types and relation rules to the user, and ask: "Does this type system fit your project, or should we adjust it?" The default types are starting points, not answers.
300
-
301
- **Before creating nodes with relations:** Read \`yg-architecture.yaml\` to check which relation types are allowed between the source and target node types. Do not guess \u2014 if the architecture does not allow \`service\` to call \`data\`, you cannot create that relation. The options are:
302
- 1. Use an allowed relation type
303
- 2. Ask the user whether to update the architecture (explain the constraint)
304
- 3. Change the node type to one that allows the needed relation
218
+ Consequences of this cascade:
219
+ - Adding an aspect to a parent applies it to ALL children. Check impact first: \`yg impact --aspect <id>\`.
220
+ - Adding a node to a flow with aspects means that node must satisfy flow aspects.
221
+ - Architecture default aspects apply to every node of that type automatically.
222
+ - Implies chains expand recursively. Cycles are forbidden \u2014 CLI detects them.
305
223
 
306
- **Never silently modify \`yg-architecture.yaml\`.** If a relation is forbidden, do NOT add the target type to the allowed list without asking the user first. Present the constraint, explain the options, let the user decide.
224
+ ### Reviewer
307
225
 
308
- ### Delegating to Subagents
309
-
310
- When you delegate work to a subagent (any subprocess, tool agent, or spawned assistant), the subagent does NOT inherit your Yggdrasil knowledge. Before any other instruction, the subagent MUST:
311
-
312
- 1. Read \`.yggdrasil/agent-rules.md\` \u2014 this is the complete operating manual
313
- 2. Follow the Quick Start Protocol from that file before touching any mapped code
226
+ The reviewer is an LLM invoked by \`yg approve\`. It receives: the aspect's content.md + all source files of the node. It checks every rule from content.md against the code.
314
227
 
315
- Include this as the FIRST instruction in every subagent prompt:
316
-
317
- \`\`\`
318
- BEFORE doing anything else: read .yggdrasil/agent-rules.md and follow its protocol.
319
- DELIVERABLES \u2014 all required, incomplete work will be rejected:
320
- 1. Working source code
321
- 2. Graph nodes for every new/modified source file
322
- 3. \`yg check\` passing
323
- \`\`\`
228
+ - **Approved** \u2192 baseline recorded, drift cleared.
229
+ - **Refused** \u2192 violation report with what and where. Fix the code, re-run approve.
324
230
 
325
- A subagent that delivers code without corresponding graph updates has not completed its task.`;
326
- var REFERENCE = `## REFERENCE
231
+ Three approve modes: \`--node <path>\` (one or more nodes), \`--aspect <id>\` (batch all nodes affected by this aspect change), \`--flow <name>\` (batch all nodes in this flow). Batch at most 3-5 nodes per invocation \u2014 the reviewer loses accuracy with too many. Use \`--dry-run\` to preview the reviewer prompt without making an LLM call.
327
232
 
328
- ### Graph Structure
233
+ ### Drift and Cascade
329
234
 
330
- \`\`\`
331
- .yggdrasil/
332
- yg-config.yaml \u2190 project config: reviewer, quality thresholds, parallel
333
- yg-architecture.yaml \u2190 node type definitions, default aspects per type
334
- model/ \u2190 what exists: nodes, hierarchy, relations, file mappings
335
- aspects/ \u2190 what must: cross-cutting requirements \u2014 the ONLY enforcement rules
336
- flows/ \u2190 why and in what process: business processes with node participation
337
- schemas/ \u2190 YAML schemas \u2014 read before creating any graph element
338
- .drift-state/ \u2190 generated by CLI; never edit manually
339
- \`\`\`
235
+ Drift = source code or upstream context changed since the last approve. The reviewer must verify again. \`yg check\` detects two kinds:
340
236
 
341
- Key facts:
237
+ - **Source drift** \u2014 mapped source files were modified. Fix: \`yg approve --node <path>\`.
238
+ - **Upstream drift (cascade)** \u2014 an aspect, parent node, flow, or dependency changed. This cascades: one aspect change can cause drift in every node that uses it. Fix: \`yg approve --aspect <id>\` or approve affected nodes individually.
342
239
 
343
- - **Hierarchy:** nodes nest in \`model/\`. Children inherit parent aspects. Parent aspects flow to children automatically. **Consequence:** before nesting nodes under a parent, check which aspects the parent has \u2014 every child must satisfy ALL of them. If an aspect applies to the parent but not to a specific child, either move the aspect to the children that need it, or make the child a top-level node instead.
344
- - **Aspect id = directory path** under \`aspects/\`. Each aspect has \`yg-aspect.yaml\` + content \`.md\` files. Content files contain enforcement rules checked by the reviewer. No automatic parent-child \u2014 use \`implies\` explicitly.
345
- - **Flows = business processes.** A flow describes what happens in the world, not code sequences. Flow aspects propagate to all participants.
346
- - **Nodes = \`yg-node.yaml\` only.** Name, type, description, mapping, relations, aspects, ports. No \`.md\` files in nodes.
240
+ Cascade is the cost multiplier. Before changing a widely-used aspect, run \`yg impact --aspect <id>\` to see how many nodes will need re-approval. Each is a separate LLM call.
347
241
 
348
- **Node type guidance:** Each type in \`yg-architecture.yaml node_types\` has a \`description\` that tells you when to use it. Check the project's architecture file for the full list and descriptions. Common types: \`module\` (business logic), \`service\` (providing functionality), \`library\` (shared utilities), \`infrastructure\` (guards, middleware, interceptors \u2014 invisible in call graphs but affect blast radius).
242
+ If you modify code without reading the aspect content files (\`yg context --file\` \u2192 follow the \`read:\` paths), you will likely write code that violates rules you didn't know about. The reviewer will reject it. You will have to read the aspects anyway, then rewrite. Double cost.
349
243
 
350
- ### Aspect Distribution Channels
244
+ Do not interrupt \`yg approve\` \u2014 it processes each aspect across all source files. Interrupting leaves drift state unrecorded. Always read the full raw output \u2014 no \`| grep\`, \`| head\`, \`| tail\`. The reviewer already ran; the output is the return on that cost.
351
245
 
352
- Every graph dimension is a distribution channel for aspects to nodes:
246
+ ### CLI Commands
353
247
 
354
- | Channel | How aspects reach nodes |
248
+ | Command | Purpose |
355
249
  |---|---|
356
- | Direct | \`node.aspects\` in yg-node.yaml |
357
- | Type | Architecture defines default aspects per node type |
358
- | Hierarchy | Parent aspects inherited by children |
359
- | Port | Consumer must satisfy port-required aspects |
360
- | Flow | Participants inherit flow-level aspects |
361
-
362
- ### Context Assembly
250
+ | \`yg check\` | Unified gate \u2014 drift, validation, coverage, completeness. Blocks CI. |
251
+ | \`yg context --file <path>\` | Show owning node, effective aspects (\`read:\` paths), dependencies |
252
+ | \`yg context --node <path>\` | Show node overview \u2014 aspects, flows, dependents, source files |
253
+ | \`yg approve --node <path> [<path2>...]\` | Run reviewer on one or more nodes |
254
+ | \`yg approve --aspect <id>\` | Batch approve all nodes affected by this aspect change |
255
+ | \`yg approve --flow <name>\` | Batch approve all nodes in this flow |
256
+ | \`yg approve --dry-run --node <path>\` | Preview reviewer prompt without LLM call |
257
+ | \`yg impact --node <path>\` | Blast radius \u2014 dependents, flows, cascade scope |
258
+ | \`yg impact --file <path>\` | Blast radius for a specific file |
259
+ | \`yg impact --aspect <id>\` | All nodes affected by this aspect |
260
+ | \`yg impact --flow <name>\` | All nodes in this flow |
261
+ | \`yg tree [--root <path>] [--depth <n>]\` | Browse graph structure \u2014 all nodes with type and description |
262
+ | \`yg aspects\` | List all aspects with usage counts and sources |
263
+ | \`yg flows\` | List all flows with participants and aspects |
264
+ | \`yg owner --file <path>\` | Find which node owns a source file |
265
+ | \`yg init\` | Bootstrap or refresh \`.yggdrasil/\` setup |
363
266
 
364
- Two context commands serve different purposes:
267
+ ### Impact and Cost
365
268
 
366
- - **\`yg context --node <path>\`** \u2014 node overview: aspects, flows, dependents
367
- - **\`yg context --file <path>\`** \u2014 per-file: aspects to satisfy, consumed dependencies
269
+ Every graph change has blast radius. \`yg impact\` shows how many nodes are affected. Each affected node is a separate reviewer call (LLM request) during approve. An aspect touching 20 nodes = 20 LLM calls = real cost.
368
270
 
369
- **Reading context:** Both commands output structured text. Aspect content file paths appear with a \`read:\` prefix \u2014 read each one to get the enforcement rules.
271
+ When code doesn't match an aspect, three options:
370
272
 
371
- \`yg context --node <path>\` outputs:
372
- - **Header** \u2014 node path, description, type
373
- - **Source files** \u2014 files owned by this node
374
- - **Must satisfy** \u2014 aspects with paths to content.md files
375
- - **Participates in** \u2014 flows
376
- - **Dependencies** \u2014 nodes this node depends on
377
- - **Dependents** \u2014 count of nodes that depend on this one (consequence framing for blast radius)
378
- - **Parent** \u2014 parent node
273
+ | Option | When | Cost |
274
+ |---|---|---|
275
+ | **Change code** \u2014 conform to aspect | Aspect is correct, code violates it | Proportional to files needing fixes |
276
+ | **Change aspect** \u2014 conform to code | Aspect is too narrow or wrong, code is correct | \`yg impact --aspect\` \u2192 re-approve ALL nodes with this aspect |
277
+ | **Suppress** \u2014 \`yg-suppress\` waiver | Known tech debt, refactor not now | Zero approve cost, consciously accepted risk |
379
278
 
380
- \`yg context --file <path>\` outputs:
381
- - **Owner** \u2014 node path and type (or "unmapped" with candidate nodes)
382
- - **Must satisfy** \u2014 aspects with paths to content.md files
383
- - **Dependencies consumed** \u2014 what this file uses from each dependency
384
- - **Node context** \u2014 back-pointer: run \`yg context --node\` for full node overview
279
+ This is a cost/impact trade-off. Assess, propose the option to the user, let them decide. Never choose silently \u2014 especially for options 2 and 3.`;
280
+ var DECISIONS = `## DECISIONS
385
281
 
386
- Read ALL aspect content files listed \u2014 the cost is low, the risk of skipping is high.
282
+ ### Workflow
387
283
 
388
- ### Information Routing
284
+ **Start of conversation:** \`yg check\`. If errors \u2014 fix before any other work. \`yg check\` failures block commits and CI. Nothing passes until check is clean.
389
285
 
390
- When you encounter information, route it to the correct location:
286
+ **Before touching a source file:** \`yg context --file <path>\`. Read the aspect content files listed under \`read:\`. These are the rules the reviewer will check your code against. For blast radius: \`yg impact --file <path>\`.
391
287
 
392
- - **Enforceable cross-cutting rule** \u2192 aspect (\`aspects/<id>/\` with \`yg-aspect.yaml\` + content \`.md\` files). If applies to ALL nodes of a type \u2192 architecture default aspects.
393
- - **Business process with participants** \u2192 flow (\`flows/<name>/\` with \`yg-flow.yaml\`). Process-level requirements \u2192 flow aspects.
394
- - **Node identity** \u2192 \`description\` field in \`yg-node.yaml\` (1-2 sentences).
395
- - **Already visible in source code** \u2192 not captured in the graph.
396
- - **Non-enforceable knowledge** (business strategy, personas, design decisions) \u2192 not captured in the graph. If it can be made enforceable, write it as an aspect.
288
+ **After modifying code:** \`yg check\` \u2192 fix errors \u2192 \`yg approve --node <path>\`. Approve is part of the change \u2014 the change is not done until approve passes. Do not defer approval.
397
289
 
398
- ### Quick Routing Table
290
+ **End of conversation:** \`yg check\` \u2014 resolve all drift. \`yg check\` failures block CI. If drift remains, the build breaks.
399
291
 
400
- | What you have | Where it goes |
401
- |---|---|
402
- | Cross-cutting rule (3+ nodes) | Aspect content.md |
403
- | Architectural invariant for a node type | Architecture default aspect |
404
- | Business process participation | Flow (\`yg-flow.yaml nodes\`) |
405
- | Process-level requirement | Flow \`aspects\` + aspect directory |
406
- | Node identity (brief) | \`description\` in yg-node.yaml |
407
- | Already visible in source code or config files | Not captured |
408
- | Non-enforceable knowledge | Not captured |
292
+ **Unmapped files:** \`yg context --file\` will say if a file has no owner and suggest candidates. Either add it to an existing node's mapping or create a new node. Code without graph coverage works but is not verified \u2014 inform the user and propose options.
409
293
 
410
- ### Creating Aspects
294
+ **Greenfield (no nodes yet):** Graph before code. Create architecture types, aspects, and nodes first \u2014 they are the specification. Then implement code that satisfies the aspects. \`yg check\` will guide you through coverage gaps.
411
295
 
412
- - [ ] 1. Read \`schemas/yg-aspect.yaml\`
413
- - [ ] 2. Create \`aspects/<id>/\` directory
414
- - [ ] 3. Write \`yg-aspect.yaml\` \u2014 name, description, optional implies
415
- - [ ] 4. Write content \`.md\` files: WHAT must be satisfied + WHY (user's words, do not invent)
416
- - [ ] 5. \`yg check\`
296
+ ### When to Create Graph Elements
417
297
 
418
- Test: "Does this requirement apply to more than one node?" Yes \u2192 aspect. "Can the reviewer check it against source code?" Yes \u2192 aspect. Both must be true.
298
+ **Aspect** \u2014 when the same pattern appears in 3+ files AND the reviewer can verify it against source code. Both conditions. "Every handler logs audit trail" \u2014 pattern + verifiable = aspect. "Code should be readable" \u2014 not verifiable, not an aspect. Read \`schemas/yg-aspect.yaml\` before creating. Content \`.md\` files state WHAT must be satisfied and WHY \u2014 use the user's words, never invent rationale. Things that do NOT become aspects: knowledge already visible in source code (imports, config), non-enforceable knowledge (business strategy, personas, pricing), and conventions the reviewer cannot check against code.
419
299
 
420
- ### Creating Flows
300
+ **Flow** \u2014 when you see a sequence of steps toward a business goal. Not code call sequences \u2014 real-world processes. "User places an order" = flow. "Handler calls service" = relation between nodes. Read \`schemas/yg-flow.yaml\` before creating.
421
301
 
422
- - [ ] 1. Read \`schemas/yg-flow.yaml\`
423
- - [ ] 2. Create \`flows/<name>/\` directory
424
- - [ ] 3. Write \`yg-flow.yaml\` \u2014 name, description, nodes (participant list), and flow-level aspects
425
- - [ ] 4. \`yg check\`
302
+ **Node** \u2014 one per cohesive feature area. Not per directory, not per file. If a node would map >10 source files or cover >3 distinct workflows, split into children. Why: the reviewer sees ALL files in a node. Too many files = reviewer loses context and produces false rejections. Aim for 2-5 source files per node with aspects. Read \`schemas/yg-node.yaml\` before creating.
426
303
 
427
- Test: "Does this describe what happens in the world, or only in the software?" If only software \u2014 rewrite.
304
+ **Architecture change** \u2014 when existing types don't fit the project structure. Always confirm with the user. Never silently modify \`yg-architecture.yaml\`. If a relation between types is forbidden, present the constraint and let the user decide: use an allowed relation type, change the node type, or update the architecture.
428
305
 
429
- **Flow identification heuristic:** If a spec, conversation, or code reveals a sequence of steps toward a business goal \u2014 it IS a flow. This applies to multi-actor processes AND single-actor workflows.
306
+ ### Aspect Discovery
430
307
 
431
- ### Ports
308
+ Aspects emerge from patterns \u2014 greenfield and brownfield:
432
309
 
433
- Nodes can declare typed ports \u2014 named entry points with required aspects:
310
+ - After working on 3+ files in the same area: are you applying the same pattern? If yes, create an aspect.
311
+ - Watch for "invisible" aspects: audit logging, webhook dispatch, auth guards, job dispatch \u2014 cross-cutting but easy to miss.
312
+ - Brownfield: same utility called in 3+ files = aspect waiting to be created.
434
313
 
435
- \`\`\`yaml
436
- ports:
437
- charge:
438
- description: "Charge payment"
439
- aspects: [correlation-tracking]
440
- \`\`\`
314
+ ### Delegating to Subagents
441
315
 
442
- Consumers reference ports via consumes on relations:
316
+ Subagents don't inherit Yggdrasil knowledge. First instruction in every subagent prompt:
443
317
 
444
- \`\`\`yaml
445
- relations:
446
- - target: payments/service
447
- type: calls
448
- consumes: [charge]
318
+ \`\`\`
319
+ BEFORE doing anything else: read .yggdrasil/agent-rules.md and follow its protocol.
320
+ DELIVERABLES \u2014 all required, incomplete work will be rejected:
321
+ 1. Working source code
322
+ 2. Graph nodes for every new/modified source file
323
+ 3. \`yg check\` passing
449
324
  \`\`\`
450
325
 
451
- At check time: \`port-missing-consumes\` fires if target has ports but consumer has no consumes. \`port-undefined\` fires if consumes references undefined port. \`consumes-without-ports\` fires if consumes is declared but target has no ports.
452
- At approve time: Reviewer verifies consumer satisfies port-required aspects.
453
-
454
- ### CLI Commands
455
-
456
- Core: \`yg check\`, \`yg context --node/--file\`, \`yg impact --node/--file/--aspect/--flow\`, \`yg approve --node/--aspect/--flow\`
457
- Navigation: \`yg tree [--root <path>] [--depth <n>]\`, \`yg aspects\`, \`yg flows\`, \`yg owner --file\`
458
- Setup: \`yg init\`
459
- Debug: \`yg approve --dry-run --node <path>\` \u2014 preview reviewer prompt without LLM call
460
-
461
- ### Error Categories
462
-
463
- CLI groups errors into categories. Each message tells you what happened, why,
464
- and what command to run next.
465
-
466
- - **Drift (\`source-drift\`, \`upstream-drift\`):** source files or upstream context changed since last approve. Run approve workflow.
467
- - **Structural (\`yaml-invalid\`, \`config-invalid\`, \`relation-broken\`, etc.):** YAML broken or graph inconsistent. Fix the YAML.
468
- - **Coverage (\`unmapped-files\`, \`mapping-path-missing\`):** source files not mapped. Bootstrap workflow.
469
- - **Completeness (\`description-missing\`):** required fields missing. Add them.
470
- - **Architecture (\`aspect-undefined\`, \`relation-target-forbidden\`, \`port-*\`, etc.):** references broken or contracts violated. Fix references.
471
- - **Semantic (\`aspect-violation\`, approve only):** Reviewer found aspects not satisfied in source code.
472
-
473
- Follow the CLI's suggested next command.
474
-
475
- ### Approve Enforcement
476
-
477
- Approve is the architecture enforcement gate. Binary \u2014 no flags, no negotiation.
478
-
479
- **How it works:**
480
- 1. Source or upstream context changed \u2192 run reviewer \u2192 reviewer checks each aspect's content.md against source code
481
- 2. Reviewer satisfied \u2192 \`approved\`, new baseline recorded
482
- 3. Reviewer not satisfied \u2192 \`refused\` with \`aspect-violation\` \u2014 fix source code and re-run
483
-
484
- **Three modes:**
485
-
486
- - \`yg approve --node <path> [<path2> ...]\` \u2014 one or more node paths. Multiple paths run as a batch.
487
- - \`yg approve --aspect <id>\` \u2014 batch approve all cascade nodes caused by this aspect change.
488
- - \`yg approve --flow <name>\` \u2014 batch approve all cascade nodes caused by this flow change.
489
-
490
- Batch mode runs approvals in parallel (up to \`parallel\` config limit). Use batch when \`yg check\` suggests it in \`suggestedNext\`.
491
-
492
- **Do NOT interrupt \`yg approve\`.** When reviewer is configured, approve calls the reviewer for every aspect across every source file \u2014 this takes time and is intentional. Interrupting it leaves drift state unrecorded and forces a re-run.
493
-
494
- **Always read the FULL raw output of \`yg approve\`.** Every aspect result, every error message \u2014 read it all. The reviewer already ran and the cost is paid; the output is the return on that investment.
495
-
496
- Always run the command without \`| grep\`, \`| head\`, \`| tail\`, or any filter that discards lines. Saving to a file and reading it (\`tee\`) is fine \u2014 that preserves all data. The rule is: all reviewer output must reach you unmodified.
497
-
498
- Always batch at most 3-5 nodes per approve invocation. This is a maximum, not a suggestion.
499
-
500
- **When reviewer rejects \u2014 decision tree:**
501
-
502
- 1. **Code violates aspect** \u2192 fix the code. This is the common case.
503
- 2. **Code is compliant but aspect wording is ambiguous** \u2192 fix the aspect content.md to be clearer. The escape hatch is improving the rule, not bypassing enforcement.
504
- 3. **Reviewer cannot verify because node has too many files** \u2192 the reviewer sees all source files in the node. If the node is too large, the reviewer lacks focused context. Split the node into smaller nodes so each has 2-5 source files with the relevant aspects. Never remove aspects to make approve pass \u2014 that disables enforcement.
505
- 4. **Aspect applies to this node but not to all its files** \u2192 the aspect may be too broad for this node. Either split the node (files that need the aspect vs. files that don't), or refine the aspect content.md to scope which files it applies to.
506
-
507
- **Never remove an aspect from a node to bypass a rejection.** If approve fails, the fix is in the code, the aspect wording, or the node structure \u2014 not in removing enforcement.`;
508
- var GUARD_RAILS = `## GUARD RAILS
509
-
510
- ### Core Rules
511
-
512
- 1. **Graph first.** Before reading, researching, planning, or modifying ANY source file, run \`yg context --file <path>\`. For blast radius, also run \`yg impact\`. The graph is your primary source of architectural understanding.
513
- 2. **Aspects are the specification; code implements; approve verifies.** Aspects define enforceable rules. Code must satisfy them. Approve checks compliance. This is the enforcement loop.
514
- 3. **Check blocks commits and CI.** \`yg check\` must pass before every commit. Treat this as fact. All errors (drift, structural, coverage, completeness) must be resolved.
515
- 4. **Never invent rationale.** If you don't know why a requirement exists, ask the user. Never hallucinate the reason behind an aspect.
516
- 5. **Ask before resolving ambiguity.** When multiple valid interpretations exist, stop, list options, ask the user. Never silently choose.
517
- 6. **Yggdrasil is invisible to the user.** Never mention the graph, aspects, flows, nodes, \`yg\` commands, or \`.yggdrasil/\` in conversation with the user. Present graph knowledge as your understanding \u2014 "this module handles X" not "the graph says this module handles X."
518
-
519
- ### Recognizing Graph-Required Actions
520
-
521
- What matters is the ACTION you are performing, not what instructed it. If the action involves reading, understanding, or modifying mapped code, the graph protocol applies \u2014 whether the instruction came from a skill, a plan, a user message, a brainstorming session, a debugging workflow, or your own initiative.
522
-
523
- **Actions that require \`yg context --file\`:**
524
-
525
- - Reading or exploring source files to understand a component
526
- - Proposing approaches, designs, or plans for changing code
527
- - Reviewing or debugging code
528
- - Any form of reasoning about how mapped code works or should change
529
-
530
- **Actions that also require \`yg impact\`:**
531
-
532
- - Assessing blast radius before changing or removing a component
533
- - Finding all dependents of a component
534
- - Planning cross-cutting refactors or feature removals
535
-
536
- **Actions that do NOT require yg:**
537
-
538
- - Git operations (log, diff, status, blame)
539
- - Reading documentation, READMEs, or config files outside \`.yggdrasil/\`
540
- - Running tests, builds, or linters
541
- - Working with files that \`yg context --file\` reports as unmapped
542
-
543
- ### Operational Rules
544
-
545
- - **English only** for all files in \`.yggdrasil/\`. Conversation can be any language.
546
- - **Read schemas before creating** any \`yg-node.yaml\`, \`yg-aspect.yaml\`, or \`yg-flow.yaml\`.
547
- - **Tools read, you write.** The \`yg\` CLI only reads, validates, and manages metadata. You create and edit files manually.
548
- - **Incremental approval.** Run \`yg approve\` per node after every 3-5 source file changes. Do not defer to end of task.
549
- - **Never defer approval.** When you finish modifying code, approve immediately. Do not say "I'll approve later" or leave drift for the next session. Approval is part of the change \u2014 the change is not done until approve passes.
550
- - **Description maintenance.** Every \`yg-node.yaml\`, \`yg-aspect.yaml\`, and \`yg-flow.yaml\` has a \`description\` field. Write it when creating new elements. Update it when the element's identity or purpose changes.
551
-
552
- ### Aspect Discovery During Implementation
553
-
554
- Aspects emerge from patterns \u2014 in greenfield AND brownfield:
555
-
556
- - **After working on 3+ files in the same area, pause and check:** Are you applying the same pattern repeatedly? If YES, stop and create an aspect NOW.
557
- - **Watch for "invisible" aspects:** Patterns that don't feel "architectural" but ARE cross-cutting: audit logging on every mutation, webhook dispatch after state changes, job dispatch for async operations, authorization guards on every endpoint.
558
- - **Brownfield trigger:** When you read existing code and see the same utility called in 3+ files, that IS an aspect waiting to be created.
326
+ Code without graph updates = incomplete work.
559
327
 
560
- ### Bootstrap Mode
328
+ ### \`yg-suppress\` \u2014 Inline Aspect Waiver
561
329
 
562
- Trigger: \`yg check\` shows \`unmapped-files\` with high uncovered file count, or 0 nodes.
330
+ Source code comments with \`yg-suppress(<aspect-path>) <reason>\` waive a specific aspect. The reviewer honors these unconditionally.
563
331
 
564
- - [ ] 1. Identify the active work area (files the user wants to modify)
565
- - [ ] 2. Create nodes for areas you will work on (with aspects for enforcement)
566
- - [ ] 3. Create minimal nodes (no aspects) for areas you will NOT work on \u2014 provides coverage without enforcement
567
- - [ ] 4. Scan for cross-cutting patterns \u2192 create aspects
568
- - [ ] 5. Ask user about business processes \u2192 create flows if applicable
569
- - [ ] 6. \`yg check\`, \`yg approve\` per node
570
- - [ ] 7. Proceed with user's original request
332
+ \`\`\`
333
+ // yg-suppress(cqrs/single-responsibility) brownfield handler, refactor planned
334
+ # yg-suppress(security/input-validation) static config, no user input
335
+ <!-- yg-suppress(accessibility/aria-labels) generated markup, tracked in JIRA-456 -->
336
+ \`\`\`
571
337
 
572
- Constraint: Focus on the active area. Expand incrementally.
338
+ - You may propose a suppress when you see brownfield code or known tech debt violating an aspect
339
+ - You MUST NEVER write a suppress without explicit user confirmation \u2014 no exceptions
340
+ - Provide the correct aspect-path from graph context, ask the user for the reason
341
+ - You do not invent reasons \u2014 the user provides or approves them
342
+ - The marker applies contextually to surrounding code (function, class, block). At file level, it applies to the entire file.
573
343
 
574
344
  ### Escape Hatch
575
345
 
576
- If the user explicitly requests a code-only change, comply but:
346
+ If the user explicitly requests a code-only change without graph updates: comply, but warn that this creates drift. \`yg check\` will catch it \u2014 and CI will block until it's resolved. Do not run \`yg approve\` \u2014 leave the drift visible.
577
347
 
578
- - Warn: "This creates drift. Run \`yg check\` next session to reconcile."
579
- - Do NOT run \`yg approve\` \u2014 leave the drift visible.
348
+ ### Operational Notes
580
349
 
581
- <critical_protocol>
582
- BEFORE reading, analyzing, or modifying ANY source file:
583
- \`yg context --file <path>\`
584
- One command. No exceptions. No "I'll do it later." No "this is just analysis."
585
- </critical_protocol>`;
586
- var AGENT_RULES_CONTENT = [PROTOCOL, REFERENCE, GUARD_RAILS].join("\n\n---\n\n") + "\n";
350
+ - English only for all files in \`.yggdrasil/\`. Conversation can be any language.
351
+ - Read the relevant schema from \`schemas/\` before creating any YAML file.
352
+ - Every \`yg-node.yaml\`, \`yg-aspect.yaml\`, and \`yg-flow.yaml\` needs a \`description\`. Write it when creating, update it when purpose changes.
353
+ - When renaming or splitting a node: run \`yg flows\` and update any flow \`nodes\` lists that reference the old path. \`yg check\` will catch broken references but it's faster to fix them proactively.
354
+ - When unsure about anything: ask the user. Do not guess. Do not assume.
355
+ - Never invent rationale for aspects. If you don't know why a requirement exists, ask.`;
356
+ var AGENT_RULES_CONTENT = [SYSTEM, DECISIONS].join("\n\n---\n\n") + "\n";
587
357
 
588
358
  // src/templates/platform.ts
589
359
  var AGENT_RULES_IMPORT = "@.yggdrasil/agent-rules.md";
@@ -1364,10 +1134,17 @@ var MIGRATIONS = [
1364
1134
  ];
1365
1135
 
1366
1136
  // src/cli/init.ts
1367
- function getGraphSchemasDir() {
1137
+ function getPackageRoot() {
1368
1138
  const currentDir = path5.dirname(fileURLToPath(import.meta.url));
1369
- const packageRoot = path5.join(currentDir, "..");
1370
- return path5.join(packageRoot, "graph-schemas");
1139
+ return path5.join(currentDir, "..");
1140
+ }
1141
+ function getGraphSchemasDir() {
1142
+ return path5.join(getPackageRoot(), "graph-schemas");
1143
+ }
1144
+ async function getCliVersion() {
1145
+ const pkgPath = path5.join(getPackageRoot(), "package.json");
1146
+ const pkg2 = JSON.parse(await readFile4(pkgPath, "utf-8"));
1147
+ return pkg2.version;
1371
1148
  }
1372
1149
  async function refreshSchemas(yggRoot) {
1373
1150
  const schemasDir = path5.join(yggRoot, "schemas");
@@ -1669,7 +1446,7 @@ async function existingInit(projectRoot) {
1669
1446
  }
1670
1447
  p.intro(chalk.bold("Yggdrasil Configuration"));
1671
1448
  const currentVersion = await detectVersion(yggRoot);
1672
- const cliVersion = "4.0.0";
1449
+ const cliVersion = await getCliVersion();
1673
1450
  if (currentVersion && currentVersion !== cliVersion) {
1674
1451
  const migrate = await p.confirm({
1675
1452
  message: `Graph version ${currentVersion} detected \u2014 CLI is ${cliVersion}. Run migration?`,
@@ -1767,6 +1544,7 @@ function registerInitCommand(program2) {
1767
1544
  } catch {
1768
1545
  await writeFile4(architecturePath, DEFAULT_ARCHITECTURE, "utf-8");
1769
1546
  }
1547
+ await updateConfigVersion(yggRoot, await getCliVersion());
1770
1548
  const rulesPath = await installRulesForPlatform(projectRoot, options.platform);
1771
1549
  process.stdout.write(`Rules and schemas refreshed: ${path5.relative(projectRoot, rulesPath)}
1772
1550
  `);
@@ -1,12 +1,39 @@
1
1
  # yg-architecture.yaml — Schema for architecture constraints
2
2
  # File: .yggdrasil/yg-architecture.yaml
3
- # Defines node types with architectural constraints.
3
+ #
4
+ # Defines the project's type system: what kinds of nodes exist, how they can
5
+ # relate, and which aspects apply by default. This is the foundation of the
6
+ # graph — every node declares a type, and every type must be defined here.
7
+ #
8
+ # Changes to this file affect the entire graph and should be confirmed with the user.
4
9
  # All properties except description are optional — absence means no enforcement.
10
+ # When a constraint is absent, anything is allowed. When present, only listed
11
+ # values are permitted.
5
12
 
6
13
  node_types:
7
14
  <type-id>:
8
- description: <string> # required — what this type is for
9
- aspects: [<aspect-id>] # optional — required on every file of this type
10
- parents: [<type-id>] # optional — allowed parent types
11
- relations: # optional allowed relation targets
12
- <relation-type>: [<type-id>] # calls | uses | extends | implements | emits | listens
15
+ description: <string> # required — what this type is for, when to use it
16
+
17
+ aspects: [<aspect-id>] # optional — aspects automatically applied to every node
18
+ # of this type (channel 3 in aspect resolution).
19
+ # These also cascade to children of nodes of this type
20
+ # (channel 4). Use for invariants that ALL nodes of
21
+ # this type must satisfy.
22
+
23
+ parents: [<type-id>] # optional — allowed parent node types in the hierarchy.
24
+ # If omitted, this type can appear under any parent.
25
+ # If specified, nesting under an unlisted parent type
26
+ # triggers a parent-type-forbidden error.
27
+
28
+ relations: # optional — allowed relation targets by relation type.
29
+ # If a relation type is listed, only the specified
30
+ # target types are allowed. Unlisted relation types
31
+ # are unrestricted. If omitted entirely, all relations
32
+ # are allowed.
33
+ <relation-type>: [<type-id>] # Relation types:
34
+ # calls — runtime invocation
35
+ # uses — compile-time dependency
36
+ # extends — inheritance / specialization
37
+ # implements — interface contract
38
+ # emits — publishes events (must pair with listens)
39
+ # listens — subscribes to events (must pair with emits)
@@ -1,9 +1,20 @@
1
1
  # yg-aspect.yaml — Schema for cross-cutting aspects
2
2
  # Each aspect is a directory under .yggdrasil/aspects/ containing this file
3
- # plus any number of .md content files (requirements, rationale, guidance).
4
- # Aspect identifier = relative path from aspects/ to the directory (e.g. observability/logging).
5
- # Aspects can be organized in nested directories for hierarchy.
3
+ # plus any number of .md content files.
4
+ #
5
+ # Aspect identifier = relative path from aspects/ to the directory
6
+ # (e.g. observability/logging). Aspects can be organized in nested
7
+ # directories — the directory structure is for organization only,
8
+ # there is no automatic parent-child inheritance between aspects.
9
+ #
10
+ # The .md content files are what the reviewer checks against source code.
11
+ # They should state WHAT must be satisfied and WHY.
6
12
 
7
13
  name: CrossCuttingRequirementName # required — display name
8
- description: "Short description for discovery via yg aspects" # optional
9
- # implies: [other-aspect, another-aspect] # optional other aspect identifiers included automatically (recursive, must be acyclic)
14
+ description: "Short description" # optional but recommended — shown in yg aspects output
15
+ # and context packages, helps agents discover relevant aspects
16
+
17
+ # implies: [other-aspect] # optional — other aspect identifiers included automatically
18
+ # when this aspect is effective on a node. Recursive expansion
19
+ # (A implies B implies C = all three effective). Must be acyclic
20
+ # — CLI detects and rejects cycles.
@@ -1,10 +1,22 @@
1
1
  # yg-flow.yaml — Schema for end-to-end business flows
2
2
  # Each flow is a directory under .yggdrasil/flows/ containing this file.
3
+ #
4
+ # A flow describes a business process — what happens in the world,
5
+ # not code call sequences. "User places an order" is a flow.
6
+ # "Handler calls service" is a relation between nodes.
7
+ #
8
+ # Descendants of a declared participant are automatically included —
9
+ # listing a parent node covers all its children.
3
10
 
4
11
  name: EndToEndProcessName # required — display name
5
- description: "Short description of this business process" # optional
12
+ description: "What this business process does" # optional but recommended — shown in
13
+ # yg flows output and context packages
14
+
6
15
  nodes: # required, non-empty — participant nodes (alias: participants)
7
16
  - orders/order-service # paths relative to model/
8
- - payments/payment-service
9
- - inventory/inventory-service
10
- # aspects: [requires-saga] # optional — aspect tags propagated to ALL participants
17
+ - payments/payment-service # each participant (and its descendants) must satisfy
18
+ - inventory/inventory-service # any flow-level aspects declared below
19
+
20
+ # aspects: [requires-saga] # optional — aspect identifiers propagated to ALL participants
21
+ # (channel 5 in aspect resolution). Use for requirements that
22
+ # apply to every node in this process but not globally.
@@ -1,23 +1,31 @@
1
1
  # yg-node.yaml — Schema for model nodes
2
2
  # Every node is a directory under .yggdrasil/model/ containing this file.
3
+ # The node's path in the graph = its directory path relative to model/.
4
+ # Nodes nest by directory — a node at model/orders/handler/ is a child
5
+ # of model/orders/ and inherits its parent's aspects.
3
6
 
4
7
  name: ComponentName # required — display name
5
- type: service # required — must match a type from yg-architecture.yaml
6
- description: "Short description of what this node does" # optional
8
+ type: service # required — must match a type defined in yg-architecture.yaml
9
+ description: "What this node does" # optional but recommended — shown in context output,
10
+ # helps agents understand purpose without reading code
7
11
 
8
- aspects: # optional — list of aspect identifiers
9
- - aspect-id # aspect directory name under aspects/
12
+ aspects: # optional — aspect identifiers applied directly to this node
13
+ - aspect-id # must match a directory name under aspects/
14
+ # these aspects also cascade to all child nodes
10
15
 
11
- ports: # optional — named entry points with required aspects (on target nodes)
12
- port-name:
16
+ ports: # optional — named entry points with required aspects
17
+ port-name: # consumers of this node reference ports via consumes
13
18
  description: "What this port provides" # required
14
- aspects: [aspect-id] # required — aspects consumers must satisfy
19
+ aspects: [aspect-id] # required — aspects that consumers must satisfy (channel 6)
15
20
 
16
21
  relations: # optional — outgoing dependencies to other nodes
17
- - target: other/module-path # required — path relative to model/
22
+ - target: other/module-path # required — node path relative to model/
18
23
  type: calls # required — calls | uses | extends | implements | emits | listens
19
- consumes: [port-name] # optional — port names consumed from target (required when target has ports)
24
+ consumes: [port-name] # optional — port names consumed from target
25
+ # required when target declares ports — otherwise check warns
20
26
 
21
- mapping: # optional — flat list of source file or directory paths
22
- - src/modules/component/ # paths are relative to repository root
23
- - src/modules/component.ts
27
+ mapping: # optional — source files and directories owned by this node
28
+ - src/modules/component/ # directory all files inside are owned (recursive)
29
+ - src/modules/component.ts # file — exact match
30
+ # paths are relative to repository root
31
+ # each source file must have exactly one owner node
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrisdudek/yg",
3
- "version": "4.0.2",
3
+ "version": "4.1.0",
4
4
  "description": "Continuous architecture enforcement for AI-assisted development. Aspects, review, enforcement.",
5
5
  "type": "module",
6
6
  "bin": {