[Bug + Versioning Question] executa publish succeeds for an app_bundled Executa but does not create an ExecutaVersion

Hi team,

I found a consistently reproducible versioning issue with an existing app_bundled Executa.

anna-app executa publish reports success, generates a new content hash, and returns idempotent_hit: false, but no new ExecutaVersion is created. As a result, an app release can only freeze the previous Executa version.

Issue summary

The affected Executa is:

Field Value
CLI @anna-ai/cli 0.1.38
Host anna.partners
Executa tool-gamentic-engine-7h8aweky
executa_id 1025
Visibility app_bundled
is_published FALSE
Previous registered version 0.2.13
Previous latest_version_id 349

The associated app is gamentic-anna (app_id: 19). Its manifest references the Executa through:

{
  "required_executas": [
    {
      "tool_id": "tool-gamentic-engine-7h8aweky",
      "min_version": "0.2.15",
      "version": "0.2.15"
    }
  ]
}

However, the Executa registry remains on 0.2.13, even after publishing 0.2.14 and 0.2.15.

Reproduction

Preconditions

Start with an existing Executa that has:

visibility: app_bundled
is_published: false
latest registered version: 0.2.13
latest_version_id: 349

The 0.2.15 package has already been published to PyPI, and executa.json contains version 0.2.15.

Run the following commands from the Executa’s backend directory:

cd ~/anna-dev/gamentic-anna/backend

anna-app executa status engine --json
anna-app executa publish --json
anna-app executa status engine --json

Before publishing, the status reports:

{
  "version_count": 13,
  "latest_version": {
    "version": "0.2.13",
    "id": 349
  }
}

The publish command returns successfully:

{
  "executa_id": 1025,
  "version": "0.2.15",
  "content_hash": "11eea73a4555f8d71d07c6fdf2e98c3f492f99a86ff7aa63a60badec203ab8b4",
  "idempotent_hit": false,
  "first_publish": false,
  "visibility": "app_bundled",
  "latest_version_id": 349
}

The previous 0.2.13 content hash was:

0f53a1c7...

Therefore, this is a new publish payload rather than an idempotent retry.

After the publish command succeeds, running the status command again still reports:

{
  "version_count": 13,
  "latest_version": {
    "version": "0.2.13",
    "id": 349
  }
}

The same behavior previously occurred with version 0.2.14.

Actual result

The publish operation:

  • Returns successfully;
  • Returns the requested version, 0.2.15;
  • Produces a new content_hash;
  • Returns idempotent_hit: false;
  • Does not increment version_count;
  • Does not create a new ExecutaVersion;
  • Continues returning the old latest_version_id: 349.

There is no CLI error or warning indicating that version creation was skipped.

Expected result

If executa publish succeeds for an existing bundled Executa, I would expect it to create a new ExecutaVersion.

For this reproduction, the expected status would be equivalent to:

{
  "version_count": 14,
  "latest_version": {
    "version": "0.2.15",
    "id": "<new version id>"
  }
}

The publish response should also return the newly created version ID instead of 349.

If app_bundled Executas are not supposed to be versioned through this command while is_published is false, the command should return an actionable error rather than reporting a successful non-idempotent publish.

Initial diagnosis

The response suggests that the CLI and backend successfully process the new manifest or artifact:

  • The returned version changes to 0.2.15;
  • The content hash changes;
  • idempotent_hit is false.

The failure therefore appears to occur after content processing but before, or while, registering the corresponding ExecutaVersion.

My current hypothesis is that version creation may be gated by one of these state fields:

visibility = app_bundled
is_published = false

A possible backend path is:

accept new publish payload
→ calculate/store new content hash
→ skip ExecutaVersion creation because the Executa is not publicly published
→ return success with the previous latest_version_id

This would explain why the response contains the new version and hash while latest_version_id and version_count remain unchanged.

Another possibility is that bundled Executas require a separate registration or state-transition step that is not performed by anna-app executa publish.

