Project Housekeeping

This page explains how to maintain and evolve a project deployment over time using:

It focuses on operational choices. It does not repeat conceptual definitions from Concepts or full option syntax from Commands reference.

Important

These commands deploy and remove contexts. They never check or resolve the requirements that contexts declare (Python packages, tool bundles such as the STM32CubeMX2 application, VS Code extensions). Only setup and doctor do. After adding, updating or replaying a context, run cube agentic-ai doctor <project_top_folder> --fix. An update is a remove, then an add with the same services (--services all for a project created with setup), then that doctor --fix.

Note

Naming convention used below: bundleName identifies a context bundle, and serviceId identifies a service inside that bundle.


Why there is no project-update command

There is no single project-update command by design.

Project evolution is not one workflow. Teams may want to:

  • Add a new context without touching existing ones.

  • Intentionally keep a mixed-version service state for compatibility reasons.

  • Reconcile to a single pinned version from a preset.

  • Replay an exact historical mixed-version state.

  • Restrict unpinned updates to lock-known versions.

Instead of forcing one policy, the installer provides explicit primitives so users can choose between freedom and control at each step.


The housekeeping levers

Think in five independent decisions.

Decision

Flexible choice

Controlled choice

What to add or refresh

project-add for one context, project-deploy for many

project-deploy-installed to limit candidates to installed pinned versions

How to change an existing deployment

Additive updates with project-add or project-deploy (narrower follow-up scope does not remove prior deployment state, so leftovers can remain)

Clean replacement by removing first with project-remove, then re-adding or re-deploying; unchanged installer-managed artifacts can also be replayed safely

Removal granularity

Remove a selected service subset (service IDs) with project-remove and --services <serviceId,...> (more flexible, but can preserve mixed-version leftovers before a later add)

Remove the entire context (bundleName) with project-remove before re-adding (more controlled, avoids carry-over and mixing risk)

How bundle version is selected for bundleName

Unpinned bundleName with flexible policy (highest installed eligible version)

Pinned bundleName@version, or unpinned bundleName with lock-driven policy (reuse project-locked version)

How preset replay behaves

project-deploy with --preset (reconcile default)

project-deploy with --preset --preset-no-reconcile (exact per-service replay)

Note

For version selection, pinned references (bundleName@version) are always explicit and authoritative. Policy choices apply to unpinned references (bundleName).


Practical scenarios

1) Catalog is behind, but a newer bundle is installed intentionally

You can still deploy newer installed versions.

For this example, assume a catalog entry specifies 1.3.0 for bundleName=cube-agentic-ai-<connector>, and both 1.3.0 and 1.4.0 are installed. The current release’s catalog uses open-ended minimum ranges instead of exact pins.

  • Install or update the context bundle on the machine.

  • Deploy with explicit pinning (name@version) for deterministic intent.

  • Or deploy unpinned (name) when you intentionally accept local inventory influence.

This is useful when the installer catalog has not yet been refreshed but your team validated a newer context bundle.

Example:

# The catalog entry specifies 1.3.0, but you validated 1.4.0 and deploy it explicitly
cube agentic-ai project-add cube-agentic-ai-<connector>@1.4.0 <project_top_folder>

# Unpinned deploy reuses the highest installed semantic version (1.4.0 here)
cube agentic-ai project-add cube-agentic-ai-<connector> <project_top_folder>

Possible command-result excerpt for the unpinned call:

{
	"data": {
		"bundleRef": "cube-agentic-ai-<connector>@1.4.0"
	}
}

2) Intentionally mix services from different bundle versions

Mixed-version service state is allowed.

  • Add or deploy context services over time with different bundle versions.

  • Do not remove services unless you want to shrink or reset the state.

This supports gradual migrations where not all services move at once.

Example:

# First run unpinned, so current highest selected is 1.3.0
cube agentic-ai project-add cube-agentic-ai-<connector> <project_top_folder> --services serviceId-S1,serviceId-S2

# Later, add one service from explicitly pinned newer 1.4.0
cube agentic-ai project-add cube-agentic-ai-<connector>@1.4.0 <project_top_folder> --services serviceId-S3

Possible lock excerpt:

{
	"bundleName": "cube-agentic-ai-<connector>",
	"selectedServiceProvenance": ["serviceId-S1@1.3.0|required", "serviceId-S2@1.3.0|optional", "serviceId-S3@1.4.0|optional"]
}

3) Reconcile a preset to a single effective bundle version per context

Default preset deployment (project-deploy with --preset) is reconcile mode.

  • Use this when you want a clean, deterministic target state from preset inputs.

  • In preset mode, preset bundle references are pinned and authoritative.

Example:

cube agentic-ai project-deploy <project_top_folder> --preset preset.json

Preset excerpt:

{
	"bundles": [
		{
			"name": "cube-agentic-ai-<connector>",
			"version": "1.3.0",
			"serviceProvenance": ["serviceId-S1@1.3.0|required", "serviceId-S2@1.4.0|optional"],
			"kind": "connector"
		}
	]
}

In preset JSON, field name is the context bundle name, and each serviceProvenance entry is <serviceId>@<bundleVersion>|<required|optional>. Untagged legacy entries are treated as optional.

Possible reconciled result excerpt:

{
	"bundleName": "cube-agentic-ai-<connector>",
	"bundleVersion": "1.3.0",
	"selectedServiceProvenance": ["serviceId-S1@1.3.0|required", "serviceId-S2@1.3.0|optional"]
}

In reconcile mode, services selected from the preset are deployed against the preset bundle version (1.3.0 here).

4) Keep preset diversity exactly as recorded

Use project-deploy with --preset --preset-no-reconcile.

  • The deploy expands execution by (bundle, version) groups.

  • Services keep their recorded provenance versioning instead of being reconciled.

Use this when historical fidelity matters more than homogenization.

Operational equivalence:

  • project-deploy --preset --preset-no-reconcile is equivalent to running one pinned project-add per (bundle, version) group from serviceProvenance.

Example:

cube agentic-ai project-deploy <project_top_folder> --preset preset.json --preset-no-reconcile

Equivalent grouped execution excerpt:

project-add cube-agentic-ai-<connector>@1.3.0 --services serviceId-S1
project-add cube-agentic-ai-<connector>@1.4.0 --services serviceId-S2

5) Keep unpinned updates under lock control

Use lock-driven policy for unpinned references.

  • With unpinned names, lock-driven reuses the bundle version already locked in the project when available (for example 1.3.0 from the earlier unpinned add).

  • With explicit name@version, the explicit pin remains authoritative.

This is a good middle ground between strict pinning and full flexibility.

Example:

cube agentic-ai project-add cube-agentic-ai-<connector> <project_top_folder> --bundle-version-policy lock-driven
cube agentic-ai project-deploy <project_top_folder> --mode all --bundle-version-policy lock-driven

Possible nominal result excerpt:

{
	"ok": true,
	"data": {
		"bundleRef": "cube-agentic-ai-<connector>@1.3.0"
	}
}

Note

If the required locked version is not installed locally, the command fails with BUNDLE_LOCKED_VERSION_NOT_INSTALLED. In this example, the missing locked version would be cube-agentic-ai-<connector>@1.3.0.


Connector upgrades and tool dependencies

Connector bundles and their Cube tool dependencies have separate scopes. machine-bootstrap upgrades catalog connectors on the machine. It does not refresh tool versions already selected by an existing project lock. In this section, workspace means the project top folder targeted by the command (<project_top_folder>). Both terms refer to the same project-level lock and deployment scope. A fresh workspace resolves the newest installed tool version that satisfies the connector’s dependency range, while an existing workspace keeps its locked version for reproducibility.

project-add, project-deploy, and project-deploy-installed report each tool dependency’s project-lock status (ADDED, UPDATED, UNCHANGED, or REMOVED) and machine status (INSTALLED or REUSED). If a newer installed version satisfies the dependency range but is not selected because of the project lock, the command adds TOOL_DEPENDENCY_PINNED_BY_PROJECT_LOCK to data.warnings and the human-readable refresh hint to data.warningMessages. To refresh tool dependencies intentionally, run cube bundle update --project from the project top folder. Review and retain the resulting lock changes.