From 08e2209afad032af67ee2280198c680a27b5e445 Mon Sep 17 00:00:00 2001
From: 4pmtong
Date: Tue, 11 Aug 2026 18:00:11 +0800
Subject: [PATCH] refactor: standardize Workspace Bundle terminology
---
backend/app/agent/toolkit/terminal_toolkit.py | 14 +++----
.../controller/workspace_config_controller.py | 16 ++++----
backend/app/router.py | 2 +-
backend/app/workspace_bundle/agent_plugins.py | 10 ++---
backend/app/workspace_bundle/authoring.py | 6 +--
backend/app/workspace_bundle/cloud.py | 2 +-
backend/app/workspace_bundle/installer.py | 14 +++----
backend/app/workspace_bundle/runtime.py | 10 ++---
backend/app/workspace_bundle/secrets.py | 19 +++++-----
backend/app/workspace_config/__init__.py | 12 +++---
backend/app/workspace_config/admission.py | 10 ++---
.../app/workspace_config/legacy_migration.py | 6 +--
backend/app/workspace_config/manifest.py | 18 ++++-----
backend/app/workspace_config/models.py | 10 ++---
backend/app/workspace_config/resolver.py | 4 +-
backend/app/workspace_git/configuration.py | 8 ++--
backend/main.py | 2 +-
.../app/agent/factory/test_toolkit_safety.py | 6 +--
.../agent/toolkit/test_terminal_toolkit.py | 8 ++--
.../app/permission_policy/test_service.py | 6 +--
backend/tests/app/run_journal/test_store.py | 22 +++++------
.../app/workspace_bundle/test_authoring.py | 18 ++++-----
.../app/workspace_bundle/test_installer.py | 18 ++++-----
.../app/workspace_bundle/test_secrets.py | 4 +-
.../test_workspace_bundle_runtime.py | 6 +--
.../app/workspace_config/test_admission.py | 6 +--
.../tests/app/workspace_config/test_models.py | 28 +++++++-------
.../test_configuration_repository.py | 38 +++++++++----------
electron/main/workspaceSecrets/vault.ts | 2 +-
.../AgentPluginImportWizard.tsx | 4 +-
.../WorkspaceBundleInstallWizard.test.tsx | 10 ++---
.../WorkspaceBundleInstallWizard.tsx | 16 ++++----
.../EnvironmentRequirementsEditor.tsx | 2 +-
.../WorkspaceBundleSaveDialog.test.tsx | 6 +--
.../WorkspaceBundleSaveDialog.tsx | 10 ++---
src/pages/Home/components/HomeHubToolbar.tsx | 2 +-
src/service/workspaceBundleInstallApi.test.ts | 38 +++++++++----------
src/service/workspaceBundleInstallApi.ts | 4 +-
src/service/workspaceConfigurationApi.test.ts | 2 +-
src/service/workspaceConfigurationApi.ts | 2 +-
.../electron/main/workspaceSecrets.test.ts | 2 +-
.../hooks/useWorkspaceConfiguration.test.tsx | 2 +-
42 files changed, 213 insertions(+), 212 deletions(-)
diff --git a/backend/app/agent/toolkit/terminal_toolkit.py b/backend/app/agent/toolkit/terminal_toolkit.py
index 465601bc..14485880 100644
--- a/backend/app/agent/toolkit/terminal_toolkit.py
+++ b/backend/app/agent/toolkit/terminal_toolkit.py
@@ -16,6 +16,7 @@ import asyncio
import logging
import os
import platform
+import re
import shlex
import shutil
import signal
@@ -55,12 +56,9 @@ logger = logging.getLogger("terminal_toolkit")
APP_VERSION = "1.0.2"
-_SECRET_BROKER_ENVIRONMENT_KEYS = {
- "EIGENT_WORKSPACE_SECRET_BROKER_ENDPOINT",
- "EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY",
- "EIGENT_WORKFORCE_SECRET_BROKER_ENDPOINT",
- "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY",
-}
+_SECRET_BROKER_ENVIRONMENT_KEY = re.compile(
+ r"^EIGENT_[A-Z0-9_]+_SECRET_BROKER_(?:ENDPOINT|CAPABILITY)$"
+)
_BUNDLE_RUNTIME_BASE_ENVIRONMENT_KEYS = {
"APPDATA",
@@ -92,7 +90,9 @@ _BUNDLE_RUNTIME_BASE_ENVIRONMENT_KEYS = {
def is_secret_broker_environment_key(name: str) -> bool:
- return name.strip().upper() in _SECRET_BROKER_ENVIRONMENT_KEYS
+ return bool(
+ _SECRET_BROKER_ENVIRONMENT_KEY.fullmatch(name.strip().upper())
+ )
def is_control_plane_environment_key(name: str) -> bool:
diff --git a/backend/app/controller/workspace_config_controller.py b/backend/app/controller/workspace_config_controller.py
index bc656c1f..bd6cc194 100644
--- a/backend/app/controller/workspace_config_controller.py
+++ b/backend/app/controller/workspace_config_controller.py
@@ -42,7 +42,7 @@ from app.workspace_bundle import (
WorkspaceBundleCloudError,
)
from app.workspace_config import (
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceConfigError,
assert_bundle_asset_safe,
canonical_digest,
@@ -130,7 +130,7 @@ def _default_document(space_id: str, name: str | None) -> dict[str, Any]:
display_name = (name or "Workspace").strip() or "Workspace"
return {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": _default_bundle_id(space_id),
"name": display_name,
@@ -176,7 +176,7 @@ def _base_document(space_id: str, name: str | None) -> tuple[dict, str | None]:
)
if revision is None:
return _default_document(space_id, name), None
- document = WorkforceBundleManifest.model_validate(
+ document = WorkspaceBundleManifest.model_validate(
revision.manifest
).canonical_payload()
metadata = document.setdefault("metadata", {})
@@ -197,7 +197,7 @@ def _payload(
"version": 0,
"base_revision_id": base_revision_id,
"document": document,
- "document_digest": WorkforceBundleManifest.model_validate(
+ "document_digest": WorkspaceBundleManifest.model_validate(
document
).digest,
"persisted": False,
@@ -329,7 +329,7 @@ def _prepared_asset_payload(asset: Any) -> dict[str, Any]:
def _workspace_configuration_review(
draft: WorkspaceConfigDraftRecord,
) -> dict[str, Any]:
- manifest = WorkforceBundleManifest.model_validate(draft.document)
+ manifest = WorkspaceBundleManifest.model_validate(draft.document)
base = WorkspaceBundleAuthoringService.review(
manifest,
mcp_config=read_mcp_config(),
@@ -396,7 +396,7 @@ def _assert_cloud_prepared_assets_match(
manifest_digest: str,
cloud_revision: dict[str, Any],
) -> None:
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
cloud_revision.get("manifest", {})
)
base = WorkspaceBundleAuthoringService.review(
@@ -600,7 +600,7 @@ async def put_workspace_configuration(
)
journal = get_default_run_journal()
try:
- manifest = WorkforceBundleManifest.model_validate(body.document)
+ manifest = WorkspaceBundleManifest.model_validate(body.document)
canonical = manifest.canonical_payload()
existing = journal.get_workspace_config_draft(space_id)
if existing is not None:
@@ -766,7 +766,7 @@ async def upload_prepared_workspace_configuration_asset(
draft=draft,
descriptor=descriptor,
)
- manifest = WorkforceBundleManifest.model_validate(draft.document)
+ manifest = WorkspaceBundleManifest.model_validate(draft.document)
bundle_id = manifest.metadata.id
revision_id = f"{bundle_id}@{manifest.metadata.revision}"
cloud = _authoring_cloud(authorization)
diff --git a/backend/app/router.py b/backend/app/router.py
index aa759ea5..bfeda6e0 100644
--- a/backend/app/router.py
+++ b/backend/app/router.py
@@ -134,7 +134,7 @@ def register_routers(app: FastAPI, prefix: str = "") -> None:
},
{
"router": workspace_bundle_controller.router,
- "tags": ["Workforce Bundles"],
+ "tags": ["Workspace Bundles"],
"description": "Review-first local Bundle installation",
"self_authenticated": True,
},
diff --git a/backend/app/workspace_bundle/agent_plugins.py b/backend/app/workspace_bundle/agent_plugins.py
index 82a33874..dd9bca78 100644
--- a/backend/app/workspace_bundle/agent_plugins.py
+++ b/backend/app/workspace_bundle/agent_plugins.py
@@ -1,4 +1,4 @@
-"""Agent Plugins v1.0.0 importer for reviewable Workforce Bundle drafts."""
+"""Agent Plugins v1.0.0 importer for reviewable Workspace Bundle drafts."""
from __future__ import annotations
@@ -27,7 +27,7 @@ from app.run_journal.store import SQLiteRunJournal
from app.workspace_bundle.authoring import WorkspaceBundleAuthoringService
from app.workspace_config import (
SecretValueInManifestError,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
assert_bundle_asset_safe,
assert_manifest_secret_free,
canonical_digest,
@@ -161,7 +161,7 @@ class AgentPluginAsset:
@dataclass(frozen=True)
class AgentPluginImportResult:
- manifest: WorkforceBundleManifest
+ manifest: WorkspaceBundleManifest
assets: tuple[AgentPluginAsset, ...]
source_metadata: dict[str, Any]
warnings: tuple[AgentPluginImportWarning, ...]
@@ -291,10 +291,10 @@ class AgentPluginImporter:
excluded=excluded,
semantic_executable_paths=semantic_executable_paths,
)
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": bundle_id or self._bundle_id(plugin_name),
"name": plugin_name,
diff --git a/backend/app/workspace_bundle/authoring.py b/backend/app/workspace_bundle/authoring.py
index 976144a4..37d85058 100644
--- a/backend/app/workspace_bundle/authoring.py
+++ b/backend/app/workspace_bundle/authoring.py
@@ -1,11 +1,11 @@
-"""Secret-free review projection for authoring a Workforce Bundle."""
+"""Secret-free review projection for authoring a Workspace Bundle."""
from __future__ import annotations
import re
from typing import Any
-from app.workspace_config import WorkforceBundleManifest, canonical_digest
+from app.workspace_config import WorkspaceBundleManifest, canonical_digest
from app.workspace_config.admission import LegacyEnvironmentImporter
_SENSITIVE_ENV_NAME = re.compile(
@@ -21,7 +21,7 @@ class WorkspaceBundleAuthoringService:
@classmethod
def review(
cls,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
*,
mcp_config: dict[str, Any] | None = None,
) -> dict[str, Any]:
diff --git a/backend/app/workspace_bundle/cloud.py b/backend/app/workspace_bundle/cloud.py
index 4c78300a..7541db0f 100644
--- a/backend/app/workspace_bundle/cloud.py
+++ b/backend/app/workspace_bundle/cloud.py
@@ -1,4 +1,4 @@
-"""Device-authenticated Cloud transport for Workforce Bundle installation."""
+"""Device-authenticated Cloud transport for Workspace Bundle installation."""
from __future__ import annotations
diff --git a/backend/app/workspace_bundle/installer.py b/backend/app/workspace_bundle/installer.py
index 5d5ef8fc..c25bd39d 100644
--- a/backend/app/workspace_bundle/installer.py
+++ b/backend/app/workspace_bundle/installer.py
@@ -1,4 +1,4 @@
-"""Review-first local Workforce Bundle installation and materialization."""
+"""Review-first local Workspace Bundle installation and materialization."""
from __future__ import annotations
@@ -31,7 +31,7 @@ from app.workspace_bundle.secrets import (
from app.workspace_config import (
ConfigPlacement,
SecretValueInManifestError,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
assert_bundle_asset_safe,
canonical_digest,
)
@@ -96,7 +96,7 @@ class WorkspaceBundleInstaller:
manifest_value = revision.get("manifest")
if not isinstance(manifest_value, dict):
raise WorkspaceBundleInstallError("Bundle manifest is missing")
- manifest = WorkforceBundleManifest.model_validate(manifest_value)
+ manifest = WorkspaceBundleManifest.model_validate(manifest_value)
if (
manifest.metadata.id != bundle_id
or manifest.revision_id != revision_id
@@ -458,7 +458,7 @@ class WorkspaceBundleInstaller:
)
cloud_version = int(cloud_installation["version"])
assets, executable_assets = await self._download_assets(proposal)
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
proposal.manifest
)
lock_payload = {
@@ -579,7 +579,7 @@ class WorkspaceBundleInstaller:
)
if installed_bundle_id != proposal.bundle_id:
raise WorkspaceBundleInstallError(
- "Space already uses a different Workforce Bundle"
+ "Space already uses a different Workspace Bundle"
)
if installed_revision_id == proposal.revision_id:
local_materialization = (
@@ -725,7 +725,7 @@ class WorkspaceBundleInstaller:
@staticmethod
def _install_plan(
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
assets: list[dict[str, Any]],
*,
mcp_destinations: list[dict[str, Any]] | None = None,
@@ -796,7 +796,7 @@ class WorkspaceBundleInstaller:
async def _inspect_mcp_destinations(
self,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
assets: list[dict[str, Any]],
) -> list[dict[str, Any]]:
assert self.cloud is not None
diff --git a/backend/app/workspace_bundle/runtime.py b/backend/app/workspace_bundle/runtime.py
index 38792438..b94d4d07 100644
--- a/backend/app/workspace_bundle/runtime.py
+++ b/backend/app/workspace_bundle/runtime.py
@@ -33,7 +33,7 @@ from app.workspace_bundle.mcp_destination import (
)
from app.workspace_config.models import (
EffectiveEnvironmentSpec,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceLock,
canonical_digest,
)
@@ -361,7 +361,7 @@ class RuntimeEnvironmentAssembler:
if revision is None:
raise EnvironmentSetupRequiredError(["bundle_revision_missing"])
try:
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
spec.semantic_spec.get("bundle")
)
except Exception as exc:
@@ -724,13 +724,13 @@ class RuntimeEnvironmentAssembler:
def _load_configuration_contract(
self,
root: Path,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
) -> WorkspaceLock:
try:
manifest_value = yaml.safe_load(
self._read_limited(root / "workspace.yaml").decode("utf-8")
)
- materialized_manifest = WorkforceBundleManifest.model_validate(
+ materialized_manifest = WorkspaceBundleManifest.model_validate(
manifest_value
)
lock_value = yaml.safe_load(
@@ -807,7 +807,7 @@ class RuntimeEnvironmentAssembler:
def _validate_declared_bindings(
self,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
proposal: WorkspaceBundleInstallProposalRecord,
local_by_slot: dict[str, WorkspaceBundleLocalBindingRecord],
secret_bindings: tuple[WorkspaceBundleSecretBindingRecord, ...],
diff --git a/backend/app/workspace_bundle/secrets.py b/backend/app/workspace_bundle/secrets.py
index 55c8a4d0..d10a72a9 100644
--- a/backend/app/workspace_bundle/secrets.py
+++ b/backend/app/workspace_bundle/secrets.py
@@ -21,15 +21,16 @@ def _capture_broker_environment(
capability = environment.pop(
"EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY", ""
)
- legacy_endpoint = environment.pop(
- "EIGENT_WORKFORCE_SECRET_BROKER_ENDPOINT", ""
- )
- legacy_capability = environment.pop(
- "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY", ""
- )
- if endpoint or capability:
- return endpoint, capability
- return legacy_endpoint, legacy_capability
+ # Strip any obsolete or vendor-specific broker authority as well. Only the
+ # Workspace keys above are accepted as the active authority, but no broker
+ # credential may leak into an agent child process.
+ for key in tuple(environment):
+ if re.fullmatch(
+ r"EIGENT_[A-Z0-9_]+_SECRET_BROKER_(?:ENDPOINT|CAPABILITY)",
+ key.strip().upper(),
+ ):
+ environment.pop(key, None)
+ return endpoint, capability
_BROKER_ENDPOINT, _BROKER_CAPABILITY = _capture_broker_environment(os.environ)
diff --git a/backend/app/workspace_config/__init__.py b/backend/app/workspace_config/__init__.py
index 065a5dd3..a96dbc4c 100644
--- a/backend/app/workspace_config/__init__.py
+++ b/backend/app/workspace_config/__init__.py
@@ -14,8 +14,8 @@
from app.workspace_config.capabilities import ModelCapabilityRegistry
from app.workspace_config.manifest import (
- load_workforce_manifest,
- parse_workforce_manifest,
+ load_workspace_manifest,
+ parse_workspace_manifest,
)
from app.workspace_config.models import (
ConfigPlacement,
@@ -31,7 +31,7 @@ from app.workspace_config.models import (
ThinkingEffort,
UnsafeCloudProjectionError,
UnsupportedThinkingEffortError,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceBundleReconfigurationPendingError,
WorkspaceConfigError,
WorkspaceLock,
@@ -60,7 +60,7 @@ __all__ = [
"ThinkingEffort",
"UnsafeCloudProjectionError",
"UnsupportedThinkingEffortError",
- "WorkforceBundleManifest",
+ "WorkspaceBundleManifest",
"WorkspaceBundleReconfigurationPendingError",
"WorkspaceLock",
"WorkspaceConfigError",
@@ -69,7 +69,7 @@ __all__ = [
"assert_manifest_secret_free",
"canonical_digest",
"canonical_json",
- "load_workforce_manifest",
+ "load_workspace_manifest",
"normalize_thinking_effort",
- "parse_workforce_manifest",
+ "parse_workspace_manifest",
]
diff --git a/backend/app/workspace_config/admission.py b/backend/app/workspace_config/admission.py
index 4cbd746f..af75e1f2 100644
--- a/backend/app/workspace_config/admission.py
+++ b/backend/app/workspace_config/admission.py
@@ -36,7 +36,7 @@ from app.workspace_config.models import (
ResolvedConnectorBinding,
ResolvedContextSource,
ThinkingEffort,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceBundleReconfigurationPendingError,
canonical_digest,
normalize_thinking_effort,
@@ -58,7 +58,7 @@ _SECRET_ARG = re.compile(
@dataclass(frozen=True)
class EnvironmentAdmissionTemplate:
- manifest: WorkforceBundleManifest
+ manifest: WorkspaceBundleManifest
provider_capability: ProviderModelCapability
runtime_capability_manifest: dict[str, Any]
# None means the user did not override the installed Bundle layer.
@@ -177,10 +177,10 @@ class LegacyEnvironmentImporter:
"legacy_source_checksum": source_checksum,
}
)
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": f"bundle_legacy_{identity[:24]}",
"name": "Personal Default Bundle",
@@ -313,7 +313,7 @@ class EnvironmentAdmissionService:
raise ValueError(
"Materialized Workspace Bundle revision is missing"
)
- installed_manifest = WorkforceBundleManifest.model_validate(
+ installed_manifest = WorkspaceBundleManifest.model_validate(
revision.manifest
)
proposal = self.journal.get_active_workspace_bundle_proposal(
diff --git a/backend/app/workspace_config/legacy_migration.py b/backend/app/workspace_config/legacy_migration.py
index 7fa61810..4c0b75d4 100644
--- a/backend/app/workspace_config/legacy_migration.py
+++ b/backend/app/workspace_config/legacy_migration.py
@@ -61,7 +61,7 @@ class LegacyWorkspaceBundleMigration:
self.output_path = (
self.root
/ "migrations"
- / "personal-default-workforce-bundle-v1.json"
+ / "personal-default-workspace-bundle-v1.json"
)
def run(self) -> LegacyMigrationResult:
@@ -106,7 +106,7 @@ class LegacyWorkspaceBundleMigration:
bindings = self._secret_bindings(servers)
safe_payload = {
"migration_version": _MIGRATION_VERSION,
- "kind": "PersonalDefaultWorkforceBundleMigration",
+ "kind": "PersonalDefaultWorkspaceBundleMigration",
"bundle_manifest": template.manifest.canonical_payload(),
"runtime_capability_manifest": (
template.runtime_capability_manifest
@@ -136,7 +136,7 @@ class LegacyWorkspaceBundleMigration:
Exception
) as exc: # startup migration is intentionally fail-open
logger.warning(
- "Legacy Workforce Bundle migration degraded: %s", exc
+ "Legacy Workspace Bundle migration degraded: %s", exc
)
return LegacyMigrationResult(
status="degraded",
diff --git a/backend/app/workspace_config/manifest.py b/backend/app/workspace_config/manifest.py
index dffd82e6..2619afd9 100644
--- a/backend/app/workspace_config/manifest.py
+++ b/backend/app/workspace_config/manifest.py
@@ -12,7 +12,7 @@
# limitations under the License.
# ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
-"""Safe parser for shareable Workforce Bundle manifests."""
+"""Safe parser for shareable Workspace Bundle manifests."""
from __future__ import annotations
@@ -22,30 +22,30 @@ from typing import Any
import yaml
from app.workspace_config.models import (
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceConfigError,
assert_manifest_secret_free,
)
-def parse_workforce_manifest(value: str | bytes) -> WorkforceBundleManifest:
+def parse_workspace_manifest(value: str | bytes) -> WorkspaceBundleManifest:
try:
payload: Any = yaml.safe_load(value)
except yaml.YAMLError as exc:
- raise WorkspaceConfigError("invalid Workforce Bundle YAML") from exc
+ raise WorkspaceConfigError("invalid Workspace Bundle YAML") from exc
if not isinstance(payload, dict):
raise WorkspaceConfigError(
- "Workforce Bundle manifest must be a YAML mapping"
+ "Workspace Bundle manifest must be a YAML mapping"
)
# Run this before Pydantic so callers receive the typed privacy-boundary
# error instead of a generic wrapped ValidationError.
assert_manifest_secret_free(payload)
- return WorkforceBundleManifest.model_validate(payload)
+ return WorkspaceBundleManifest.model_validate(payload)
-def load_workforce_manifest(path: Path) -> WorkforceBundleManifest:
+def load_workspace_manifest(path: Path) -> WorkspaceBundleManifest:
if path.name != "workspace.yaml":
raise WorkspaceConfigError(
- "Workforce Bundle manifest must be named workspace.yaml"
+ "Workspace Bundle manifest must be named workspace.yaml"
)
- return parse_workforce_manifest(path.read_text(encoding="utf-8"))
+ return parse_workspace_manifest(path.read_text(encoding="utf-8"))
diff --git a/backend/app/workspace_config/models.py b/backend/app/workspace_config/models.py
index fa8197e0..9220ca9e 100644
--- a/backend/app/workspace_config/models.py
+++ b/backend/app/workspace_config/models.py
@@ -12,7 +12,7 @@
# limitations under the License.
# ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
-"""Immutable Workforce Bundle and environment materialization contracts."""
+"""Immutable Workspace Bundle and environment materialization contracts."""
from __future__ import annotations
@@ -650,14 +650,14 @@ class BundleSpec(_StrictFrozenModel):
return self
-class WorkforceBundleManifest(_StrictFrozenModel):
+class WorkspaceBundleManifest(_StrictFrozenModel):
api_version: Literal["eigent.ai/v1alpha1"] = Field(alias="apiVersion")
- kind: Literal["WorkforceBundle"]
+ kind: Literal["WorkspaceBundle"]
metadata: BundleMetadata
spec: BundleSpec
@model_validator(mode="after")
- def reject_secret_values(self) -> WorkforceBundleManifest:
+ def reject_secret_values(self) -> WorkspaceBundleManifest:
assert_manifest_secret_free(self.canonical_payload())
return self
@@ -896,7 +896,7 @@ class EffectiveEnvironmentSpec(_StrictFrozenModel):
*,
owner_type: Literal["run", "run_attempt"],
owner_id: str,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
semantic_spec: dict[str, Any],
local_materialization: LocalMaterialization,
permission_profile_revision: str,
diff --git a/backend/app/workspace_config/resolver.py b/backend/app/workspace_config/resolver.py
index 7e5d1b07..ae37bc09 100644
--- a/backend/app/workspace_config/resolver.py
+++ b/backend/app/workspace_config/resolver.py
@@ -23,7 +23,7 @@ from app.workspace_config.models import (
LocalMaterialization,
ProviderModelCapability,
ThinkingEffort,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
canonical_digest,
)
@@ -34,7 +34,7 @@ class EnvironmentConfigResolver:
def resolve(
self,
*,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
owner_type: Literal["run", "run_attempt"],
owner_id: str,
local_materialization: LocalMaterialization,
diff --git a/backend/app/workspace_git/configuration.py b/backend/app/workspace_git/configuration.py
index a8870f94..31469138 100644
--- a/backend/app/workspace_git/configuration.py
+++ b/backend/app/workspace_git/configuration.py
@@ -37,7 +37,7 @@ from app.run_journal import (
)
from app.workspace_config import (
ConfigPlacement,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceLock,
assert_manifest_secret_free,
canonical_digest,
@@ -92,7 +92,7 @@ class ConfigurationRepositoryService:
*,
space_id: str,
space_root: Path,
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
placement: ConfigPlacement,
created_by: str,
lock_payload: dict[str, Any] | None = None,
@@ -263,7 +263,7 @@ class ConfigurationRepositoryService:
current_lock_payload = yaml.safe_load(
workspace_lock_path.read_text(encoding="utf-8")
)
- current_manifest = WorkforceBundleManifest.model_validate(
+ current_manifest = WorkspaceBundleManifest.model_validate(
current_manifest_payload
)
current_lock = WorkspaceLock.model_validate(
@@ -397,7 +397,7 @@ class ConfigurationRepositoryService:
@staticmethod
def _default_lock(
- manifest: WorkforceBundleManifest,
+ manifest: WorkspaceBundleManifest,
) -> dict[str, Any]:
return {
"apiVersion": "eigent.ai/lock/v1alpha1",
diff --git a/backend/main.py b/backend/main.py
index 88eab88a..23d181d9 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -183,7 +183,7 @@ async def startup_event():
)
if legacy_bundle_migration.status == "degraded":
app_logger.warning(
- "Legacy Workforce Bundle migration degraded without blocking "
+ "Legacy Workspace Bundle migration degraded without blocking "
"startup: %s",
legacy_bundle_migration.error,
)
diff --git a/backend/tests/app/agent/factory/test_toolkit_safety.py b/backend/tests/app/agent/factory/test_toolkit_safety.py
index 404c06a1..81e8be11 100644
--- a/backend/tests/app/agent/factory/test_toolkit_safety.py
+++ b/backend/tests/app/agent/factory/test_toolkit_safety.py
@@ -80,8 +80,8 @@ def test_mcp_process_environment_excludes_secret_broker_authority():
"EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY": (
"broker-secret"
),
- "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY": (
- "legacy-secret"
+ "EIGENT_OBSOLETE_SECRET_BROKER_CAPABILITY": (
+ "obsolete-secret"
),
"AUTHORIZATION": "consumer-authorization",
"MCP_API_TOKEN": "consumer-secret",
@@ -99,4 +99,4 @@ def test_mcp_process_environment_excludes_secret_broker_authority():
assert environment["AUTHORIZATION"] == "consumer-authorization"
assert "EIGENT_WORKSPACE_SECRET_BROKER_ENDPOINT" not in environment
assert "EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY" not in environment
- assert "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY" not in environment
+ assert "EIGENT_OBSOLETE_SECRET_BROKER_CAPABILITY" not in environment
diff --git a/backend/tests/app/agent/toolkit/test_terminal_toolkit.py b/backend/tests/app/agent/toolkit/test_terminal_toolkit.py
index cdcfaea9..ccf63fb7 100644
--- a/backend/tests/app/agent/toolkit/test_terminal_toolkit.py
+++ b/backend/tests/app/agent/toolkit/test_terminal_toolkit.py
@@ -142,10 +142,10 @@ class TestTerminalToolkit:
"http://127.0.0.1:1234"
),
"EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY": "broker-secret",
- "EIGENT_WORKFORCE_SECRET_BROKER_ENDPOINT": (
+ "EIGENT_OBSOLETE_SECRET_BROKER_ENDPOINT": (
"http://127.0.0.1:5678"
),
- "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY": "legacy-secret",
+ "EIGENT_OBSOLETE_SECRET_BROKER_CAPABILITY": "obsolete-secret",
"AUTHORIZATION": "Bearer secret",
"SERVICE_AUTHORIZATION": "Bearer service-secret",
"NORMAL_API_KEY": "allowed-tool-secret",
@@ -160,7 +160,7 @@ class TestTerminalToolkit:
assert "EIGENT_LOCAL_CONTROL_CAPABILITY" not in environment
assert "EIGENT_WORKSPACE_SECRET_BROKER_ENDPOINT" not in environment
assert "EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY" not in environment
- assert "EIGENT_WORKFORCE_SECRET_BROKER_ENDPOINT" not in environment
- assert "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY" not in environment
+ assert "EIGENT_OBSOLETE_SECRET_BROKER_ENDPOINT" not in environment
+ assert "EIGENT_OBSOLETE_SECRET_BROKER_CAPABILITY" not in environment
assert "AUTHORIZATION" not in environment
assert "SERVICE_AUTHORIZATION" not in environment
diff --git a/backend/tests/app/permission_policy/test_service.py b/backend/tests/app/permission_policy/test_service.py
index 914476e2..cf634fd6 100644
--- a/backend/tests/app/permission_policy/test_service.py
+++ b/backend/tests/app/permission_policy/test_service.py
@@ -12,7 +12,7 @@ from app.workspace_config import (
LocalMaterialization,
ProviderModelCapability,
ThinkingEffort,
- parse_workforce_manifest,
+ parse_workspace_manifest,
)
@@ -22,10 +22,10 @@ def _create_bound_attempt(
run_id: str,
permission_profile_revision: str,
):
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
f"""
apiVersion: eigent.ai/v1alpha1
-kind: WorkforceBundle
+kind: WorkspaceBundle
metadata:
id: bundle_{run_id}
name: Permission test
diff --git a/backend/tests/app/run_journal/test_store.py b/backend/tests/app/run_journal/test_store.py
index f0d012a2..851ae488 100644
--- a/backend/tests/app/run_journal/test_store.py
+++ b/backend/tests/app/run_journal/test_store.py
@@ -39,7 +39,7 @@ from app.workspace_config import (
LocalMaterialization,
ProviderModelCapability,
ThinkingEffort,
- parse_workforce_manifest,
+ parse_workspace_manifest,
)
@@ -90,10 +90,10 @@ def test_initializes_schema_and_durability_pragmas(journal):
def _persist_environment_spec(journal, *, owner_id: str = "run-1"):
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
"""
apiVersion: eigent.ai/v1alpha1
-kind: WorkforceBundle
+kind: WorkspaceBundle
metadata:
id: bundle_test
name: Test Bundle
@@ -157,10 +157,10 @@ def test_workspace_config_and_environment_spec_are_immutable(journal):
def test_workspace_config_revision_lifecycle_uses_version_cas(journal):
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
"""
apiVersion: eigent.ai/v1alpha1
-kind: WorkforceBundle
+kind: WorkspaceBundle
metadata:
id: bundle_lifecycle
name: Lifecycle Bundle
@@ -213,7 +213,7 @@ spec:
def test_workspace_config_draft_autosave_uses_version_cas(journal):
document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_working_copy",
"name": "Working copy",
@@ -287,7 +287,7 @@ def test_workspace_config_publish_is_atomic_and_idempotently_advances_draft(
):
document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_publish",
"name": "Publish",
@@ -343,7 +343,7 @@ def test_workspace_config_publish_rejects_same_digest_wrong_revision_identity(
):
document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_publish",
"name": "Publish",
@@ -394,7 +394,7 @@ def test_workspace_config_publish_rebases_concurrent_edit_to_next_revision(
):
published_document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_publish",
"name": "Published A",
@@ -448,7 +448,7 @@ def test_workspace_config_publish_mismatch_rolls_back_every_local_fact(
):
document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_publish",
"name": "Publish",
@@ -847,7 +847,7 @@ def test_v17_database_adds_agent_plugin_import_tables_without_losing_draft(
path = tmp_path / "run-journal.sqlite3"
document = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_existing",
"name": "Existing",
diff --git a/backend/tests/app/workspace_bundle/test_authoring.py b/backend/tests/app/workspace_bundle/test_authoring.py
index 33606800..b704ba38 100644
--- a/backend/tests/app/workspace_bundle/test_authoring.py
+++ b/backend/tests/app/workspace_bundle/test_authoring.py
@@ -5,14 +5,14 @@ import json
import pytest
from app.workspace_bundle import WorkspaceBundleAuthoringService
-from app.workspace_config import WorkforceBundleManifest
+from app.workspace_config import WorkspaceBundleManifest
def test_save_review_extracts_requirement_names_without_local_values():
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_review",
"name": "Review",
@@ -86,10 +86,10 @@ def test_save_review_extracts_requirement_names_without_local_values():
def test_save_review_keeps_non_env_secret_slots_when_legacy_env_is_not_object(
legacy_environment,
):
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_review",
"name": "Review",
@@ -141,10 +141,10 @@ def test_save_review_keeps_non_env_secret_slots_when_legacy_env_is_not_object(
def test_save_review_hardens_declared_environment_secret_without_value():
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_review",
"name": "Review",
@@ -194,7 +194,7 @@ def test_save_review_hardens_declared_environment_secret_without_value():
def test_sensitive_environment_requirement_cannot_carry_example_value():
payload = {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle_review",
"name": "Review",
@@ -220,7 +220,7 @@ def test_sensitive_environment_requirement_cannot_carry_example_value():
}
try:
- WorkforceBundleManifest.model_validate(payload)
+ WorkspaceBundleManifest.model_validate(payload)
except ValueError as exc:
assert "cannot contain examples" in str(exc)
else:
diff --git a/backend/tests/app/workspace_bundle/test_installer.py b/backend/tests/app/workspace_bundle/test_installer.py
index ad6394a6..e0f2f8cb 100644
--- a/backend/tests/app/workspace_bundle/test_installer.py
+++ b/backend/tests/app/workspace_bundle/test_installer.py
@@ -16,7 +16,7 @@ from app.workspace_bundle import (
)
from app.workspace_config import (
ConfigPlacement,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
canonical_digest,
)
from app.workspace_git import ConfigurationRepositoryService, GitBackend
@@ -25,7 +25,7 @@ from app.workspace_git import ConfigurationRepositoryService, GitBackend
def _manifest(revision: int = 1) -> dict:
return {
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle-research",
"name": "Research Workforce",
@@ -106,7 +106,7 @@ class FakeCloud:
async def get_catalog_revision(self, bundle_id, revision_id):
revision_number = int(str(revision_id).rsplit("@", 1)[1])
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
_manifest(revision_number)
).canonical_payload()
suffix = "" if revision_number == 1 else f"-v{revision_number}"
@@ -287,7 +287,7 @@ def installer(tmp_path):
def test_local_review_decision_does_not_require_cloud(tmp_path):
with SQLiteRunJournal(tmp_path / "journal.sqlite3") as journal:
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
_manifest()
).canonical_payload()
proposal = journal.put_workspace_bundle_install_proposal(
@@ -626,7 +626,7 @@ async def test_required_local_values_block_before_cloud_and_optional_env_does_no
)
async def get_catalog_revision(bundle_id, revision_id):
- canonical = WorkforceBundleManifest.model_validate(
+ canonical = WorkspaceBundleManifest.model_validate(
manifest
).canonical_payload()
definition = json.dumps(
@@ -809,7 +809,7 @@ async def test_registry_secret_mcp_cannot_be_approved_or_reported_ready(
]
async def get_catalog_revision(bundle_id, revision_id):
- canonical = WorkforceBundleManifest.model_validate(
+ canonical = WorkspaceBundleManifest.model_validate(
manifest
).canonical_payload()
return {
@@ -874,7 +874,7 @@ async def test_proposal_rejects_mcp_definition_digest_mismatch(installer):
cloud.contents["asset-mcp-private"] = content
async def get_catalog_revision(bundle_id, revision_id):
- canonical = WorkforceBundleManifest.model_validate(
+ canonical = WorkspaceBundleManifest.model_validate(
manifest
).canonical_payload()
return {
@@ -923,7 +923,7 @@ async def test_unreadable_bound_value_blocks_all_cloud_side_effects(installer):
}
async def get_catalog_revision(bundle_id, revision_id):
- canonical = WorkforceBundleManifest.model_validate(
+ canonical = WorkspaceBundleManifest.model_validate(
manifest
).canonical_payload()
return {
@@ -1182,7 +1182,7 @@ def test_startup_reconciliation_exposes_interrupted_materialization(tmp_path):
bundle_id="bundle-research",
revision_id="bundle-research@1",
config_placement="sidecar",
- manifest=WorkforceBundleManifest.model_validate(
+ manifest=WorkspaceBundleManifest.model_validate(
_manifest()
).canonical_payload(),
assets=[],
diff --git a/backend/tests/app/workspace_bundle/test_secrets.py b/backend/tests/app/workspace_bundle/test_secrets.py
index e95f9a3b..c003cb17 100644
--- a/backend/tests/app/workspace_bundle/test_secrets.py
+++ b/backend/tests/app/workspace_bundle/test_secrets.py
@@ -295,8 +295,8 @@ def test_secret_broker_authority_is_removed_from_child_environment():
"PATH": "/usr/bin",
"EIGENT_WORKSPACE_SECRET_BROKER_ENDPOINT": "http://127.0.0.1:1234",
"EIGENT_WORKSPACE_SECRET_BROKER_CAPABILITY": "x" * 43,
- "EIGENT_WORKFORCE_SECRET_BROKER_ENDPOINT": "legacy-endpoint",
- "EIGENT_WORKFORCE_SECRET_BROKER_CAPABILITY": "legacy-capability",
+ "EIGENT_OBSOLETE_SECRET_BROKER_ENDPOINT": "obsolete-endpoint",
+ "EIGENT_OBSOLETE_SECRET_BROKER_CAPABILITY": "obsolete-capability",
}
captured = _capture_broker_environment(environment)
diff --git a/backend/tests/app/workspace_bundle/test_workspace_bundle_runtime.py b/backend/tests/app/workspace_bundle/test_workspace_bundle_runtime.py
index 380d45fe..91e2479b 100644
--- a/backend/tests/app/workspace_bundle/test_workspace_bundle_runtime.py
+++ b/backend/tests/app/workspace_bundle/test_workspace_bundle_runtime.py
@@ -36,7 +36,7 @@ from app.workspace_config import (
EnvironmentConfigResolver,
LocalMaterialization,
ResolvedContextSource,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
)
from app.workspace_config.admission import LegacyEnvironmentImporter
from app.workspace_config.admission import EnvironmentAdmissionService
@@ -96,10 +96,10 @@ def _installed_spec(
slot: f"slot://{slot}" for slot in mcp_secret_slots
}
contents["mcp/local.json"] = json.dumps(mcp_definition).encode()
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle-runtime",
"name": "Runtime Bundle",
diff --git a/backend/tests/app/workspace_config/test_admission.py b/backend/tests/app/workspace_config/test_admission.py
index d4e02031..e364e6bc 100644
--- a/backend/tests/app/workspace_config/test_admission.py
+++ b/backend/tests/app/workspace_config/test_admission.py
@@ -8,7 +8,7 @@ import pytest
from app.run_journal import SQLiteRunJournal
from app.workspace_config import (
ThinkingEffort,
- WorkforceBundleManifest,
+ WorkspaceBundleManifest,
WorkspaceBundleReconfigurationPendingError,
)
from app.workspace_config.admission import (
@@ -276,10 +276,10 @@ def test_admission_pins_current_space_permission_profile(tmp_path):
def test_materialized_bundle_replaces_legacy_template_for_new_run(tmp_path):
- manifest = WorkforceBundleManifest.model_validate(
+ manifest = WorkspaceBundleManifest.model_validate(
{
"apiVersion": "eigent.ai/v1alpha1",
- "kind": "WorkforceBundle",
+ "kind": "WorkspaceBundle",
"metadata": {
"id": "bundle-team",
"name": "Team Workspace",
diff --git a/backend/tests/app/workspace_config/test_models.py b/backend/tests/app/workspace_config/test_models.py
index 19cb7f9c..5946fc68 100644
--- a/backend/tests/app/workspace_config/test_models.py
+++ b/backend/tests/app/workspace_config/test_models.py
@@ -21,13 +21,13 @@ from app.workspace_config import (
assert_bundle_asset_safe,
assert_manifest_secret_free,
canonical_digest,
- parse_workforce_manifest,
+ parse_workspace_manifest,
)
from app.workspace_config.models import assert_cloud_projection_safe
MANIFEST_YAML = """
apiVersion: eigent.ai/v1alpha1
-kind: WorkforceBundle
+kind: WorkspaceBundle
metadata:
id: bundle_product_research
name: Product Research Workforce
@@ -96,8 +96,8 @@ def _capability() -> ProviderModelCapability:
def test_manifest_is_strict_canonical_and_digest_stable():
- first = parse_workforce_manifest(MANIFEST_YAML)
- reordered = parse_workforce_manifest(
+ first = parse_workspace_manifest(MANIFEST_YAML)
+ reordered = parse_workspace_manifest(
MANIFEST_YAML.replace(
" name: Product Research Workforce\n revision: 7",
" revision: 7\n name: Product Research Workforce",
@@ -113,14 +113,14 @@ def test_manifest_is_strict_canonical_and_digest_stable():
def test_legacy_manifest_canonical_payload_does_not_gain_environment_field():
- manifest = parse_workforce_manifest(MANIFEST_YAML)
+ manifest = parse_workspace_manifest(MANIFEST_YAML)
assert "environment" not in manifest.canonical_payload()["spec"]
def test_manifest_rejects_secret_value_even_inside_freeform_instructions():
with pytest.raises(SecretValueInManifestError, match="api_key"):
- parse_workforce_manifest(
+ parse_workspace_manifest(
MANIFEST_YAML.replace(
"coordinator: bundle://instructions/coordinator.md",
"api_key: sk-must-not-enter-a-bundle",
@@ -224,7 +224,7 @@ def test_asset_preflight_preserves_safe_structured_assets(
def test_manifest_allows_path_like_prose_and_requires_default_model():
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
MANIFEST_YAML.replace(
" context:\n",
" context:\n"
@@ -235,7 +235,7 @@ def test_manifest_allows_path_like_prose_and_requires_default_model():
)
assert manifest.spec.context[0].content is not None
with pytest.raises(ValidationError, match="default profile"):
- parse_workforce_manifest(
+ parse_workspace_manifest(
MANIFEST_YAML.replace(" default:\n", " custom:\n")
)
@@ -250,7 +250,7 @@ def test_manifest_allows_path_like_prose_and_requires_default_model():
],
)
def test_manifest_allows_device_paths_inside_local_inline_prose(path):
- parse_workforce_manifest(
+ parse_workspace_manifest(
MANIFEST_YAML.replace(
" context:\n",
" context:\n"
@@ -281,7 +281,7 @@ def test_cloud_projection_only_rejects_identifying_home_paths():
def test_manifest_rejects_physical_path_for_local_slot():
with pytest.raises(ValidationError, match="physical path"):
- parse_workforce_manifest(
+ parse_workspace_manifest(
MANIFEST_YAML.replace(
" sharing: reference_only",
" path: /Users/alice/private\n"
@@ -292,7 +292,7 @@ def test_manifest_rejects_physical_path_for_local_slot():
def test_thinking_effort_aliases_are_normalized_and_unsupported_is_explicit():
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
MANIFEST_YAML.replace(
"thinkingEffort: medium", "thinkingEffort: light"
)
@@ -361,7 +361,7 @@ def test_capability_registry_maps_product_max_without_blind_forwarding():
def test_cloud_projection_redacts_local_paths_and_binding_ids():
- manifest = parse_workforce_manifest(MANIFEST_YAML)
+ manifest = parse_workspace_manifest(MANIFEST_YAML)
local = LocalMaterialization(
context_sources=(
ResolvedContextSource(
@@ -420,7 +420,7 @@ def test_cloud_projection_redacts_local_paths_and_binding_ids():
def test_cloud_projection_does_not_repeat_inline_bundle_path_instructions():
- manifest = parse_workforce_manifest(
+ manifest = parse_workspace_manifest(
MANIFEST_YAML.replace(
" context:\n",
" context:\n"
@@ -449,7 +449,7 @@ def test_cloud_projection_does_not_repeat_inline_bundle_path_instructions():
def test_cloud_projection_rejects_local_fields_in_semantic_capabilities():
- manifest = parse_workforce_manifest(MANIFEST_YAML)
+ manifest = parse_workspace_manifest(MANIFEST_YAML)
spec = EnvironmentConfigResolver().resolve(
manifest=manifest,
owner_type="run",
diff --git a/backend/tests/app/workspace_git/test_configuration_repository.py b/backend/tests/app/workspace_git/test_configuration_repository.py
index 65b9cd56..79e70366 100644
--- a/backend/tests/app/workspace_git/test_configuration_repository.py
+++ b/backend/tests/app/workspace_git/test_configuration_repository.py
@@ -12,7 +12,7 @@ from app.run_journal import IdempotencyConflictError, SQLiteRunJournal
from app.workspace_config import (
ConfigPlacement,
SecretValueInManifestError,
- parse_workforce_manifest,
+ parse_workspace_manifest,
)
from app.workspace_git import (
ConfigurationRepositoryError,
@@ -24,7 +24,7 @@ from app.workspace_git import (
MANIFEST = """
apiVersion: eigent.ai/v1alpha1
-kind: WorkforceBundle
+kind: WorkspaceBundle
metadata:
id: bundle_local
name: Local Workspace
@@ -84,7 +84,7 @@ def test_sidecar_bootstrap_never_mutates_user_space(
original = space / "private-notes.txt"
original.write_text("never import me", encoding="utf-8")
service, backend = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
first = service.bootstrap(
space_id="space-1",
@@ -132,7 +132,7 @@ def test_sidecar_bootstrap_commits_verified_bundle_assets(tmp_path, journal):
result = service.bootstrap(
space_id="space-1",
space_root=space,
- manifest=parse_workforce_manifest(MANIFEST),
+ manifest=parse_workspace_manifest(MANIFEST),
placement=ConfigPlacement.SIDECAR,
created_by="user-1",
assets={
@@ -142,7 +142,7 @@ def test_sidecar_bootstrap_commits_verified_bundle_assets(tmp_path, journal):
lock_payload={
"apiVersion": "eigent.ai/lock/v1alpha1",
"bundleRevision": "bundle_local@1",
- "manifestDigest": parse_workforce_manifest(MANIFEST).digest,
+ "manifestDigest": parse_workspace_manifest(MANIFEST).digest,
"assets": [
{
"ref": "bundle://instructions/coordinator.md",
@@ -182,7 +182,7 @@ def test_same_bundle_revision_materializes_into_multiple_spaces(
first_space.mkdir()
second_space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
first = service.bootstrap(
space_id="space-1",
@@ -218,7 +218,7 @@ def test_existing_space_materialization_rejects_placement_change_before_git(
space = tmp_path / "space"
space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
service.bootstrap(
space_id="space-1",
space_root=space,
@@ -263,7 +263,7 @@ def test_in_repo_commit_excludes_and_preserves_user_staged_changes(
result = service.bootstrap(
space_id="space-1",
space_root=space,
- manifest=parse_workforce_manifest(MANIFEST),
+ manifest=parse_workspace_manifest(MANIFEST),
placement=ConfigPlacement.IN_REPO,
created_by="user-1",
)
@@ -284,7 +284,7 @@ def test_in_repo_requires_explicit_content_init(tmp_path, journal):
space = tmp_path / "plain-folder"
space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
with pytest.raises(
ConfigurationRepositoryError,
@@ -328,7 +328,7 @@ def test_nested_repository_is_rejected_without_writing_child(
service.bootstrap(
space_id="space-1",
space_root=child,
- manifest=parse_workforce_manifest(MANIFEST),
+ manifest=parse_workspace_manifest(MANIFEST),
placement=ConfigPlacement.IN_REPO,
created_by="user-1",
allow_content_repository_init=True,
@@ -345,7 +345,7 @@ def test_secret_or_device_capability_in_lock_is_rejected_before_init(
space = tmp_path / "space"
space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
with pytest.raises(SecretValueInManifestError):
service.bootstrap(
@@ -376,7 +376,7 @@ def test_lock_must_match_bundle_revision_before_git_init(tmp_path, journal):
space = tmp_path / "space"
space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
with pytest.raises(
ConfigurationRepositoryError,
@@ -408,7 +408,7 @@ def test_replay_does_not_overwrite_manual_manifest_edit(
space = tmp_path / "space"
space.mkdir()
service, _ = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
first = service.bootstrap(
space_id="space-1",
space_root=space,
@@ -444,7 +444,7 @@ def test_bootstrap_recovers_exact_untracked_files_after_crash(
space = tmp_path / "space"
space.mkdir()
service, backend = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
repository = tmp_path / "state" / "spaces" / "space-1" / "configuration"
backend.init_repository(repository)
manifest_path = repository / "workspace.yaml"
@@ -502,7 +502,7 @@ def test_bootstrap_clears_owner_execute_for_non_executable_asset_recovery(
space = tmp_path / "space"
space.mkdir()
service, backend = _service(tmp_path, journal)
- manifest = parse_workforce_manifest(MANIFEST)
+ manifest = parse_workspace_manifest(MANIFEST)
repository = tmp_path / "state" / "spaces" / "space-1" / "configuration"
backend.init_repository(repository)
content = b"public package data\n"
@@ -558,7 +558,7 @@ def test_bundle_upgrade_preserves_user_edits_and_removes_only_clean_old_assets(
space = tmp_path / "space"
space.mkdir()
service, backend = _service(tmp_path, journal)
- first_manifest = parse_workforce_manifest(MANIFEST)
+ first_manifest = parse_workspace_manifest(MANIFEST)
first_assets = {
"instructions/coordinator.md": b"version one\n",
"assets/obsolete.txt": b"remove on upgrade\n",
@@ -587,7 +587,7 @@ def test_bundle_upgrade_preserves_user_edits_and_removes_only_clean_old_assets(
)
edited_path = first.configuration_repository_root / "instructions/coordinator.md"
edited_path.write_text("user edit\n", encoding="utf-8")
- second_manifest = parse_workforce_manifest(
+ second_manifest = parse_workspace_manifest(
MANIFEST.replace("revision: 1", "revision: 2")
)
second_assets = {"instructions/coordinator.md": b"version two\n"}
@@ -652,7 +652,7 @@ def test_revision_conflict_is_detected_before_git_mutation(
space = tmp_path / "space"
space.mkdir()
service, _ = _service(tmp_path, journal)
- original = parse_workforce_manifest(MANIFEST)
+ original = parse_workspace_manifest(MANIFEST)
first = service.bootstrap(
space_id="space-1",
space_root=space,
@@ -660,7 +660,7 @@ def test_revision_conflict_is_detected_before_git_mutation(
placement=ConfigPlacement.SIDECAR,
created_by="user-1",
)
- conflicting = parse_workforce_manifest(
+ conflicting = parse_workspace_manifest(
MANIFEST.replace("name: Local Workspace", "name: Changed Name")
)
diff --git a/electron/main/workspaceSecrets/vault.ts b/electron/main/workspaceSecrets/vault.ts
index 92d5bb7b..02733b7a 100644
--- a/electron/main/workspaceSecrets/vault.ts
+++ b/electron/main/workspaceSecrets/vault.ts
@@ -26,7 +26,7 @@ import type {
} from './types';
const FORMAT_VERSION = 1;
-const VAULT_FILE_NAME = 'workforce-secret-vault.v1.json';
+const VAULT_FILE_NAME = 'workspace-secret-vault.v1.json';
const MAX_VAULT_BYTES = 8 * 1024 * 1024;
export const MAX_WORKSPACE_SECRET_BYTES = 64 * 1024;
diff --git a/src/components/WorkspaceBundle/AgentPluginImportWizard.tsx b/src/components/WorkspaceBundle/AgentPluginImportWizard.tsx
index 38297aec..d2713461 100644
--- a/src/components/WorkspaceBundle/AgentPluginImportWizard.tsx
+++ b/src/components/WorkspaceBundle/AgentPluginImportWizard.tsx
@@ -286,7 +286,7 @@ export function AgentPluginImportWizard({
/>
Agent Plugin converted
- {conversion.bundle_id}@{conversion.revision_id} is a local Workforce
+ {conversion.bundle_id}@{conversion.revision_id} is a local Workspace
Bundle draft. It has not been published or installed elsewhere.
@@ -311,7 +311,7 @@ export function AgentPluginImportWizard({
Import Agent Plugin
Import the Agent Plugins standard. Eigent reviews the package before
- converting it to a local Workforce Bundle draft.
+ converting it to a local Workspace Bundle draft.
diff --git a/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.test.tsx b/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.test.tsx
index 42741904..fe725b9f 100644
--- a/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.test.tsx
+++ b/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.test.tsx
@@ -99,8 +99,8 @@ import { WorkspaceBundleInstallWizard } from './WorkspaceBundleInstallWizard';
const manifest = {
apiVersion: 'eigent.ai/v1alpha1',
- kind: 'WorkforceBundle',
- metadata: { id: 'research', name: 'Research workforce', revision: 1 },
+ kind: 'WorkspaceBundle',
+ metadata: { id: 'research', name: 'Research workspace', revision: 1 },
spec: {
instructions: {},
context: [],
@@ -135,7 +135,7 @@ const review = {
bundle: {
id: 'research',
workspace_id: 'author-space',
- name: 'Research workforce',
+ name: 'Research workspace',
visibility: 'public' as const,
latest_published_revision_id: 'research@1',
},
@@ -236,7 +236,7 @@ describe('WorkspaceBundleInstallWizard', () => {
const user = userEvent.setup();
renderWizard({ initialHandle: 'research@1' });
- expect(await screen.findByText('Research workforce')).toBeInTheDocument();
+ expect(await screen.findByText('Research workspace')).toBeInTheDocument();
expect(mocks.createSpace).not.toHaveBeenCalled();
expect(mocks.decide).not.toHaveBeenCalled();
@@ -785,7 +785,7 @@ describe('WorkspaceBundleInstallWizard', () => {
).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'Retry' }));
- expect(await screen.findByText('Research workforce')).toBeInTheDocument();
+ expect(await screen.findByText('Research workspace')).toBeInTheDocument();
expect(mocks.fetchReview).toHaveBeenCalledTimes(2);
});
diff --git a/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.tsx b/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.tsx
index 8fa69d23..124973a0 100644
--- a/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.tsx
+++ b/src/components/WorkspaceBundle/WorkspaceBundleInstallWizard.tsx
@@ -337,7 +337,7 @@ function McpDestinationReview({
}
const installSeedKey = (revisionId: string, actorId: string): string =>
- `eigent:workforce-bundle-install-seed:v1:${actorId}:${revisionId}`;
+ `eigent:workspace-bundle-install-seed:v1:${actorId}:${revisionId}`;
function readInstallSeed(
revisionId: string,
@@ -564,7 +564,7 @@ export function WorkspaceBundleInstallWizard({
async (rawHandle: string) => {
const parsed = parseWorkspaceBundleHandle(rawHandle);
if (!parsed) {
- setError('Use a published handle such as my-workforce@1.');
+ setError('Use a published handle such as my-workspace@1.');
setRetryMode(null);
return;
}
@@ -634,13 +634,13 @@ export function WorkspaceBundleInstallWizard({
const name =
review.bundle?.name ||
review.revision.manifest.metadata.name ||
- 'Imported workforce';
+ 'Imported workspace';
const spaceId = await createSpaceOnServer({
name,
sourceType: 'blank',
setActive: false,
metadata: {
- createdFrom: 'workforce_bundle_install',
+ createdFrom: 'workspace_bundle_install',
bundleRevision: handle.revisionId,
bundleInstallProposalId: proposalId,
bundleInstallRequestId: requestId,
@@ -963,10 +963,10 @@ export function WorkspaceBundleInstallWizard({
- Install Workforce Bundle
+ Install Workspace Bundle
- Review what the workforce can access, then configure required values
+ Review what the workspace environment can access, then configure required values
and connections locally.
@@ -1010,8 +1010,8 @@ export function WorkspaceBundleInstallWizard({
setHandleInput(event.target.value)}
- placeholder="research-workforce@1"
- aria-label="Workforce Bundle share handle"
+ placeholder="research-workspace@1"
+ aria-label="Workspace Bundle share handle"
/>
{busyKey === 'review' ? (
diff --git a/src/components/WorkspaceConfiguration/EnvironmentRequirementsEditor.tsx b/src/components/WorkspaceConfiguration/EnvironmentRequirementsEditor.tsx
index a04142f3..5cb2f89e 100644
--- a/src/components/WorkspaceConfiguration/EnvironmentRequirementsEditor.tsx
+++ b/src/components/WorkspaceConfiguration/EnvironmentRequirementsEditor.tsx
@@ -53,7 +53,7 @@ export function EnvironmentRequirementsEditor({
Declare names and safe documentation only. Secret values, tokens, and
local environment values are never stored in or shared with a
- Workforce Bundle.
+ Workspace Bundle.
{
fireEvent.click(screen.getByRole('button', { name: 'Publish version' }));
expect(
- await screen.findByLabelText('Published Workforce Bundle handle')
+ await screen.findByLabelText('Published Workspace Bundle handle')
).toHaveTextContent('bundle-1@1');
expect(screen.getByText('Shareable install handle')).toBeInTheDocument();
expect(
- screen.getByText(/paste it into Import Workforce Bundle/i)
+ screen.getByText(/paste it into Import Workspace Bundle/i)
).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Copy share handle' }));
diff --git a/src/components/WorkspaceConfiguration/WorkspaceBundleSaveDialog.tsx b/src/components/WorkspaceConfiguration/WorkspaceBundleSaveDialog.tsx
index 4ab00e18..d5789fb0 100644
--- a/src/components/WorkspaceConfiguration/WorkspaceBundleSaveDialog.tsx
+++ b/src/components/WorkspaceConfiguration/WorkspaceBundleSaveDialog.tsx
@@ -230,7 +230,7 @@ export function WorkspaceBundleSaveDialog({
const totalAssetBytes = selectedAssetBytes + preparedAssetBytes;
const assetLimitError = review
? totalAssetCount > MAX_ASSET_COUNT
- ? `A Workforce Bundle can contain at most ${MAX_ASSET_COUNT} assets.`
+ ? `A Workspace Bundle can contain at most ${MAX_ASSET_COUNT} assets.`
: totalAssetBytes > MAX_TOTAL_ASSET_BYTES
? 'Selected assets exceed the 128 MiB total Bundle limit.'
: Object.values(assetFiles).some(
@@ -284,7 +284,7 @@ export function WorkspaceBundleSaveDialog({
try {
if (totalAssetCount > MAX_ASSET_COUNT) {
throw new Error(
- `A Workforce Bundle can contain at most ${MAX_ASSET_COUNT} assets.`
+ `A Workspace Bundle can contain at most ${MAX_ASSET_COUNT} assets.`
);
}
const selected = manualAssetPaths.map((path) => {
@@ -558,7 +558,7 @@ export function WorkspaceBundleSaveDialog({
}}
>
@@ -864,7 +864,7 @@ export function WorkspaceBundleSaveDialog({
{publishedHandle}
@@ -880,7 +880,7 @@ export function WorkspaceBundleSaveDialog({
Share this exact bundle_id@revision handle.
- Recipients can paste it into Import Workforce Bundle to
+ Recipients can paste it into Import Workspace Bundle to
review and install this immutable version.
diff --git a/src/pages/Home/components/HomeHubToolbar.tsx b/src/pages/Home/components/HomeHubToolbar.tsx
index 2853a930..8ebb9ff1 100644
--- a/src/pages/Home/components/HomeHubToolbar.tsx
+++ b/src/pages/Home/components/HomeHubToolbar.tsx
@@ -255,7 +255,7 @@ export default function HomeHubToolbar({
onClick={() => navigate('/workspace-bundles/install')}
>
- Import Workforce Bundle
+ Import Workspace Bundle
{isDesktop() ? (
diff --git a/src/service/workspaceBundleInstallApi.test.ts b/src/service/workspaceBundleInstallApi.test.ts
index 77be35ac..a8751d9f 100644
--- a/src/service/workspaceBundleInstallApi.test.ts
+++ b/src/service/workspaceBundleInstallApi.test.ts
@@ -33,46 +33,46 @@ describe('workspace Bundle install API', () => {
});
it('accepts only a canonical immutable share handle', () => {
- expect(parseWorkspaceBundleHandle('research-workforce@12')).toEqual({
- bundleId: 'research-workforce',
- revisionId: 'research-workforce@12',
+ expect(parseWorkspaceBundleHandle('research-workspace@12')).toEqual({
+ bundleId: 'research-workspace',
+ revisionId: 'research-workspace@12',
});
- expect(parseWorkspaceBundleHandle('research-workforce')).toBeNull();
- expect(parseWorkspaceBundleHandle('research-workforce@0')).toBeNull();
+ expect(parseWorkspaceBundleHandle('research-workspace')).toBeNull();
+ expect(parseWorkspaceBundleHandle('research-workspace@0')).toBeNull();
});
it('loads the published revision before creating a local proposal', async () => {
- mocks.findBundle.mockResolvedValue({ id: 'research-workforce' });
+ mocks.findBundle.mockResolvedValue({ id: 'research-workspace' });
mocks.getRevision.mockResolvedValue({
- id: 'research-workforce@1',
- bundle_id: 'research-workforce',
+ id: 'research-workspace@1',
+ bundle_id: 'research-workspace',
status: 'published',
});
await fetchWorkspaceBundleInstallReview({
- bundleId: 'research-workforce',
- revisionId: 'research-workforce@1',
+ bundleId: 'research-workspace',
+ revisionId: 'research-workspace@1',
});
expect(mocks.getRevision).toHaveBeenCalledWith(
- 'research-workforce',
- 'research-workforce@1'
+ 'research-workspace',
+ 'research-workspace@1'
);
expect(mocks.fetchPost).not.toHaveBeenCalled();
});
it('rejects a draft revision during the review-first read', async () => {
- mocks.findBundle.mockResolvedValue({ id: 'research-workforce' });
+ mocks.findBundle.mockResolvedValue({ id: 'research-workspace' });
mocks.getRevision.mockResolvedValue({
- id: 'research-workforce@1',
- bundle_id: 'research-workforce',
+ id: 'research-workspace@1',
+ bundle_id: 'research-workspace',
status: 'validated',
});
await expect(
fetchWorkspaceBundleInstallReview({
- bundleId: 'research-workforce',
- revisionId: 'research-workforce@1',
+ bundleId: 'research-workspace',
+ revisionId: 'research-workspace@1',
})
).rejects.toThrow('Only published');
});
@@ -84,8 +84,8 @@ describe('workspace Bundle install API', () => {
proposalId: 'p-1',
requestId: 'r-1',
spaceId: 'space-1',
- bundleId: 'research-workforce',
- revisionId: 'research-workforce@1',
+ bundleId: 'research-workspace',
+ revisionId: 'research-workspace@1',
});
expect(mocks.fetchPost).toHaveBeenCalledWith(
diff --git a/src/service/workspaceBundleInstallApi.ts b/src/service/workspaceBundleInstallApi.ts
index 1cdebe5d..dc55fb53 100644
--- a/src/service/workspaceBundleInstallApi.ts
+++ b/src/service/workspaceBundleInstallApi.ts
@@ -149,14 +149,14 @@ export async function fetchWorkspaceBundleInstallReview(
);
if (revision.status !== 'published') {
throw new Error(
- 'Only published Workforce Bundle versions can be installed.'
+ 'Only published Workspace Bundle versions can be installed.'
);
}
if (
revision.bundle_id !== handle.bundleId ||
revision.id !== handle.revisionId
) {
- throw new Error('The Workforce Bundle version identity does not match.');
+ throw new Error('The Workspace Bundle version identity does not match.');
}
// Public install remains usable even if mutable owner metadata is not
// readable by this account. The immutable revision is the authority.
diff --git a/src/service/workspaceConfigurationApi.test.ts b/src/service/workspaceConfigurationApi.test.ts
index a5565705..f484c744 100644
--- a/src/service/workspaceConfigurationApi.test.ts
+++ b/src/service/workspaceConfigurationApi.test.ts
@@ -27,7 +27,7 @@ import {
const document: WorkspaceConfigurationDocument = {
apiVersion: 'eigent.ai/v1alpha1',
- kind: 'WorkforceBundle',
+ kind: 'WorkspaceBundle',
metadata: { id: 'bundle-1', name: 'Bundle', revision: 1 },
spec: {
instructions: {},
diff --git a/src/service/workspaceConfigurationApi.ts b/src/service/workspaceConfigurationApi.ts
index 5e1f9e43..18b7ce8d 100644
--- a/src/service/workspaceConfigurationApi.ts
+++ b/src/service/workspaceConfigurationApi.ts
@@ -58,7 +58,7 @@ export interface WorkspaceAgentProfile {
export interface WorkspaceConfigurationDocument {
apiVersion: 'eigent.ai/v1alpha1';
- kind: 'WorkforceBundle';
+ kind: 'WorkspaceBundle';
metadata: {
id: string;
name: string;
diff --git a/test/unit/electron/main/workspaceSecrets.test.ts b/test/unit/electron/main/workspaceSecrets.test.ts
index be5701ac..a0039796 100644
--- a/test/unit/electron/main/workspaceSecrets.test.ts
+++ b/test/unit/electron/main/workspaceSecrets.test.ts
@@ -105,7 +105,7 @@ describe('WorkspaceSecretVault', () => {
expect(fs.statSync(store.rootDir).mode & 0o777).toBe(0o700);
expect(fs.statSync(store.filePath).mode & 0o777).toBe(0o600);
expect(fs.readdirSync(store.rootDir)).toEqual([
- 'workforce-secret-vault.v1.json',
+ 'workspace-secret-vault.v1.json',
]);
expect(fsync).toHaveBeenCalledTimes(2);
expect(store.resolve(result)).toBe('sentinel-super-secret');
diff --git a/test/unit/hooks/useWorkspaceConfiguration.test.tsx b/test/unit/hooks/useWorkspaceConfiguration.test.tsx
index 8099575b..8d27da54 100644
--- a/test/unit/hooks/useWorkspaceConfiguration.test.tsx
+++ b/test/unit/hooks/useWorkspaceConfiguration.test.tsx
@@ -26,7 +26,7 @@ import { useWorkspaceConfiguration } from '@/hooks/useWorkspaceConfiguration';
const makeDocument = (name = 'Research'): WorkspaceConfigurationDocument => ({
apiVersion: 'eigent.ai/v1alpha1',
- kind: 'WorkforceBundle',
+ kind: 'WorkspaceBundle',
metadata: { id: 'bundle-1', name, revision: 1 },
spec: {
instructions: {},