@chrisdudek/yg 1.4.2 → 2.0.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.
@@ -1,27 +1,27 @@
1
- export const DEFAULT_CONFIG = `name: ""
1
+ export const DEFAULT_CONFIG = `version: "2.0.0"
2
2
 
3
- stack:
4
- language: ""
5
- runtime: ""
6
-
7
- standards: ""
3
+ name: ""
8
4
 
9
5
  node_types:
10
- - name: module
11
- - name: service
12
- - name: library
13
- - name: infrastructure
6
+ module:
7
+ description: "Business logic unit with clear domain responsibility"
8
+ service:
9
+ description: "Component providing functionality to other nodes"
10
+ library:
11
+ description: "Shared utility code with no domain knowledge"
12
+ infrastructure:
13
+ description: "Guards, middleware, interceptors — invisible in call graphs but affect blast radius"
14
14
 
15
15
  artifacts:
16
16
  responsibility.md:
17
17
  required: always
18
18
  description: "What this node is responsible for, and what it is not"
19
- structural_context: true
19
+ included_in_relations: true
20
20
  interface.md:
21
21
  required:
22
22
  when: has_incoming_relations
23
23
  description: "Public API — methods, parameters, return types, contracts, failure modes, exposed data structures"
24
- structural_context: true
24
+ included_in_relations: true
25
25
  internals.md:
26
26
  required: never
27
27
  description: "How the node works and why — algorithms, business rules, state machines, design decisions with rejected alternatives"
@@ -95,7 +95,22 @@ Before preflight:
95
95
 
96
96
  - Verify \`yg\` CLI is available. If not found, inform user and stop.
97
97
  - If \`yg preflight\` shows 0 nodes → enter BOOTSTRAP MODE (see Operations).
98
- - If drift report shows >10 drifted nodes → report scope to user, ask which area to prioritize. Do not resolve all at once.`;
98
+ - If drift report shows >10 drifted nodes → report scope to user, ask which area to prioritize. Do not resolve all at once.
99
+
100
+ ### Delegating to Subagents
101
+
102
+ 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:
103
+
104
+ 1. Read \`.yggdrasil/agent-rules.md\` — this is the complete operating manual
105
+ 2. Follow the Quick Start Protocol from that file before touching any mapped code
106
+
107
+ Include this as the FIRST instruction in every subagent prompt:
108
+
109
+ \`\`\`
110
+ BEFORE doing anything else: read .yggdrasil/agent-rules.md and follow its protocol.
111
+ \`\`\`
112
+
113
+ A subagent that skips this step will read code without graph context, miss architectural constraints, and produce changes that break graph-code consistency.`;
99
114
 
100
115
  // prettier-ignore
101
116
  const OPERATIONS = `## OPERATIONS
@@ -181,11 +196,11 @@ Per area checklist:
181
196
 
182
197
  - [ ] 1. \`yg owner --file <path>\` — confirm no coverage
183
198
  - [ ] 2. Determine node granularity — propose to user if unclear
184
- - [ ] 3. Create node directory, read \`schemas/node.yaml\`, create \`node.yaml\`
185
- - [ ] 4. Analyze source — for each artifact type in \`config.artifacts\`: extract content, do not invent
186
- - [ ] 5. Identify relations — add to \`node.yaml\`
199
+ - [ ] 3. Create node directory, read \`schemas/yg-node.yaml\`, create \`yg-node.yaml\`
200
+ - [ ] 4. Analyze source — for each artifact type in \`yg-config.yaml artifacts\`: extract content, do not invent
201
+ - [ ] 5. Identify relations — add to \`yg-node.yaml\`
187
202
  - [ ] 6. Identify cross-cutting requirements — add matching aspects, create if needed
188
- - [ ] 6b. For each aspect on the node: identify 2-5 code anchors (function names, constants) that evidence the pattern → add to \`node.yaml\` \`anchors\` field
203
+ - [ ] 6b. For each aspect on the node: identify 2-5 code anchors (function names, constants) that evidence the pattern → add as \`anchors\` in the aspect entry in \`yg-node.yaml\`
189
204
  - [ ] 7. Identify business process participation — add to flow, ask user if process unclear
190
205
  - [ ] 8. \`yg validate\` — fix errors
191
206
  - [ ] 9. \`yg drift-sync --node <path>\`
@@ -235,7 +250,7 @@ When reviewing graph quality (triggered by user or quality improvement):
235
250
  - [ ] 1. \`yg build-context --node <path>\`
236
251
  - [ ] 2. Read mapped source files
237
252
  - [ ] 3. For each claim in graph: verify against source code
238
- - [ ] 4. For each aspect: verify the pattern holds in THIS node. If it deviates, add \`aspect_exceptions\` in \`node.yaml\`
253
+ - [ ] 4. For each aspect: verify the pattern holds in THIS node. If it deviates, add \`exceptions\` to the aspect entry in \`yg-node.yaml\`
239
254
  - [ ] 5. Report inconsistencies
240
255
 
241
256
  **Step 2 — Completeness** (catches MISSING information):
@@ -260,7 +275,7 @@ const KNOWLEDGE_BASE = `## KNOWLEDGE BASE
260
275
 
261
276
  \`\`\`
262
277
  .yggdrasil/
263
- config.yaml vocabulary, stack, node types, artifact rules, required aspects
278
+ yg-config.yaml version, vocabulary, node types, artifact rules, required aspects
264
279
  model/ ← what exists: nodes, hierarchy, relations, file mappings
265
280
  aspects/ ← what must: cross-cutting requirements with rationale and guidance
266
281
  flows/ ← why and in what process: business processes with node participation
@@ -272,15 +287,10 @@ const KNOWLEDGE_BASE = `## KNOWLEDGE BASE
272
287
  Key facts:
273
288
 
274
289
  - **Hierarchy:** nodes nest in \`model/\`. Children inherit parent context. Do not repeat parent content in children.
275
- - **Aspect id = directory path** under \`aspects/\`. Each aspect has \`aspect.yaml\` + content \`.md\` files. No automatic parent-child — use \`implies\` explicitly.
290
+ - **Aspect id = directory path** under \`aspects/\`. Each aspect has \`yg-aspect.yaml\` + content \`.md\` files. No automatic parent-child — use \`implies\` explicitly.
276
291
  - **Flows = business processes.** A flow describes what happens in the world, not code sequences. Flow aspects propagate to all participants.
277
292
 
278
- **Node type guidance:**
279
-
280
- - \`module\` — business logic unit with clear domain responsibility
281
- - \`service\` — component providing functionality to other nodes
282
- - \`library\` — shared utility code with no domain knowledge
283
- - \`infrastructure\` — guards, resolvers, middleware, interceptors, validators that intercept or modify request flow. These affect blast radius of changes but are invisible in call graphs. Map them to make blast radius analysis accurate. Key signal: code that runs WITHOUT being explicitly called by business logic (e.g., NestJS guards, Express middleware, GraphQL resolvers).
293
+ **Node type guidance:** Each type in \`yg-config.yaml node_types\` has a \`description\` that tells you when to use it. Check the project's config for the full list and descriptions. Common types: \`module\` (business logic), \`service\` (providing functionality), \`library\` (shared utilities), \`infrastructure\` (guards, middleware, interceptors — invisible in call graphs but affect blast radius).
284
294
 
285
295
  ### Artifact Structure
286
296
 
@@ -292,26 +302,28 @@ Three artifacts capture node knowledge at three levels:
292
302
 
293
303
  **Enrichment priority (when adding incrementally):** \`interface.md\` first (highest cross-module ROI — contracts enable other nodes to reason about interactions), then \`responsibility.md\` (identity and boundaries), then \`internals.md\` (depth for complex nodes). A node with only \`interface.md\` provides more cross-module value than one with only \`internals.md\`.
294
304
 
305
+ Projects can define additional artifact types in \`yg-config.yaml\` under \`artifacts\`. Each custom artifact has a \`description\` (tells you what to write), a \`required\` condition (\`always\`, \`never\`, \`when: has_incoming_relations\`, \`when: has_aspect:<id>\`), and an \`included_in_relations\` flag (if true, included in dependency context packages for structural relations). The three standard artifacts are always present in config. Check \`yg-config.yaml\` to see all defined artifacts for the project.
306
+
295
307
  ### Context Assembly
296
308
 
297
- Run \`yg build-context --node <path>\` to get the deterministic context package for a node. The package assembles global config, hierarchy, own artifacts, aspects, and relational context. It is your architectural map. For implementation-level claims (exact call patterns, error handling, await vs fire-and-forget) — verify against source code. If the package is insufficient, enrich the graph.
309
+ Run \`yg build-context --node <path>\` to get the deterministic context package for a node. The package assembles global project identity, hierarchy, own artifacts, aspects, and relational context. It is your architectural map. For implementation-level claims (exact call patterns, error handling, await vs fire-and-forget) — verify against source code. If the package is insufficient, enrich the graph.
298
310
 
299
311
  ### Information Routing
300
312
 
301
313
  When you encounter information, route it to the correct location:
302
314
 
303
- - **Specific to this node** → local node artifact (check \`config.yaml artifacts\` for available types)
304
- - **Rule for many nodes** → aspect (\`aspects/<id>/\` with \`aspect.yaml\` + content \`.md\` files). If applies to ALL nodes of a type → \`node_types[*].required_aspects\` in \`config.yaml\`
305
- - **Business process** → flow (\`flows/<name>/\` with \`flow.yaml\` + \`description.md\`). Ask user if process unclear.
315
+ - **Specific to this node** → local node artifact (check \`yg-config.yaml artifacts\` for available types)
316
+ - **Rule for many nodes** → aspect (\`aspects/<id>/\` with \`yg-aspect.yaml\` + content \`.md\` files). If applies to ALL nodes of a type → \`node_types.<type>.required_aspects\` in \`yg-config.yaml\`
317
+ - **Business process** → flow (\`flows/<name>/\` with \`yg-flow.yaml\` + \`description.md\`). Ask user if process unclear.
306
318
  - **Shared across a domain** → parent node artifact. Children receive it through hierarchy.
307
- - **Technology stack or standard** → \`config.yaml\` under \`stack\` or \`standards\` (+ \`rationale\` field)
308
- - **Decision (why + why NOT):** one node → Decisions section of \`internals.md\` with format "Chose X over Y because Z"; category of nodes → aspect content files; tech choice → \`config.yaml\` rationale field. Always include rejected alternatives — they are the highest-value graph content. If the rationale is unknown: record the decision with "rationale: unknown" and note what CAN be observed from the code. Never invent a plausible-sounding rationale.
319
+ - **Technology stack or standard** → node artifact at the appropriate hierarchy level (e.g., root node's \`responsibility.md\` for single-stack repos, or deployment unit node for monorepos)
320
+ - **Decision (why + why NOT):** one node → Decisions section of \`internals.md\` with format "Chose X over Y because Z"; category of nodes → aspect content files; tech choice → node artifact at the level where the technology applies. Always include rejected alternatives — they are the highest-value graph content. If the rationale is unknown: record the decision with "rationale: unknown" and note what CAN be observed from the code. Never invent a plausible-sounding rationale.
309
321
 
310
322
  ### Creating Aspects
311
323
 
312
- - [ ] 1. Read \`schemas/aspect.yaml\`
324
+ - [ ] 1. Read \`schemas/yg-aspect.yaml\`
313
325
  - [ ] 2. Create \`aspects/<id>/\` directory
314
- - [ ] 3. Write \`aspect.yaml\` — name, optional description, optional implies
326
+ - [ ] 3. Write \`yg-aspect.yaml\` — name, optional description, optional implies
315
327
  - [ ] 4. Write content \`.md\` files: WHAT must be satisfied + WHY (user's words, do not invent)
316
328
  - [ ] 5. \`yg validate\`
317
329
 
@@ -323,23 +335,23 @@ Test: "Does this requirement apply to more than one node?" Yes → aspect. No
323
335
  - **Architectural:** Structural patterns with rationale (e.g., dual-rollback on provider failure, idempotency via key generation, fire-and-forget dispatch)
324
336
  - **Concurrency:** Shared concurrency strategies (e.g., pessimistic locking, retry-on-deadlock, optimistic versioning)
325
337
 
326
- When a node follows an aspect's pattern with exceptions, record exceptions in \`node.yaml\` under \`aspect_exceptions\`. Example: aspect says "fire-and-forget" but this node awaits the publish call. The exception appears in the context package next to the aspect content, preventing abstractions from masking implementation details.
338
+ When a node follows an aspect's pattern with exceptions, record them in the \`exceptions\` field of the aspect entry in \`yg-node.yaml\`. Example: aspect says "fire-and-forget" but this node awaits the publish call add \`exceptions: ["awaits publish call instead of fire-and-forget because..."]\`. Exceptions appear in the context package next to the aspect content, preventing abstractions from masking implementation details.
327
339
 
328
340
  **Aspect lifecycle warning.** Aspects decay CATASTROPHICALLY — a pattern either exists or it doesn't. When a pattern changes, ALL aspect claims become wrong at once. This differs from other artifacts: \`interface.md\` and \`responsibility.md\` are most stable (~9-year half-life); \`internals.md\` has moderate stability (~2.5-year half-life); aspects are least stable (~2.4-year half-life, binary decay). After any significant feature addition, review ALL aspects touching the affected area. Don't wait for drift — aspects can be 100% wrong without any mapped file changing.
329
341
 
330
- **Aspect stability tiers.** If an aspect has a \`stability\` field in \`aspect.yaml\`, use it to calibrate review urgency:
342
+ **Aspect stability tiers.** If an aspect has a \`stability\` field in \`yg-aspect.yaml\`, use it to calibrate review urgency:
331
343
 
332
344
  - \`schema\` — enforced by data model; review only when data model changes (most stable)
333
345
  - \`protocol\` — contractual pattern; review when contracts or interfaces change
334
346
  - \`implementation\` — specific mechanism; review after ANY significant code change (least stable)
335
347
 
336
- When code anchors (\`anchors\` field in \`node.yaml\`) are present for an aspect, they list code patterns (function names, constants, SQL fragments) evidencing the aspect's implementation in this node. \`yg validate\` checks that each anchor exists in the node's mapped source files — a missing anchor (W014) signals the aspect may be stale for this node.
348
+ When code anchors (\`anchors\` in an aspect entry in \`yg-node.yaml\`) are present, they list code patterns (function names, constants, SQL fragments) evidencing the aspect's implementation in this node. \`yg validate\` checks that each anchor exists in the node's mapped source files — a missing anchor (W014) signals the aspect may be stale for this node.
337
349
 
338
350
  ### Creating Flows
339
351
 
340
- - [ ] 1. Read \`schemas/flow.yaml\`
352
+ - [ ] 1. Read \`schemas/yg-flow.yaml\`
341
353
  - [ ] 2. Create \`flows/<name>/\` directory
342
- - [ ] 3. Write \`flow.yaml\` — declare participants and flow-level aspects
354
+ - [ ] 3. Write \`yg-flow.yaml\` — declare participants and flow-level aspects
343
355
  - [ ] 4. Write \`description.md\` with required sections: Business context, Trigger, Goal, Participants, Paths (at least Happy path), Invariants across all paths
344
356
  - [ ] 5. \`yg validate\`
345
357
 
@@ -350,7 +362,7 @@ Test: "Does this describe what happens in the world, or only in the software?" I
350
362
  ### Operational Rules
351
363
 
352
364
  - **English only** for all files in \`.yggdrasil/\`. Conversation can be any language.
353
- - **Read schemas before creating** any \`node.yaml\`, \`aspect.yaml\`, or \`flow.yaml\`.
365
+ - **Read schemas before creating** any \`yg-node.yaml\`, \`yg-aspect.yaml\`, or \`yg-flow.yaml\`.
354
366
  - **Tools read, you write.** The \`yg\` CLI only reads, validates, and manages metadata. You create and edit files manually.
355
367
  - **Incremental sync.** Run \`yg drift-sync\` after every 3-5 source file changes. Do not defer to end of task.
356
368
  - **Completeness test:** Two checks, both required:
@@ -390,13 +402,13 @@ yg journal-archive Archive consolidated journal entries.
390
402
 
391
403
  | What you have | Where it goes |
392
404
  |---|---|
393
- | Information specific to this node | Local node artifact (check \`config.yaml artifacts\` for types) |
405
+ | Information specific to this node | Local node artifact (check \`yg-config.yaml artifacts\` for types) |
394
406
  | Rule that applies to many nodes | Aspect (content \`.md\` files in \`aspects/<id>/\`) |
395
- | Architectural invariant for a node type | Required aspect in \`config.yaml node_types\` |
396
- | Business process participation | Flow (\`flow.yaml participants\`) |
407
+ | Architectural invariant for a node type | Required aspect in \`yg-config.yaml node_types\` |
408
+ | Business process participation | Flow (\`yg-flow.yaml participants\`) |
397
409
  | Process-level requirement | Flow \`aspects\` + aspect directory |
398
410
  | Context shared across a domain | Parent node artifact |
399
- | Technology stack | \`config.yaml stack\` (+ \`rationale\` field) |
400
- | Global coding standards | \`config.yaml standards\` |`;
411
+ | Technology stack | Node artifact at appropriate hierarchy level |
412
+ | Coding standards | Node artifact at appropriate hierarchy level |`;
401
413
 
402
414
  export const AGENT_RULES_CONTENT = [CORE_PROTOCOL, OPERATIONS, KNOWLEDGE_BASE].join('\n\n---\n\n') + '\n';
@@ -1,4 +1,4 @@
1
- # aspect.yaml — Schema for cross-cutting aspects
1
+ # yg-aspect.yaml — Schema for cross-cutting aspects
2
2
  # Each aspect is a directory under .yggdrasil/aspects/ containing this file
3
3
  # plus any number of .md content files (requirements, rationale, guidance).
4
4
  # Aspect identifier = relative path from aspects/ to the directory (e.g. observability/logging).
@@ -7,3 +7,7 @@
7
7
  name: CrossCuttingRequirementName # required — display name
8
8
  description: "Short description for discovery via yg aspects" # optional
9
9
  # implies: [other-aspect, another-aspect] # optional — other aspect identifiers included automatically (recursive, must be acyclic)
10
+ # stability: protocol # optional — schema | protocol | implementation
11
+ # schema = enforced by data model (most stable)
12
+ # protocol = enforced by convention/contract
13
+ # implementation = specific mechanism (least stable, review after any code change)
@@ -1,7 +1,11 @@
1
- # config.yaml — Schema for the Yggdrasil project configuration
2
- # Located at .yggdrasil/config.yaml — one per project.
1
+ # yg-config.yaml — Schema for the Yggdrasil project configuration
2
+ # Located at .yggdrasil/yg-config.yaml — one per project.
3
3
  # Edit this after running yg init to describe your project.
4
4
 
5
+ version: "2.0.0" # managed by CLI — do not edit manually. Tracks the CLI version
6
+ # that created or last migrated this config. Used by the migration
7
+ # system to determine which migrations to run on upgrade.
8
+
5
9
  name: "My Project" # required — project display name
6
10
 
7
11
  stack: # required — technology stack (freeform keys)
@@ -13,22 +17,25 @@ stack: # required — technology stack (freeform keys
13
17
 
14
18
  standards: "" # optional — global coding conventions (free text)
15
19
 
16
- node_types: # required — allowed node type names
17
- - name: module # each type needs at least a 'name'
20
+ node_types: # required — non-empty object of node type definitions
21
+ module: # key = type name used in yg-node.yaml
22
+ description: "Business logic unit with clear domain responsibility"
18
23
  # required_aspects: [] # optional — aspects every node of this type must have
19
- - name: service
20
- - name: library
24
+ service:
25
+ description: "Component providing functionality to other nodes"
26
+ library:
27
+ description: "Shared utility code with no domain knowledge"
21
28
 
22
29
  artifacts: # required — artifact type definitions
23
30
  responsibility.md: # key = filename in node directories
24
31
  required: always # always | never | { when: <condition> }
25
32
  description: "What this node is responsible for, and what it is not"
26
- structural_context: true # true = included in dependency context packages
33
+ included_in_relations: true # true = included in dependency context packages
27
34
  interface.md:
28
35
  required:
29
36
  when: has_incoming_relations # conditions: has_incoming_relations, has_outgoing_relations, has_aspect:<id>
30
37
  description: "Public API — methods, parameters, return types, contracts"
31
- structural_context: true
38
+ included_in_relations: true
32
39
  # Additional artifact types: logic.md, constraints.md, errors.md, model.md, state.md, decisions.md
33
40
 
34
41
  quality: # optional — quality thresholds
@@ -1,4 +1,4 @@
1
- # flow.yaml — Schema for end-to-end business flows
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
3
  # plus description.md with required sections (see rules).
4
4
 
@@ -1,12 +1,19 @@
1
- # node.yaml — Schema for model nodes
1
+ # yg-node.yaml — Schema for model nodes
2
2
  # Every node is a directory under .yggdrasil/model/ containing this file
3
- # plus artifact .md files defined in config.yaml.
3
+ # plus artifact .md files defined in yg-config.yaml.
4
4
 
5
5
  name: ComponentName # required — display name
6
6
  type: service # required — must match a type from config.node_types
7
- aspects: [] # optional — list of aspect identifiers (directory paths under aspects/)
8
7
  blackbox: false # optional, default false — if true, coarse-grained coverage without deep artifacts
9
8
 
9
+ aspects: # optional — list of aspect configurations
10
+ - aspect: aspect-id # required — aspect identifier (directory path under aspects/)
11
+ exceptions: # optional — how this node deviates from the aspect's pattern
12
+ - "Description of deviation and why"
13
+ anchors: # optional — code patterns for aspect staleness detection
14
+ - functionName # yg validate checks each pattern exists in mapped source files (W014)
15
+ - CONSTANT_NAME
16
+
10
17
  relations: # optional — outgoing dependencies to other nodes
11
18
  - target: other/module-path # required — path relative to model/
12
19
  type: calls # required — calls | uses | extends | implements | emits | listens
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@chrisdudek/yg",
3
- "version": "1.4.2",
3
+ "version": "2.0.0",
4
4
  "description": "Make your repository self-aware. Persistent semantic memory and deterministic context assembly for AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "yg": "./dist/bin.js"
7
+ "yg": "dist/bin.js"
8
8
  },
9
9
  "files": [
10
10
  "dist/",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "repository": {
45
45
  "type": "git",
46
- "url": "https://github.com/krzysztofdudek/Yggdrasil.git",
46
+ "url": "git+https://github.com/krzysztofdudek/Yggdrasil.git",
47
47
  "directory": "source/cli"
48
48
  },
49
49
  "publishConfig": {
@@ -53,11 +53,13 @@
53
53
  "chalk": "^5.6.2",
54
54
  "commander": "^14.0.3",
55
55
  "ignore": "^7.0.5",
56
+ "semver": "^7.7.4",
56
57
  "yaml": "^2.8.2"
57
58
  },
58
59
  "devDependencies": {
59
60
  "@eslint/js": "^10.0.1",
60
61
  "@types/node": "^25.3.0",
62
+ "@types/semver": "^7.7.1",
61
63
  "@vitest/coverage-v8": "^4.0.18",
62
64
  "eslint": "^10.0.1",
63
65
  "prettier": "^3.8.1",