@chrisdudek/yg 5.0.4 → 5.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 +2110 -761
- package/dist/structure.d.ts +30 -11
- package/dist/structure.js +298 -273
- package/package.json +2 -3
- package/graph-schemas/yg-architecture.yaml +0 -62
- package/graph-schemas/yg-aspect.yaml +0 -194
- package/graph-schemas/yg-config.yaml +0 -53
- package/graph-schemas/yg-flow.yaml +0 -25
- package/graph-schemas/yg-node.yaml +0 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrisdudek/yg",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Architecture rules your AI coding agent can't ignore. It gets the rules for a file before it edits, and every change is checked — by a free local script or an LLM reviewer — before it moves on. Works with Claude Code, Cursor, Copilot, Codex, Cline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"dist/**/*.js",
|
|
11
11
|
"dist/**/*.d.ts",
|
|
12
12
|
"dist/**/*.wasm",
|
|
13
|
-
"dist/**/*.node-types.json"
|
|
14
|
-
"graph-schemas/"
|
|
13
|
+
"dist/**/*.node-types.json"
|
|
15
14
|
],
|
|
16
15
|
"engines": {
|
|
17
16
|
"node": ">=22"
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# yg-architecture.yaml — Schema for architecture constraints
|
|
2
|
-
# File: .yggdrasil/yg-architecture.yaml
|
|
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.
|
|
9
|
-
|
|
10
|
-
node_types:
|
|
11
|
-
<type-id>:
|
|
12
|
-
description: <string> # required — what this type is for, when to use it.
|
|
13
|
-
# absence is a FATAL architecture-invalid error (the whole type system is rejected).
|
|
14
|
-
|
|
15
|
-
when: <file-predicate> # optional — per-file classification.
|
|
16
|
-
# Types WITH `when` are file-classifying: every file in
|
|
17
|
-
# a node's mapping must satisfy the predicate (forward
|
|
18
|
-
# check). Types WITHOUT `when` are organizational:
|
|
19
|
-
# parent-only nodes — any mapping fires
|
|
20
|
-
# type-without-when-with-mapping.
|
|
21
|
-
#
|
|
22
|
-
# Grammar:
|
|
23
|
-
# path: <glob> — minimatch glob on repo-relative POSIX path
|
|
24
|
-
# content: <regex> — JavaScript regex against file content
|
|
25
|
-
# path + content combined — implicit all_of of both atoms
|
|
26
|
-
# all_of: [<predicate>, ...] — every child must satisfy
|
|
27
|
-
# any_of: [<predicate>, ...] — at least one child must satisfy
|
|
28
|
-
# not: <predicate> — single child negation
|
|
29
|
-
#
|
|
30
|
-
# See: yg knowledge read working-with-architecture
|
|
31
|
-
|
|
32
|
-
enforce: strict # optional — bidirectional enforcement.
|
|
33
|
-
# Requires `when`. Every repo file matching the type's
|
|
34
|
-
# `when` MUST belong to exactly one node of this type
|
|
35
|
-
# (backward scan). A matching file owned by no such node
|
|
36
|
-
# emits type-strict-orphan; one owned by a node of a
|
|
37
|
-
# different type emits type-strict-misplaced.
|
|
38
|
-
# Use only for types where missing the type means missing
|
|
39
|
-
# a critical aspect (security, audit, regulatory).
|
|
40
|
-
|
|
41
|
-
log_required: <boolean> # optional — default false. Enable (true) on types whose
|
|
42
|
-
# changes carry business intent worth capturing — domain
|
|
43
|
-
# logic, command handlers, persistence adapters. When true,
|
|
44
|
-
# a node of this type demands a fresh log entry before
|
|
45
|
-
# `yg check --approve` whenever its mapped source changed
|
|
46
|
-
# since the node's last positive closure. Leave omitted
|
|
47
|
-
# (false) for types whose changes carry no business decision
|
|
48
|
-
# worth forcing an entry for (e.g. config, types, constants).
|
|
49
|
-
|
|
50
|
-
aspects: # optional — aspects automatically applied to every
|
|
51
|
-
# node of this type (channel 3). Two forms per entry:
|
|
52
|
-
- <aspect-id> # bare string — unconditional
|
|
53
|
-
- id: <aspect-id> # object form — with per-site applicability filter
|
|
54
|
-
status: enforced # optional — explicit status override (channel 3).
|
|
55
|
-
# Must satisfy bump rule (bump up OK, downgrade is validator error).
|
|
56
|
-
when: <aspect-predicate> # optional — see schemas/yg-aspect.yaml for grammar
|
|
57
|
-
# These also cascade to children (channel 4).
|
|
58
|
-
|
|
59
|
-
parents: [<type-id>, ...] # optional — allowed parent node types in the hierarchy.
|
|
60
|
-
|
|
61
|
-
relations: # optional — allowed relation targets by relation type.
|
|
62
|
-
<relation-type>: [<type-id>, ...] # calls | uses | extends | implements | emits | listens
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# yg-aspect.yaml — Schema for cross-cutting aspects
|
|
2
|
-
# Each aspect is a directory under .yggdrasil/aspects/ containing this file
|
|
3
|
-
# plus any number of .md content files (for LLM aspects) or a check.mjs
|
|
4
|
-
# (for deterministic aspects).
|
|
5
|
-
#
|
|
6
|
-
# Aspect identifier = relative path from aspects/ to the directory
|
|
7
|
-
# (e.g. observability/logging). Aspects can be organized in nested
|
|
8
|
-
# directories — the directory structure is for organization only,
|
|
9
|
-
# there is no automatic parent-child inheritance between aspects.
|
|
10
|
-
#
|
|
11
|
-
# The .md content files are what the reviewer checks against source code.
|
|
12
|
-
# They should state WHAT must be satisfied and WHY.
|
|
13
|
-
|
|
14
|
-
name: CrossCuttingRequirementName # required — display name
|
|
15
|
-
description: "Short description" # required — shown in yg aspects output and context packages.
|
|
16
|
-
# Validator emits description-missing if absent.
|
|
17
|
-
|
|
18
|
-
# reviewer: # OPTIONAL — reviewer kind is inferred from rule-file presence:
|
|
19
|
-
#
|
|
20
|
-
# content.md present → llm
|
|
21
|
-
# check.mjs present → deterministic
|
|
22
|
-
# neither + implies declared → aggregate
|
|
23
|
-
#
|
|
24
|
-
# The reviewer: block is only required when you need to declare
|
|
25
|
-
# reviewer.tier: for an LLM aspect. When present, an explicit
|
|
26
|
-
# reviewer.type must agree with the inferred kind (validator
|
|
27
|
-
# error otherwise).
|
|
28
|
-
#
|
|
29
|
-
# Three kinds:
|
|
30
|
-
# llm — aspect ships content.md; an LLM reads it and
|
|
31
|
-
# judges the code against the rule.
|
|
32
|
-
# deterministic — aspect ships check.mjs; the runner executes it
|
|
33
|
-
# locally with graph-aware ctx (files, fs, graph,
|
|
34
|
-
# parsers). Language-agnostic. No LLM call, zero
|
|
35
|
-
# token cost.
|
|
36
|
-
# aggregate — aspect ships neither rule source but declares
|
|
37
|
-
# implies:. A named bundle — expands its implied
|
|
38
|
-
# aspects onto every node where effective. Has no
|
|
39
|
-
# own reviewer and produces no own verdict. An
|
|
40
|
-
# aspect with neither rule source and no implies:
|
|
41
|
-
# is rejected (aspect-empty).
|
|
42
|
-
# type: llm # optional; must be 'llm', 'deterministic', or 'aggregate' if set.
|
|
43
|
-
# tier: deep # optional, only when type: llm (or inferred llm).
|
|
44
|
-
# If omitted, the aspect uses reviewer.default from yg-config.yaml.
|
|
45
|
-
# If present, must reference a key under reviewer.tiers in the config.
|
|
46
|
-
# Forbidden when type is 'deterministic' or 'aggregate'.
|
|
47
|
-
|
|
48
|
-
status: enforced # optional — aspect-level default. enum: draft | advisory | enforced.
|
|
49
|
-
# Absent → 'enforced'.
|
|
50
|
-
# draft = reviewer skipped, no verdict, no baseline, no drift.
|
|
51
|
-
# advisory = reviewer runs; refused → warning (no block).
|
|
52
|
-
# enforced = reviewer runs; refused → error (blocks check).
|
|
53
|
-
# This is only the aspect-level default. The effective status on a
|
|
54
|
-
# node is max() across cascading channels 1–6; channel 7 (implies)
|
|
55
|
-
# carries status_inherit instead. Downgrade attempts are validator
|
|
56
|
-
# errors. Advisory and enforced verdicts are recorded in the
|
|
57
|
-
# baseline; draft aspects get no verdict.
|
|
58
|
-
|
|
59
|
-
# implies: # optional — other aspects included automatically when this
|
|
60
|
-
# # aspect is effective on a node. Two forms:
|
|
61
|
-
# - simple-aspect-id # bare string — implied unconditionally (when outer aspect passes)
|
|
62
|
-
# - id: conditional-aspect-id # object form — imply only when `when` passes on the node
|
|
63
|
-
# when: <predicate> # see `when` section below for grammar
|
|
64
|
-
# status_inherit: strictest # optional — propagation modifier for this implies edge.
|
|
65
|
-
# enum: strictest | own-default.
|
|
66
|
-
# Absent → 'strictest' (implied aspect promotes to
|
|
67
|
-
# the implier's effective status if higher than the
|
|
68
|
-
# implied aspect's own default).
|
|
69
|
-
# 'own-default' anchors the implied aspect to its
|
|
70
|
-
# own aspect-level default (decouples from implier).
|
|
71
|
-
#
|
|
72
|
-
# ASYMMETRY NOTE: attach-site entries on channels
|
|
73
|
-
# 1–6 (node, ancestor, architecture type, ancestor
|
|
74
|
-
# type, flow, port) carry an explicit `status:`
|
|
75
|
-
# VALUE. Channel 7 (implies) carries a propagation
|
|
76
|
-
# MODIFIER (`status_inherit:`) instead. Implies is
|
|
77
|
-
# not a direct attach — the implied aspect's status
|
|
78
|
-
# is structurally derived from the implier's
|
|
79
|
-
# effective status on the node. The modifier
|
|
80
|
-
# selects how to derive; a value-overriding
|
|
81
|
-
# `status:` on an implies edge would couple the
|
|
82
|
-
# edge to a literal that becomes stale if the
|
|
83
|
-
# implied aspect's own default changes.
|
|
84
|
-
# Chains expand recursively. Cycles are forbidden — CLI detects.
|
|
85
|
-
|
|
86
|
-
# when: <predicate> # optional — applicability filter. If the predicate evaluates
|
|
87
|
-
# to false on a node, this aspect is not effective on that node
|
|
88
|
-
# regardless of which channel attached it. Combines with
|
|
89
|
-
# attach-site `when` declarations via AND.
|
|
90
|
-
#
|
|
91
|
-
# Grammar:
|
|
92
|
-
# when:
|
|
93
|
-
# all_of: [<clause>, ...] # AND
|
|
94
|
-
# any_of: [<clause>, ...] # OR
|
|
95
|
-
# not: <clause> # negation
|
|
96
|
-
# <atomic> # top-level atomics imply all_of
|
|
97
|
-
#
|
|
98
|
-
# Atomic clauses:
|
|
99
|
-
# relations:
|
|
100
|
-
# <relation-type>: # calls | uses | extends | implements | emits | listens
|
|
101
|
-
# target_type: <type-id> # match target node's declared type
|
|
102
|
-
# target: <node-path> # match exact node path (relative to model/)
|
|
103
|
-
# consumes_port: <port> # match a port consumed on this relation
|
|
104
|
-
# descendants: # same as relations but evaluated against any descendant in model/
|
|
105
|
-
# relations: {...}
|
|
106
|
-
# type: <type-id>
|
|
107
|
-
# has_port: <port-name>
|
|
108
|
-
# node:
|
|
109
|
-
# type: <type-id>
|
|
110
|
-
# has_port: <port-name>
|
|
111
|
-
# has_mapping: true | false
|
|
112
|
-
#
|
|
113
|
-
# Example:
|
|
114
|
-
# when:
|
|
115
|
-
# any_of:
|
|
116
|
-
# - relations: { calls: { target_type: service-client } }
|
|
117
|
-
# - descendants: { relations: { calls: { target_type: service-client } } }
|
|
118
|
-
|
|
119
|
-
# scope: # optional — controls review granularity (applies to both LLM
|
|
120
|
-
# and deterministic aspects). Forbidden on aggregate aspects.
|
|
121
|
-
# Absent → equivalent to { per: node }.
|
|
122
|
-
#
|
|
123
|
-
# Fields:
|
|
124
|
-
# per: node | file REQUIRED. Default: node.
|
|
125
|
-
# node — one review over the whole subject set.
|
|
126
|
-
# LLM: one prompt with all subject files.
|
|
127
|
-
# Deterministic: one check(ctx) invocation; ctx.files = subject set.
|
|
128
|
-
# file — one review per subject file.
|
|
129
|
-
# LLM: one prompt per file.
|
|
130
|
-
# Deterministic: one check(ctx) invocation per file; ctx.files = [file].
|
|
131
|
-
# WARNING: per: file is ONLY for file-local rules — a per-file
|
|
132
|
-
# reviewer cannot see sibling files. Rules that need cross-file
|
|
133
|
-
# context (e.g. "correlation ID propagates across calls") must
|
|
134
|
-
# stay per: node. Before switching an aspect to per: file, verify
|
|
135
|
-
# the rule can be judged from that single file alone.
|
|
136
|
-
#
|
|
137
|
-
# files: <file-predicate> OPTIONAL. Filters which mapped files enter
|
|
138
|
-
# the subject set. Subject set = mapped files ∩ filter.
|
|
139
|
-
# Absent → all mapped files.
|
|
140
|
-
# Empty subject set after filtering → vacuous pass by design (no review,
|
|
141
|
-
# no error). An aspect may legitimately exclude every file of a node it
|
|
142
|
-
# lands on (e.g. a filter that matches only *.ts files landing on a
|
|
143
|
-
# node with only *.py files).
|
|
144
|
-
#
|
|
145
|
-
# File-predicate grammar — atoms:
|
|
146
|
-
# path: "glob" minimatch glob on repo-relative POSIX path
|
|
147
|
-
# content: "regex" JavaScript regex tested against file content
|
|
148
|
-
# Boolean combinators (same as aspect when:):
|
|
149
|
-
# all_of: [...] AND
|
|
150
|
-
# any_of: [...] OR
|
|
151
|
-
# not: <clause> negation
|
|
152
|
-
# Top-level path + content imply all_of.
|
|
153
|
-
#
|
|
154
|
-
# NOTE: path/content are FILE atoms — they belong here in scope.files.
|
|
155
|
-
# The aspect-level when: field uses NODE atoms (node, relations,
|
|
156
|
-
# descendants) and filters which NODES the aspect applies to — do not
|
|
157
|
-
# mix the two. The CLI will cross-hint you if you use an atom in the
|
|
158
|
-
# wrong site.
|
|
159
|
-
#
|
|
160
|
-
# Cost note: editing scope: (per or files) changes the input hash for
|
|
161
|
-
# every pair of this aspect — every node using the aspect needs
|
|
162
|
-
# re-verification. Run `yg impact --aspect <id>` before widening or
|
|
163
|
-
# narrowing the filter.
|
|
164
|
-
#
|
|
165
|
-
# Example:
|
|
166
|
-
# scope:
|
|
167
|
-
# per: file
|
|
168
|
-
# files:
|
|
169
|
-
# all_of:
|
|
170
|
-
# - path: "src/**/*.ts"
|
|
171
|
-
# - not: { path: "**/*.test.ts" }
|
|
172
|
-
|
|
173
|
-
# references: # optional — supporting files for the LLM reviewer.
|
|
174
|
-
# Permitted on LLM aspects ONLY (forbidden on deterministic).
|
|
175
|
-
# Each entry is a string (shorthand) OR an object { path, description? }.
|
|
176
|
-
#
|
|
177
|
-
# Example:
|
|
178
|
-
# references:
|
|
179
|
-
# - docs/error-codes.md # shorthand
|
|
180
|
-
# - path: source/cli/src/errors/codes.ts
|
|
181
|
-
# description: "Catalogue of valid error codes; reviewer rejects unknown codes."
|
|
182
|
-
#
|
|
183
|
-
# Constraints (validated by `yg check`):
|
|
184
|
-
# - Path is repo-root-relative.
|
|
185
|
-
# - No '..' that escapes the repo root; no leading '/'; no Windows drive letter; no '~'.
|
|
186
|
-
# - File must exist at check time and resolve (after symlink follow) to a regular file.
|
|
187
|
-
# - No duplicates within one aspect.
|
|
188
|
-
#
|
|
189
|
-
# Drift semantics: changes to referenced files cascade to all nodes where this
|
|
190
|
-
# aspect is effective — same as changes to content.md. Run `yg impact --file <ref>`
|
|
191
|
-
# before editing a widely-referenced file.
|
|
192
|
-
#
|
|
193
|
-
# Size limits: per-tier caps via reviewer.tiers.<tier>.references.* in yg-config.yaml.
|
|
194
|
-
# Defaults: 64 KiB per file, 256 KiB total per aspect.
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# yg-config.yaml — Schema for the Yggdrasil project configuration
|
|
2
|
-
# Located at .yggdrasil/yg-config.yaml — one per project.
|
|
3
|
-
# Edit this after running yg init to describe your project.
|
|
4
|
-
|
|
5
|
-
version: "5.0.0" # managed by CLI — do not edit manually. Tracks the CLI version
|
|
6
|
-
# that last initialized or upgraded this config.
|
|
7
|
-
|
|
8
|
-
quality: # optional — quality thresholds
|
|
9
|
-
max_direct_relations: 10 # maximum outgoing relations per node (warning if above)
|
|
10
|
-
|
|
11
|
-
parallel: 1 # optional — concurrency limit for the yg check --approve fill (positive integer, default: 1)
|
|
12
|
-
|
|
13
|
-
debug: false # optional — when true, appends all command output to .yggdrasil/.debug.log
|
|
14
|
-
# Default: false (off). Log is append-only; rotate or delete manually.
|
|
15
|
-
|
|
16
|
-
coverage: # optional — scopes the unmapped-files gate. Absent = whole repo required (today's behavior).
|
|
17
|
-
required: ["/"] # roots where an uncovered tracked file is an ERROR (blocks). "/" = whole repo.
|
|
18
|
-
excluded: [] # roots where an uncovered file is SILENT (no warning).
|
|
19
|
-
# Files outside required and excluded are a non-blocking WARNING.
|
|
20
|
-
# Subtrees containing their own nested .yggdrasil/ are auto-skipped by every check.
|
|
21
|
-
|
|
22
|
-
reviewer: # required — aspect verification during yg check --approve
|
|
23
|
-
default: standard # required when more than one tier is configured; optional with exactly one tier.
|
|
24
|
-
# Must reference one of the keys under reviewer.tiers.
|
|
25
|
-
tiers: # required — named tier configurations, minimum one entry.
|
|
26
|
-
standard: # tier name — referenced from aspects via reviewer.tier:
|
|
27
|
-
provider: ollama # provider id (one of: ollama, openai, anthropic, google,
|
|
28
|
-
# openai-compatible, claude-code, codex, gemini-cli)
|
|
29
|
-
consensus: 1 # positive odd integer >= 1 (3+ for majority vote). Per-tier.
|
|
30
|
-
config: # provider-specific settings — same fields the provider accepts.
|
|
31
|
-
model: "qwen3.5:9b" # model id
|
|
32
|
-
endpoint: "http://localhost:11434" # custom endpoint (required for ollama, openai-compatible)
|
|
33
|
-
temperature: 0 # reduces variability — keep at 0
|
|
34
|
-
# timeout: 300 # Per-call timeout in SECONDS (default 300). Only CLI providers.
|
|
35
|
-
# max_prompt_chars: 200000 # optional — assembled reviewer-prompt character cap (positive integer).
|
|
36
|
-
# Checked deterministically before the LLM call. Absent = unlimited.
|
|
37
|
-
# Exceeding this limit renders a blocking error naming remedies
|
|
38
|
-
# (split the node, shorten references, or raise the cap).
|
|
39
|
-
# Never participates in verdict identity — tuning it does not
|
|
40
|
-
# invalidate recorded baselines.
|
|
41
|
-
# Add more tiers as needed (e.g. a `deep` tier with a higher-capability model for critical aspects).
|
|
42
|
-
# An aspect references a non-default tier via:
|
|
43
|
-
#
|
|
44
|
-
# reviewer:
|
|
45
|
-
# type: llm
|
|
46
|
-
# tier: deep
|
|
47
|
-
#
|
|
48
|
-
# Tier names match ^[a-zA-Z][a-zA-Z0-9_-]{0,62}$ and `default` is reserved.
|
|
49
|
-
# yg-secrets.yaml is a deep-merge overlay over this file (gitignored): it
|
|
50
|
-
# mirrors the same shape and overrides any field locally — most often a
|
|
51
|
-
# tier's api_key, or pointing a named tier at a different provider/model.
|
|
52
|
-
# Only the tier NAME is folded into a verdict hash, so a local override never
|
|
53
|
-
# invalidates recorded baselines. Keep credentials out of this committed file.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# yg-flow.yaml — Schema for end-to-end business flows
|
|
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.
|
|
10
|
-
|
|
11
|
-
name: EndToEndProcessName # required — display name
|
|
12
|
-
description: "What this business process does" # required — shown in yg flows output and
|
|
13
|
-
# context packages. Validator emits description-missing if absent.
|
|
14
|
-
|
|
15
|
-
nodes: # required, non-empty — participant nodes (alias: participants)
|
|
16
|
-
- orders/order-service # paths relative to model/
|
|
17
|
-
- payments/payment-service # each participant (and its descendants) must satisfy
|
|
18
|
-
- inventory/inventory-service # any flow-level aspects declared below
|
|
19
|
-
|
|
20
|
-
aspects: # optional — aspects propagate to all flow participants (channel 5)
|
|
21
|
-
- simple-aspect # bare string
|
|
22
|
-
- id: conditional-aspect # object form with per-site applicability filter
|
|
23
|
-
status: enforced # optional — explicit status override (channel 5).
|
|
24
|
-
# Must satisfy bump rule (bump up OK, downgrade is validator error).
|
|
25
|
-
when: <predicate> # optional — see schemas/yg-aspect.yaml for grammar
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# yg-node.yaml — Schema for model nodes
|
|
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.
|
|
6
|
-
|
|
7
|
-
name: ComponentName # required — display name
|
|
8
|
-
type: service # required — must match a type defined in yg-architecture.yaml
|
|
9
|
-
description: "What this node does" # required — shown in context output and helps agents
|
|
10
|
-
# understand purpose. Validator emits description-missing if absent.
|
|
11
|
-
|
|
12
|
-
aspects: # optional — aspect identifiers applied directly to this node.
|
|
13
|
-
# Two forms per entry:
|
|
14
|
-
- simple-aspect # bare string — always effective once attached (channel 1)
|
|
15
|
-
- id: conditional-aspect # object form — attach with per-site applicability filter
|
|
16
|
-
status: enforced # optional — explicit status override (channel 1).
|
|
17
|
-
# Must satisfy bump rule (bump up OK, downgrade is validator error).
|
|
18
|
-
when: <predicate> # optional — see schemas/yg-aspect.yaml for grammar
|
|
19
|
-
# Aspects cascade to all child nodes.
|
|
20
|
-
|
|
21
|
-
ports: # optional — named entry points with required aspects
|
|
22
|
-
port-name: # consumers of this node reference ports via consumes
|
|
23
|
-
description: "What this port provides" # required
|
|
24
|
-
aspects: # required — aspects consumers must satisfy (channel 6)
|
|
25
|
-
- simple-aspect # bare string form
|
|
26
|
-
- id: conditional-aspect
|
|
27
|
-
status: enforced # optional — explicit status override (channel 6).
|
|
28
|
-
# Must satisfy bump rule (bump up OK, downgrade is validator error).
|
|
29
|
-
when: <predicate> # optional — object form with per-attach applicability filter
|
|
30
|
-
|
|
31
|
-
relations: # optional — outgoing dependencies to other nodes
|
|
32
|
-
# Load-bearing, not just documentation: a built-in deterministic check
|
|
33
|
-
# parses this node's mapped code and REFUSES it (relation-undeclared-dependency,
|
|
34
|
-
# always an error) if it depends on another mapped node without a relation here.
|
|
35
|
-
# One-directional — a declared relation needs no code behind it. See
|
|
36
|
-
# `yg knowledge read ports-and-relations`.
|
|
37
|
-
- target: other/module-path # required — node path relative to model/
|
|
38
|
-
type: calls # required — calls | uses | extends | implements | emits | listens
|
|
39
|
-
consumes: [port-name] # optional — port names consumed from target
|
|
40
|
-
# required when target declares ports — otherwise yg check emits a
|
|
41
|
-
# BLOCKING ERROR (port-missing-consumes) that fails the architecture gate.
|
|
42
|
-
# There is no waiver; resolve by adding consumes or removing the ports.
|
|
43
|
-
# Naming a target that declares no ports raises consumes-without-ports.
|
|
44
|
-
|
|
45
|
-
mapping: # optional — source files and directories owned by this node
|
|
46
|
-
- src/modules/component/ # directory — all files inside are owned (recursive)
|
|
47
|
-
- src/modules/component.ts # file — exact match
|
|
48
|
-
# paths are relative to repository root
|
|
49
|
-
# each source file must have exactly one owner node
|
|
50
|
-
|