Skip to content

Migrating from 2.x to 3.x

cdowin edited this page Oct 4, 2026 · 1 revision

Migrating from 2.x to 3.x

Upgrading from 2.x. Rename devkit.toml to godot-devkit.toml and delete every section only agentic-sdlc read. Move [checks] godot to [roster] checks. Both old names still work in 3.x with one deprecation line on stderr (removed in 4.0). Replace include Makefile.devkit with GDK_CHECKS := ... and include Makefile.gates; the targets you listed in [gates] extra go in GDK_CHECKS. Rename GDK_MILESTONE_TIERS to GDK_VERIFY_TIERS.

Release 3.0.0

Breaking for a consumer Makefile: the gate framework moves here from agentic-sdlc.

  • New verb install-gates writes Makefile.gates (the gate library gdk_gate / gdk_gate_sh, verdict lines, .gate-reports/ logs, and the targets help, check, precommit, verify) and tools/dev/gdk_gate.sh. A game sets GDK_CHECKS in its Makefile and includes Makefile.gates; it needs nothing from agentic-sdlc. check runs shell (shellcheck over tracked *.sh) then each target in GDK_CHECKS; precommit is check + GDK_PRECOMMIT_TIERS; verify is check + GDK_VERIFY_TIERS less GDK_VERIFY_SKIP. There is no pm, sdlc, budget, ledger code or GDK_LEDGER_CMD.
  • make milestone, GDK_MILESTONE_TIERS and GDK_MILESTONE_SKIP still work as aliases of verify, GDK_VERIFY_TIERS and GDK_VERIFY_SKIP. Remove in 4.0.
  • The config file is godot-devkit.toml (was devkit.toml), and the roster key is [roster] checks (was [checks] godot). 3.x reads both old names and prints one deprecation line on stderr. Remove in 4.0. Only godot-devkit sections belong in the file now.
  • install-ci, install-agents, install-hooks and install-sdlc are unknown commands (they were routed to agentic-sdlc, which has no CLI since 3.0). pm, init, gates-extra and check doc|shell|pm|hooks|repo-hygiene still exit 2.
  • unit.sh fails the tier when the GUT log carries a script parse error, even over a reconciled census and a green exit (#51).
  • The runners no longer file a cost row: gdk_runners.sh drops its ledger shim.
  • This repo no longer depends on agentic-sdlc and has no PM tree. Its CI (make verify) skips the build on a docs-only pull request.

Release 2.1.0 and 2.0.0

The release notes of v2.1.0 and v2.0.0 (before the Releases-only record):

v2.1.0 — 2026-10-01

  • Built and gated with agentic-sdlc 2.2.0; the README's install example pins it.
  • refs <symbol> finds what Godot wires: a scene [connection] naming it as signal= or method= (new bucket scene connections), an autoload name declared in project.godot (indexed like a class_name), and a signal or handler named as an argument (is_connected, has_signal, has_user_signal, Signal(obj, "sig")). A bare autoload or class_name in code (var g = GameState, if Bus:, Player.new(), Player.CONST) is a typed reference, and "/root/Name" is a dynamic one; 10%Player.MAX is a use, not a % node path. None of these reads as unreferenced any more.
  • New refs --rename <old> <new> [--dry-run] renames a class_name, method, signal or autoload across .gd, .tscn, .tres and project.godot as one plan, or refuses the whole rename with every blocking site named (exit 1): a dynamic hit, the name inside a string, an occurrence refs cannot prove, a scene line naming it outside a connection it rewrites (a built-in script, a NodePath("/root/…")), a <new> already defined or an <old> defined nowhere. Without types it cannot tell a project symbol from the engine's, so <old> or <new> that is an engine method or signal name (play, pressed, _ready, and common ones such as start, get, update) refuses too. A GDScript keyword as <new> exits 2. tests/ is always in scope; a matching res:// path is listed as a PATH line, never rewritten; a repeat prints already renamed and exits 0.
  • New autoloads add <Name> <res://path> and autoloads rm <Name> declare or remove one project.godot autoload (Name="*res://path"), editing only that line. --dry-run prints the diff, a repeat is a no-op, add then rm restores the file byte for byte. A missing file, a non-canonical res:// path or one whose case differs from the file on disk, a name that is not an identifier, an engine class or a project class_name (scanned as Godot scans: addons/ counts, dot-directories and .gdignored ones do not), and a name already pointing elsewhere or declared disabled each exit 1; a missing or non-UTF-8 project.godot exits 2.
  • New stats [<dir>...] [--by dir] [--json] counts files, lines and code lines per role (.gd as game, tests, tools or vendored, from the new [stats] section, each prefix a directory with or without its slash) and for .gdshader, .tscn and .tres, with a func test_ count per tests subdir. Zero files scanned exits 1.
  • check rng scopes a declared draw's shadow to its own class body, so a func randf() in one class no longer hides a bare randf() in another, and a continuation line (an open bracket, a multi-line string, a trailing \) never closes a class body early.
  • integration.sh passes a cache repair's exit 2 through as 2, compares the import cache's age to the nanosecond across tracked and untracked-not-ignored sidecars, summarises a scenario still red after its rerun from that rerun, says why a warm worker handed back, and refuses a near-miss ## Isolated because: spelling (exit 2, naming the line).
  • make import-cache lists a rewritten existing .uid/.import sidecar on its own line instead of calling it churn, says what copied the tree and how much, sees a live Godot on a project root with a space in it, and puts -- before paths in every cp.
  • scenario.sh inside a sweep also declines the in-tree editor pass and names make import-cache; GDK_LOG_CAP_BYTES caps each --suite slice, and a verdict naming another slice is not counted for this one.
  • unit.sh prints the timeout factor it applied (timeout 360s (2x, load 4.04 on 4 cpu(s))) and records the bound in its transcript. The runners clear git's own --local-env-vars list instead of six hand-kept names.
  • The release index refuses another project's file, gives only the released tag's files a data-requires-python, and a re-dispatched tag with an identical wheel rebuilds the index instead of refusing; the release workflow sets permissions per job.

v2.0.0 — 2026-10-01

Upgrading (major). Re-install the runners (install-runners --force) and edit two things. Drop hooks-self-test from [gates] extra and from any recipe: the target is gone, with no alias. A builder's command is now make spot SYS=<slice>, not make precommit.

  • New spot tier, the builder's spot check (gdk#45). spot.sh runs gdlint and a compile of only the .gd files changed vs the merge base of HEAD and BASE (default main), untracked files included; make spot then runs unit.sh $(SYS) and exits with the worse code. No changed .gd is [SPOT] PASS — census 0: …, naming the base. compile_sweep.gd takes user arguments (-- res://a.gd …) and compiles exactly those. GDK_PRECOMMIT_TIERS is now spot, and make precommit prints one line that says it is retired.
  • Receipts for warnings, integration (smoke, --diff, --all, named) and a direct scenario run (gdk#44). The integration receipt is asked before the engine lease. GDK_RECEIPT_PATHS joins more paths to a key, so a ## covers: path in an excluded directory counts. A hit creates the file GDK_GATE_UNMEASURED names, and Makefile.tiers exports it for the gdk_gate-wrapped scenario targets, so a reused run files no cost row.
  • hooks-self-test is deleted (agentic-sdlc#122). The guard's corpus is replayed by this kit's tests; the hook's comment no longer tells you to wire it into check.
  • This repo runs agentic-sdlc 2.0.0: build wide, integrate once. Its [verify] is spot and milestone, [integrate] proves a batch with check + test, [tests] and the hooks and budget gates are gone, and the five retired hooks and eight unshipped agents are removed.

See also: Installing and pinning, Gate framework.

Clone this wiki locally