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:
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).
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.
- 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):
DEFT_RELEASE_VERSION env var (existing) — for release-pipeline builds and explicit overrides.
- 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.
- NEW:
<script_dir>/.deft-version plaintext marker file — same idea, simpler format. Populated by _write_version_marker.
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.
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
Summary
The framework's
VERSION = _resolve_version()(runline 50–85, mirrored byscripts/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.gitdirectory inside.deft/core/, the resolver falls through to0.0.0-devbecause:DEFT_RELEASE_VERSIONenv var is not set in normal operation (it's only set byscripts/release.py::run_buildduring a release-pipeline build).git describe --tags --abbrev=0is run withcwd=script_dirwherescript_dir = Path(__file__).parent.absolute()→.deft/core/. With no.gitthere, 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."0.0.0-dev".This means every vendored install reports its version as
0.0.0-deveverywhere the framework's in-processVERSIONis shown:task deft:install:upgradeheader line ("Deft CLI v0.0.0-dev - Upgrade").deft-versionmarker file (just writes0.0.0-devintovbrief/.deft-version).deft/core/VERSIONYAML manifest (ref: 'v0.0.0-dev',tag: 'v0.0.0-dev')task deft:framework:check-updatesoutput (current: "0.0.0-dev")VERSIONconstantReproduction
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. Thetasks/install.ymldescription points consumers at the GitHub Releases binary. Yet:runscript'sVERSIONconstant.VERSIONat 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..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-deveverywhere 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):
DEFT_RELEASE_VERSIONenv var (existing) — for release-pipeline builds and explicit overrides.<script_dir>/VERSIONYAML manifest'stagorreffield — parse the file the framework itself writes via_write_install_manifest. This is the natural place because:task deft:install:upgraderuns.ref: 'v0.33.0'/tag: 'v0.33.0').<script_dir>/.deft-versionplaintext marker file — same idea, simpler format. Populated by_write_version_marker.git describe --tags --abbrev=0withcwd=script_dir(existing) — only works for framework-checkout (development) consumers, not vendored installs. Keep this for the framework-self-development case.0.0.0-dev(existing fallback).The release binary should ALSO populate
.deft/core/VERSIONand/or a.deft/core/.deft-versionfile 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 inscripts/resolve_version.py):And update
cmd_install/_write_install_manifest(the release-binary path) so they ALWAYS write<script_dir>/VERSIONwith the correcttagfield at deposit time, populated from the binary's stamped version (NOT from the consumer'sgit rev-parse HEAD, which is a related bug — filing separately).Environment
deftai/statusreport, branchdeftai-upgrade-20260518.deft/core/, copied fromgit clone --depth 1 --branch v0.33.0 https://github.com/deftai/directive.git(no.gitretained)$env:DEFT_RELEASE_VERSION='0.33.0'before every framework command invocationRelated