I also checked the app publication path. The app references the Executa by tool_id through required_executas, but:

anna-app apps push --dry-run

only stages the app UI bundle. It does not register a new Executa version. Therefore, I could not identify another command in the current workflow that would create the missing ExecutaVersion.

Impact

This blocks app releases that depend on a newer bundled Executa version.

Although the app requests version 0.2.15, the platform can only resolve or freeze the last registered version, 0.2.13. The package and app manifest may therefore move forward while the platform’s Executa registry silently remains behind.

The successful publish response is also misleading for CI or release automation because it cannot be used as evidence that a new version was registered.

Requested confirmation or action

  1. Please confirm whether anna-app executa publish is expected to create an ExecutaVersion for an app_bundled Executa with is_published: false.
  2. If this is expected behavior, please check whether the backend is incorrectly skipping version creation while still returning a successful, non-idempotent publish response. An officially supported workaround would also be helpful.

If this state is intentional, could you also clarify the required command or state transition for registering a new bundled Executa version?

Thank you.

Hi @dora! :waving_hand:

Thank you for the wonderfully precise report — the before/after status --json captures and the content-hash comparison made this immediately actionable. :folded_hands:

TL;DR: Confirmed bug, fixed in 1.1.0-beta.99. executa publish for pip-distributed Executas now correctly creates a new ExecutaVersion on every version bump — and when it doesn’t create one, it tells you loudly instead of returning a fake success. :white_check_mark:

:magnifying_glass_tilted_left: What was actually happening

Good news for your setup: this had nothing to do with visibility: app_bundled or is_published: false — bundled Executas are absolutely supposed to be versioned through executa publish. The real culprit was in our server-side deduplication:

  • For pip-distributed Executas, the code lives on PyPI — outside our registry. Our “did the content change?” fingerprint didn’t include the declared version and had no code fingerprint for pip packages (unlike binaries, which have a SHA-256). So a code change + version bump produced a server-side snapshot identical to the previous version → the dedup logic said “nothing new here” and quietly returned the old 0.2.13 row. :grimacing:
  • A guard that should have raised “no content changes” was bypassed when an explicit version was supplied — which the CLI always does — turning what should have been an error into a silent 200.
  • And a small confusing detail you ran into: [version] and content_hash in the publish response were local echoes; only latest_version_id reflected server truth. That’s why the fields looked contradictory.

Your instinct that “the failure occurs after content processing but before version registration” was exactly right. :bullseye:

:hammer_and_wrench: Fixed in 1.1.0-beta.99

  1. Version-aware fingerprinting for package distributions :package: For pip/uv/npm-style distributions, the declared version is now part of the content fingerprint ([package@version] is the code identity). Bumping 0.2.13 → 0.2.15 now always creates a new ExecutaVersion.
  2. No more silent no-ops :speaker_high_volume: If a publish dedupes against an existing version but you requested a different version number, you now get an explicit 409 explaining the conflict — never a fake success.
  3. Honest idempotency signal :white_check_mark: Re-publishing the same version with identical content returns 200 with X-Anna-Idempotent: hit and a truthful idempotent_hit: true — safe and meaningful for CI/release automation.
  4. The publish flow also no longer rolls back your Executa’s synced version on a dedup hit.

:pushpin: Your questions

  1. Yesexecuta publish is expected to create an ExecutaVersion for app_bundled / unpublished Executas. No separate registration step needed; your workflow was correct all along.
  2. It was indeed incorrectly skipping creation while reporting success — fixed as above. No workaround needed anymore: just re-run anna-app executa publish on 1.1.0-beta.99+ and 0.2.15 will register properly (verify with anna-app executa status engine --jsonlatest_version should show 0.2.15 with a new id).

Thanks again for the sharp eyes and the clean reproduction — this fix makes publish trustworthy for everyone’s release automation. :blue_heart: Happy shipping! :rocket::sparkles: