Summary
The standalone workspace marker filename is inconsistent across the codebase. The runtime code treats .cf-workspace.toml as canonical and .studio-workspace.toml as a "legacy" fallback, while ADR-0020 (the rebrand decision of record), the JSON schema, and the entire cypilot → studio migration path designate .studio-workspace.toml as the canonical name. There is no superseding ADR authorizing the move to .cf-workspace.toml.
Net effect: cf migrate from cypilot writes exactly the filename the loader classifies as "legacy."
The two conflicting sources of truth
Camp A — .cf-workspace.toml is canonical (runtime code path):
skills/studio/scripts/studio/constants.py:17 — WORKSPACE_CONFIG_FILENAME = ".cf-workspace.toml"
skills/studio/scripts/studio/utils/workspace.py:597 — _LEGACY_WORKSPACE_FILENAME = ".studio-workspace.toml", and _find_standalone_workspace docstring: checks .cf-workspace.toml (canonical name) first, then .studio-workspace.toml (legacy / test-fixture name)
commands/workspace_init.py:241,384 — workspace-init writes .cf-workspace.toml
commands/workspace_add.py:242, commands/workspace_info.py:146, commands/validate.py:1357, commands/check_language.py:319
requirements/workspace-setup.md:63 — "standalone → write {project_root}/.cf-workspace.toml"
Camp B — .studio-workspace.toml is canonical (governance, schema, migration path):
architecture/ADR/0020-cpt-studio-adr-rebrand-and-mirror-override-v1.md:84 — Workspace marker file: .cypilot-workspace.toml → .studio-workspace.toml
architecture/ADR/0020-...md:140 — "Migrating a cypilot 3.9.0 project writes .studio-workspace.toml directly"
schemas/workspace.schema.json:4 — title: "Constructor Studio Workspace Configuration (.studio-workspace.toml)"
skills/studio/migrate-from-cypilot.md:129,242,307 — migration target marker file: .studio-workspace.toml
guides/MIGRATING-FROM-CYPILOT.md:44,53 — "The migrator writes … .studio-workspace.toml"
requirements/storytelling-phases.md:60,124
User-facing impact
A user migrating a real multi-repo project with cf migrate from cypilot follows the documented Category-C step and renames their workspace file to .studio-workspace.toml (as the migrate tooling, guide, and schema all instruct). The loader in _find_standalone_workspace then only picks it up via the legacy fallback branch, and the code + workspace-init treat .cf-workspace.toml as the real name. This is:
- Confusing — the migration produces a file the code calls "legacy."
- A latent break — if a future release drops the legacy fallback (it is explicitly labeled "legacy / test-fixture"), workspace discovery silently returns
(None, None) and cross-repo traceability breaks with no error.
Reproduce
# In a project with a standalone workspace file named per the migration docs:
mv .cypilot-workspace.toml .studio-workspace.toml # what migrate-from-cypilot instructs
cfs workspace-info # works, but only via the legacy fallback
# vs. `cfs workspace-init` which writes .cf-workspace.toml
Proposed resolutions (pick one direction, then make it consistent everywhere)
Option 1 — Conform to ADR-0020 (.studio-workspace.toml canonical). Update constants.py/workspace.py so .studio-workspace.toml is the canonical name (keep .cf-workspace.toml as an accepted alias), and align the ~46 .cf-workspace.toml references. Honors the existing decision-of-record.
Option 2 — Ratify .cf-workspace.toml (canonical) with a new ADR. If the move to .cf-workspace.toml was intentional, add an ADR superseding 0020's workspace-marker row, then fix the schema title, migration tooling (migrate-from-cypilot.md, MIGRATING-FROM-CYPILOT.md), and storytelling reqs to write/reference .cf-workspace.toml.
Option 3 (minimal, direction-neutral) — Treat both as first-class. Stop labeling .studio-workspace.toml "legacy," document both as supported canonical names in the loader + docstrings, and add a test asserting both resolve. Removes the break-risk without a large rename.
Happy to open a PR for whichever direction the maintainers prefer.
Environment
- Upstream
constructorfabric/studio @ 2c07f79 (default branch main)
- Found while migrating a downstream multi-repo project (35 workspace sources) from Cypilot to Constructor Studio.
Summary
The standalone workspace marker filename is inconsistent across the codebase. The runtime code treats
.cf-workspace.tomlas canonical and.studio-workspace.tomlas a "legacy" fallback, while ADR-0020 (the rebrand decision of record), the JSON schema, and the entirecypilot → studiomigration path designate.studio-workspace.tomlas the canonical name. There is no superseding ADR authorizing the move to.cf-workspace.toml.Net effect:
cf migrate from cypilotwrites exactly the filename the loader classifies as "legacy."The two conflicting sources of truth
Camp A —
.cf-workspace.tomlis canonical (runtime code path):skills/studio/scripts/studio/constants.py:17—WORKSPACE_CONFIG_FILENAME = ".cf-workspace.toml"skills/studio/scripts/studio/utils/workspace.py:597—_LEGACY_WORKSPACE_FILENAME = ".studio-workspace.toml", and_find_standalone_workspacedocstring: checks.cf-workspace.toml(canonical name) first, then.studio-workspace.toml(legacy / test-fixture name)commands/workspace_init.py:241,384—workspace-initwrites.cf-workspace.tomlcommands/workspace_add.py:242,commands/workspace_info.py:146,commands/validate.py:1357,commands/check_language.py:319requirements/workspace-setup.md:63— "standalone → write{project_root}/.cf-workspace.toml"Camp B —
.studio-workspace.tomlis canonical (governance, schema, migration path):architecture/ADR/0020-cpt-studio-adr-rebrand-and-mirror-override-v1.md:84— Workspace marker file:.cypilot-workspace.toml→.studio-workspace.tomlarchitecture/ADR/0020-...md:140— "Migrating a cypilot 3.9.0 project writes.studio-workspace.tomldirectly"schemas/workspace.schema.json:4— title: "Constructor Studio Workspace Configuration (.studio-workspace.toml)"skills/studio/migrate-from-cypilot.md:129,242,307— migrationtarget marker file: .studio-workspace.tomlguides/MIGRATING-FROM-CYPILOT.md:44,53— "The migrator writes ….studio-workspace.toml"requirements/storytelling-phases.md:60,124User-facing impact
A user migrating a real multi-repo project with
cf migrate from cypilotfollows the documented Category-C step and renames their workspace file to.studio-workspace.toml(as the migrate tooling, guide, and schema all instruct). The loader in_find_standalone_workspacethen only picks it up via the legacy fallback branch, and the code +workspace-inittreat.cf-workspace.tomlas the real name. This is:(None, None)and cross-repo traceability breaks with no error.Reproduce
Proposed resolutions (pick one direction, then make it consistent everywhere)
Option 1 — Conform to ADR-0020 (
.studio-workspace.tomlcanonical). Updateconstants.py/workspace.pyso.studio-workspace.tomlis the canonical name (keep.cf-workspace.tomlas an accepted alias), and align the ~46.cf-workspace.tomlreferences. Honors the existing decision-of-record.Option 2 — Ratify
.cf-workspace.toml(canonical) with a new ADR. If the move to.cf-workspace.tomlwas intentional, add an ADR superseding 0020's workspace-marker row, then fix the schema title, migration tooling (migrate-from-cypilot.md,MIGRATING-FROM-CYPILOT.md), and storytelling reqs to write/reference.cf-workspace.toml.Option 3 (minimal, direction-neutral) — Treat both as first-class. Stop labeling
.studio-workspace.toml"legacy," document both as supported canonical names in the loader + docstrings, and add a test asserting both resolve. Removes the break-risk without a large rename.Happy to open a PR for whichever direction the maintainers prefer.
Environment
constructorfabric/studio@2c07f79(default branchmain)