Skip to content

Version resolver returns 0.0.0-dev on vendored installs (.deft/core/ without .git): every framework surface reports wrong version #1323

@MScottAdams

Description

@MScottAdams

Summary

The framework's VERSION = _resolve_version() (run line 50–85, mirrored by scripts/resolve_version.py) cannot resolve a real version on vendored installs — i.e. the canonical layout the framework itself documents (AGENTS.md v3 template: "Deft is installed in .deft/core/"). On a vendored install with no .git directory inside .deft/core/, the resolver falls through to 0.0.0-dev because:

  1. DEFT_RELEASE_VERSION env var is not set in normal operation (it's only set by scripts/release.py::run_build during a release-pipeline build).
  2. git describe --tags --abbrev=0 is run with cwd=script_dir where script_dir = Path(__file__).parent.absolute().deft/core/. With no .git there, git walks UP and either fails (no parent repo) OR finds the consumer project's git repo (which has no framework version tags). Either way the result is empty/non-zero.
  3. Fallback returns "0.0.0-dev".

This means every vendored install reports its version as 0.0.0-dev everywhere the framework's in-process VERSION is shown:

  • task deft:install:upgrade header line ("Deft CLI v0.0.0-dev - Upgrade")
  • .deft-version marker file (just writes 0.0.0-dev into vbrief/.deft-version)
  • .deft/core/VERSION YAML manifest (ref: 'v0.0.0-dev', tag: 'v0.0.0-dev')
  • task deft:framework:check-updates output (current: "0.0.0-dev")
  • Any other surface that consumes the VERSION constant

Reproduction

# 1. Clone the framework at a real tag into a vendored install:
git clone --depth 1 --branch v0.33.0 https://github.com/deftai/directive.git /tmp/deft-v0.33.0
mkdir -p ./my-project/.deft/core/
cp -R /tmp/deft-v0.33.0/* ./my-project/.deft/core/   # NOTE: excludes .git
rm -rf /tmp/deft-v0.33.0

# 2. Set up the Taskfile include in ./my-project/Taskfile.yml referencing .deft/core/Taskfile.yml.

# 3. Try to use the framework:
cd ./my-project
task deft:install:upgrade
# Output: "Deft CLI v0.0.0-dev - Upgrade"
#         "✓ Recorded framework version 0.0.0-dev in .deft-version."
#         (.deft/core/VERSION shows ref: 'v0.0.0-dev')

# 4. The release-binary path that USED to populate the correct version is unusable for agents (see #1322).

Why this matters

The framework's own AGENTS.md template (v3) declares the canonical install location as .deft/core/. The release binary (deft-install) deposits there. The tasks/install.yml description points consumers at the GitHub Releases binary. Yet:

  • The release binary itself stamps the correct version via some mechanism (presumably Go ldflags), but only into its own Go-compiled binary — not into the Python run script's VERSION constant.
  • The deposited Python source still resolves VERSION at runtime via _resolve_version(), which doesn't know about the release-binary's stamped version because no on-disk file records it for Python to read.
  • After deposit, .deft/core/ has NO .git, NO baked-in version, and NO source for the resolver to use.

So a fresh install from the release binary will ALSO report 0.0.0-dev everywhere the Python surface is used, even though the binary "knows" the version. The version stamping is silently inconsistent between Go (binary) and Python (deposited script).

Expected behavior

The resolver should consult at least one persistent on-disk source that survives a vendored deposit. Suggested priority chain (extends the existing one):

  1. DEFT_RELEASE_VERSION env var (existing) — for release-pipeline builds and explicit overrides.
  2. NEW: <script_dir>/VERSION YAML manifest's tag or ref field — parse the file the framework itself writes via _write_install_manifest. This is the natural place because:
    • It's always present after task deft:install:upgrade runs.
    • It already encodes the version (ref: 'v0.33.0' / tag: 'v0.33.0').
    • The release binary should populate it during install.
  3. NEW: <script_dir>/.deft-version plaintext marker file — same idea, simpler format. Populated by _write_version_marker.
  4. git describe --tags --abbrev=0 with cwd=script_dir (existing) — only works for framework-checkout (development) consumers, not vendored installs. Keep this for the framework-self-development case.
  5. 0.0.0-dev (existing fallback).

The release binary should ALSO populate .deft/core/VERSION and/or a .deft/core/.deft-version file at install time so the deposited Python surface immediately resolves to the correct version without needing the env var.

Suggested fix shape

In run::_resolve_version() (and mirror in scripts/resolve_version.py):

def _resolve_version() -> str:
    # 1. env var (existing)
    env_value = os.environ.get("DEFT_RELEASE_VERSION", "").strip()
    if env_value:
        return env_value

    script_dir = Path(__file__).parent.absolute()

    # 2. NEW: read <script_dir>/VERSION YAML manifest 'ref' or 'tag' field
    manifest_path = script_dir / "VERSION"
    if manifest_path.is_file():
        try:
            text = manifest_path.read_text(encoding="utf-8")
            # Match e.g. `tag: 'v0.33.0'` or `ref: 'v0.33.0'`
            m = re.search(r"^(?:tag|ref):\s*['\"]?v?([\d.][\w.-]*)['\"]?\s*$", text, re.M)
            if m:
                return m.group(1)
        except OSError:
            pass

    # 3. NEW: read <script_dir>/.deft-version plaintext
    marker = script_dir / ".deft-version"
    if marker.is_file():
        try:
            value = marker.read_text(encoding="utf-8").strip().lstrip("v")
            if value:
                return value
        except OSError:
            pass

    # 4. git describe (existing) — only useful for framework-self-dev
    # ... existing code ...

    return "0.0.0-dev"

And update cmd_install / _write_install_manifest (the release-binary path) so they ALWAYS write <script_dir>/VERSION with the correct tag field at deposit time, populated from the binary's stamped version (NOT from the consumer's git rev-parse HEAD, which is a related bug — filing separately).

Environment

  • Consumer: deftai/statusreport, branch deftai-upgrade-20260518
  • Install: vendored at .deft/core/, copied from git clone --depth 1 --branch v0.33.0 https://github.com/deftai/directive.git (no .git retained)
  • OS: Windows 11, pwsh 7.6.1
  • Workaround currently used: $env:DEFT_RELEASE_VERSION='0.33.0' before every framework command invocation

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions