## [2026-05-15T16:03:14.564Z]
Delegate migration orchestration to core/migrator-runner.ts — thin wrapper now calls coreRunVersionUpgrade for the runMigrations/updateConfigVersion sequence, then handles CLI-layer concerns (refreshSchemas, architecture file creation, installRulesForPlatform)
## [2026-05-15T17:52:31.258Z]
Fix diagnostic-logging violations: add debugWrite() to multiple catch blocks that swallow errors without re-throwing.
## [2026-05-16T08:39:06.989Z]
Use buildIssueMessage for non-TTY already-exists warning: satisfies what-why-next aspect added via init flow
## [2026-05-16T18:22:20.812Z]
Migrated remaining ad-hoc stderr errors to buildIssueMessage (constant-text errors wrapped inline) and routed generic catch-blocks through the new abortOnUnexpectedError helper from formatters/cli-preamble.ts. Reason: even after the loadGraphOrAbort centralization, command-specific errors and option-validation messages bypassed the what/why/next structure; this commit aligns them so the AST aspect added in the next commit can enforce the rule mechanically.
## [2026-05-16T18:54:56.640Z]
Wrapped --upgrade requires --platform error in buildIssueMessage. All option-validation messages in init now use the structured what/why/next form.
## [2026-05-16T19:12:22.102Z]
Wrapped '.yggdrasil exists but is not a directory' error in buildIssueMessage. All raw error writes in init.ts now route through buildIssueMessage or abortOnUnexpectedError.
## [2026-05-27T12:26:25.442Z]
Updated writeReviewerConfig to emit v5 tiers format: reviewer.tiers.standard with provider, consensus, and config block instead of v4 flat provider keys. The v5 format aligns with the config parser which rejects v4-format configs at load time.
## [2026-05-27T13:54:33.050Z]
Comment cleanup — removed version-numbered phrasing so the comment describes what the code does rather than which schema iteration introduced it.
## [2026-05-28T05:09:49.559Z]
Init upgrade command no longer threads fromVersion or toVersion through to the runner. The runner reads the current project version from yg-config.yaml itself, runs every applicable migration incrementally, and reports the landed version. The wrapper simply forwards the migration list, refreshes schemas, and installs rules.
## [2026-05-29T10:05:51.315Z]
Test suite for this command was updated to reflect the redesigned yg check output format. The old format had section headers (Structural:, Cascade summary:), per-node cascade repetition, and a Result: footer. The new format uses a single-line verdict header, grouped cascade blocks, and Why:/Fix: labelled output. Tests that asserted the old format strings were updated to the equivalent new format assertions.
## [2026-05-30T10:23:11.222Z]
Two bespoke error messages printed by the setup command — the non-interactive-terminal guard and the missing-graph-version guard on the upgrade path — were brought into line with the command error-output convention used everywhere else in this command: a user-facing failure written to standard error is prefixed with 'Error: ' so operators and scripts can recognize it consistently. Only the message prefix changed; the conditions and exit behavior are unchanged.
## [2026-05-31T02:48:26.943Z]
The non-interactive upgrade path (the one agents and CI use) discarded the migration warnings returned by the upgrade and always reported success, even when a migration was withheld because a config could not be safely migrated — so the agent saw a success message and a zero exit while the version was silently left un-bumped. That path now surfaces the warnings and exits non-zero when a migration is withheld, matching the interactive path and the documented fix-and-re-run contract. The no-mutation safety was already correct; only the missing signal was added. The motivation is that a withheld migration must never be reported as success.
## [2026-05-31T02:55:22.074Z]
Two debug-log lines emitted when an optional config or secrets file is absent named the module and the operation but omitted the underlying error detail, leaving a future reader without the actual reason the read failed. They now include the error message, matching the established diagnostic-logging convention used elsewhere in this command. The motivation is that every diagnostic an agent or maintainer reads should carry module, operation, and the concrete error — even on an expected not-found branch — so the signal is uniform.
## [2026-05-31T03:04:38.908Z]
The non-interactive upgrade now distinguishes an incomplete (withheld) upgrade from a completed one that merely emitted informational notices. It exits non-zero with the fix-and-re-run guidance only when the chain stopped early and the version was left un-advanced; when the upgrade completed it surfaces any informational notices and reports success. The earlier version treated the mere presence of any notice as a withheld upgrade, which wrongly failed a successful upgrade that happened to emit an informational notice. The motivation is an accurate success/failure signal: complete upgrades succeed, incomplete ones fail loudly, and notices are never silently dropped.
## [2026-05-31T16:03:31.581Z]
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.
## [2026-05-31T17:27:17.334Z]
Moved the shared command-layer support helpers — the graph-load-or-abort wrapper and the unexpected-error funnel — out of the formatters layer and into the command layer. These helpers must reach both the engine (to load the graph) and the formatters (to build the uniform what/why/next message), and only the command layer may legally depend on both; keeping them in the formatters layer was an upward dependency on the engine that the layering rules forbid. The helpers register no command of their own, so they live under a dedicated command-support classification rather than as a command handler. Command handlers now import them from their new command-layer location.
## [2026-06-13T05:34:22.760Z]
Initialization and upgrade now ensure the repo-root .gitattributes carries a single line marking the verdict lock file as generated, so review tools collapse its diff and language statistics exclude it. The lock is committed to the repository but is machine-written, so treating it as generated keeps human review focused on hand-authored changes. The behaviour is idempotent: it creates the file with just that line when absent, appends the line exactly once (preserving existing content and ensuring a separating newline) when the file exists without it, and does nothing when the line is already present. It runs on both fresh initialization and every upgrade so existing adopters pick it up.
## [2026-06-13T10:37:56.058Z]
The interactive setup flow described the reviewer as running during a standalone approve step that has been removed. The reviewer now runs as part of the unified check-with-approve fill, so the onboarding prose was corrected to name the current command. Text-only fix.
