You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
They fail with OperationalError('no such table: workspace') and exit_code == 1.
Mechanism._check_proof9_merge_gate resolves the workspace from the process cwd:
try:
workspace=get_workspace(Path.cwd()) # pr_commands.py:413exceptFileNotFoundError:
returnNone# only "no workspace" is toleratedtry:
open_reqs=proof_ledger.list_requirements(workspace, ...)
exceptExceptionase:
# Fail closed, like the API path: a broken ledger blocks the merge.raisetyper.Exit(1) # pr_commands.py:422
CliRunner does not change cwd, so Path.cwd() is the repo root — which on a developer machine contains a real .codeframe/state.db left over from demos/dogfooding. When that DB predates the current schema, list_requirements raises, the gate correctly fails closed, and the test's exit_code == 0 assertion fails.
The production behaviour is right: a broken ledger should block a merge. The defect is that tests read the developer's ambient workspace instead of an isolated one.
Why this matters
CI cannot catch it. CI has no .codeframe/, so Test Suite (Unit + E2E) is green on main while the same commit is red locally. This is the inverse of the usual ambient-env trap and it is genuinely disorienting.
It taxes every remaining P0/P1. Each full-suite run surfaces 4 red tests that must be re-diagnosed and dismissed. During [P0.1] Gitignore .env.production and check history for committed secrets #895 this cost a full investigation cycle (stash → run on main → bisect to .codeframe/) before the change could be cleared.
It erodes the signal. A suite with permanently-red tests trains everyone to ignore red, which is how a real regression eventually ships.
Reproduction
# with a .codeframe/ present in the repo root
uv run pytest tests/cli/test_v2_cli_integration.py::TestPRCommands::test_pr_merge \
tests/ui/test_v2_scope_enforcement.py -q
# => 4 failed, 6 passed
mv .codeframe /tmp/ # remove the ambient workspace
uv run pytest <same args> -q
# => 10 passed
codeframe/cli/pr_commands.py:414 — catches only FileNotFoundError
codeframe/cli/pr_commands.py:419-422 — fail-closed on any ledger error
codeframe/cli/pr_commands.py:61,205 — two more Path.cwd() resolutions on the same surface
Acceptance criteria
Tests that invoke cwd-resolving CLI/API paths run against an isolated workspace (a tmp_path chdir fixture, an explicit repo_path, or a monkeypatched resolver) — not the developer's .codeframe/
The four named tests pass with a real .codeframe/ present in the repo root
A guard prevents regression: an autouse fixture (or conftest check) that fails loudly if a test resolves a workspace outside tmp_path
Production fail-closed behaviour on a broken ledger is unchanged — do not relax pr_commands.py:419-422 to make tests pass
uv run pytest tests/ --ignore=tests/e2e -m "not lifecycle" is green on a machine that has a .codeframe/ directory
Atomic by construction: one developer, one focused session.
Problem
Four tests fail on any branch, including a pristine
maincheckout, purely because the developer's repo-root.codeframe/directory exists:tests/cli/test_v2_cli_integration.py::TestPRCommands::test_pr_mergetests/ui/test_v2_scope_enforcement.py::TestMethodScope::test_read_key_allowed_on_gettests/ui/test_v2_scope_enforcement.py::TestMethodScope::test_write_key_allowed_on_writetests/ui/test_v2_scope_enforcement.py::TestAdminScope::test_admin_key_allowed_on_pr_mergeThey fail with
OperationalError('no such table: workspace')andexit_code == 1.Mechanism.
_check_proof9_merge_gateresolves the workspace from the process cwd:CliRunnerdoes not change cwd, soPath.cwd()is the repo root — which on a developer machine contains a real.codeframe/state.dbleft over from demos/dogfooding. When that DB predates the current schema,list_requirementsraises, the gate correctly fails closed, and the test'sexit_code == 0assertion fails.The production behaviour is right: a broken ledger should block a merge. The defect is that tests read the developer's ambient workspace instead of an isolated one.
Why this matters
.codeframe/, soTest Suite (Unit + E2E)is green onmainwhile the same commit is red locally. This is the inverse of the usual ambient-env trap and it is genuinely disorienting.main→ bisect to.codeframe/) before the change could be cleared.Reproduction
Evidence
codeframe/cli/pr_commands.py:413—get_workspace(Path.cwd())codeframe/cli/pr_commands.py:414— catches onlyFileNotFoundErrorcodeframe/cli/pr_commands.py:419-422— fail-closed on any ledger errorcodeframe/cli/pr_commands.py:61,205— two morePath.cwd()resolutions on the same surfaceAcceptance criteria
tmp_pathchdir fixture, an explicitrepo_path, or a monkeypatched resolver) — not the developer's.codeframe/.codeframe/present in the repo roottmp_pathpr_commands.py:419-422to make tests passuv run pytest tests/ --ignore=tests/e2e -m "not lifecycle"is green on a machine that has a.codeframe/directoryAtomic by construction: one developer, one focused session.