## [2026-05-13T05:43:44.566Z]
Add predicate-trace.ts renderer.

Why: Plan Task 1.6. The file-when evaluator emits a PredicateTrace tree; users need a human-readable rendering for error message NEXT blocks (spec §7). Tree shape mirrors the predicate structure so users can see which clause passed and which failed during type classification.

How to apply: pure renderer, no I/O. Recursively walks the trace and pushes lines with 4-space indent per nesting level. Marker is ✓ when result=true, ✗ when result=false. atom-path/atom-content add a 'matches' / 'does not match' verb and surface optional detail (binary, >5MB, file unreadable). exempt prints the auto-exempt reason. Plan Task 1.6.
## [2026-05-15T19:28:50.559Z]
Move IssueMessage type to model/validation, re-export from message-builder for backward compat; add eslint-plugin-boundaries to enforce §4.4 allowed_relations as file-level import constraints
## [2026-05-16T08:39:07.512Z]
Add posixPath() helper to context-file.ts and context-node.ts; normalize all file paths at output boundary — satisfies posix-paths-output aspect added via multiple flows
## [2026-05-16T17:37:14.559Z]
Added loadGraphOrAbort helper (cli-preamble.ts) to centralize the 'No .yggdrasil/ directory' error previously duplicated across 12 commands. The helper exits with a structured what/why/next message on ENOENT-shaped loader failures and rethrows other errors.
## [2026-05-16T18:22:21.557Z]
Added abortOnUnexpectedError helper to cli-preamble.ts. Generic catch-block errors across all commands now route through this single emit point, producing a uniform 'Unexpected error while <context>: <msg>' wrapped in buildIssueMessage.
## [2026-05-28T08:15:42.398Z]
Added optional references field (Array<{path, description?}>) to both NodeContextAspect and FileContextAspect interfaces. This field carries per-aspect reference paths through the data shape so the formatter can render additional 'read:' lines for each reference. The field is populated only for LLM aspects; AST aspects always produce undefined.
## [2026-05-28T08:20:02.034Z]
Added truncate.ts (shared helper, MAX_DESC=80) and updated context-file.ts and context-node.ts to render aspect references as additional read: lines after the primary verifiedAgainst path. References with descriptions are truncated at word boundaries to keep context output concise. This supports the aspect-references feature (Task 9) so agents can see all files they need to read for each aspect in one context call.
## [2026-05-28T11:11:03.552Z]
Added shared message builder for aspect-status validation errors. The builder returns an IssueMessage literal (engine-module convention) so parsers can attach it directly to their structured error tuples without going through buildIssueMessage. This module will be reused by upcoming validators that check status inheritance and side-table attach-site overrides — centralizing the message text keeps the wording uniform across all status diagnostics.
## [2026-05-28T11:23:19.110Z]
Added impliesStatusInheritInvalidMessage builder. Mirrors aspectStatusInvalidMessage shape (what/why/next IssueMessage) and uses the local posixPath helper for the path in the next-field. Reports the implier, implied id, the bad value, and the file to edit. The accepted values are 'strictest' and 'own-default' — explained inline in next: so the agent does not need to consult external docs to fix the issue.
## [2026-05-28T12:19:41.996Z]
Append aspectStatusDowngradeMessage builder paired with the new validator pass. The builder follows the what/why/next pattern: WHAT — node attaches aspect with status X but cascade brings status Y from origin Z; WHY — explicit attach-site cannot relax (downgrade) the cascading anchor without silently weakening enforcement; NEXT — either drop the explicit override (let the cascade win) or raise the cascading source. Origin text is opaque from the builder's view: the validator passes 'aspect-default and other channels' when the explicit site is the own channel with no cross-channel anchor, otherwise it passes the raw channel-specific origin string (ancestor:..., type:..., ancestor-type:..., flow:..., port:...).
## [2026-05-28T12:36:51.807Z]
Add scenario-specific draft-aspect messages for yg approve --aspect X. Scenario A explains that the aspect default is draft and every node is therefore a no-op; the message points to the aspect file with a concrete promotion step. Scenario B explains that the aspect is non-draft by default but resolves to draft on a particular node because of an attach-site override, with the override origin named so the user can decide whether to lift it.
## [2026-05-28T13:13:58.037Z]
Added three IssueMessage builders for aspect-status rendering in yg check: aspectNewlyActiveMessage (non-draft aspect lacks baseline verdict), aspectViolationEnforcedMessage (refused baseline + enforced status, error), aspectViolationAdvisoryMessage (refused baseline + advisory status, warning). Messages follow the what/why/next structure; aspect-newly-active explains that advisory status does NOT skip the initial verdict (only how a verdict renders later), so the agent does not assume advisory aspects are dormant on a fresh attach.
## [2026-05-28T13:46:59.815Z]
Added approveNodeAllDraftMessage builder for the --node Y all-draft skip path. The message mirrors the structure of the existing Scenario A/B messages (all-draft on --aspect): a what/why/next triple stating that draft aspects are dormant, no baseline is written, and pointing the agent at promoting an aspect to advisory/enforced as the unblock path.
## [2026-05-28T14:01:49.671Z]
Add optional status field of type AspectStatus to NodeContextAspect and FileContextAspect. The field is populated by the data builders to carry effective enforcement status (draft / advisory / enforced) per aspect on the owner node. Consumers render it; absence means status is unknown and consumers should fall back to enforced.
## [2026-05-28T14:13:24.671Z]
Context-file and context-node formatters render the effective aspect status as a bracketed tag immediately after the aspect id. When the status resolves to draft, the formatter emits a one-line notice that the reviewer was skipped and omits the read: lines (both the aspect content path and any reference paths) because draft aspects do not reach the reviewer. Enforced and advisory aspects retain the full read: list. This makes status visible at the entry point an agent reads before editing source, so the agent does not waste effort satisfying rules that will not be enforced and is not surprised when a draft aspect lacks supporting context.
## [2026-05-28T19:52:53.797Z]
Strip dangling design/plan section references from JSDoc and test descriptions. The design doc lives in .plans/ which is gitignored and will be deleted; references like 'spec §7', 'design §12.1', 'Task 14' become stale pointers to non-existent files. Replaced with self-contained prose. No behavior change.
## [2026-05-28T19:56:01.637Z]
Normalize nodePath through posixPath helper across all aspect-status-messages.ts builders that interpolate it. The posix-paths-output aspect requires that any path emitted on stdout/stderr is forward-slash normalized with trailing slashes stripped. Previously only aspectDir went through posixPath; nodePath flowed raw. Tests verified: no visible change for typical inputs (paths are already forward-slash); locks the invariant against future Windows callers.
## [2026-05-30T04:57:35.580Z]
Removed leaked internal planning references — task, phase, and decision identifiers and section citations — from source-code comments. These tokens named ephemeral planning artifacts that mean nothing to a future reader and violated the project's comment self-containment rule. The substantive explanation each comment carried was preserved; no code or behavior changed.
## [2026-05-31T06:24:50.489Z]
Two agent-facing diagnostics were corrected. A multi-node cascade target list rendered with a doubled path separator; it now renders with a single separator. And a configuration whose schema version is newer than this CLI supports was being wrapped as an internal bug with a file-an-issue prompt; it is now classified as the expected user error it is — telling the user to upgrade the CLI — without the bug framing. Neither changes the underlying detection; both make the output read correctly.
## [2026-05-31T16:03:34.603Z]
Replaced the hand-inlined path-separator normalization with calls to a single shared helper. The same small idiom — convert backslash separators to forward slashes, and in most places also strip a trailing slash — had been copied across many modules, so the normalization rule lived in dozens of places at once and any change to it risked drifting them out of step. Consolidating it behind one well-named helper means the rule lives in exactly one spot and each call site reads by intent instead of by a repeated regex. Behavior is unchanged: the helper bodies are byte-for-byte equivalent to the expressions they replace, and the full test suite passes identically.
