Skip to content

fix(web): route uninitialised-project refusals through the error screen - #334

Merged
cvince merged 1 commit into
feat/portabilityfrom
claude/web-refusal-url-systemic
Aug 28, 2026
Merged

fix(web): route uninitialised-project refusals through the error screen#334
cvince merged 1 commit into
feat/portabilityfrom
claude/web-refusal-url-systemic

Conversation

@cvince

@cvince cvince commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

The systemic class, on the three paths a run actually proved.

console.error(); process.exit(1) in a guard never throws → the surrounding catch never runs → displayErrorAndExit never serves its page. rotateCommand.ts documents this class and its own fix; it was never applied elsewhere.

command fix
checkout throw into the catch that already routes correctly
decrypt same
branch not inside a try, so it calls displayErrorAndExit directly — that function reads web mode itself, so no flag plumbing

Framed against the invariant — a URL reaches the caller. Nothing asserts loopback, so moving the renderer to Keep will not rewrite these tests.

Two commands I nearly reported as broken, and did not

The control caught both:

  • kickkick --web never reaches a guard; Commander rejects it first with missing required argument 'email'.
  • checkoutcheckout --web with no branch name does the same. The first draft of this file ran exactly that, saw output with no URL, and would have filed a violation that does not exist. Passing somebranch reaches the real guard, which was genuinely broken and is fixed here.

Both failed on "did it reach its refusal", not on "was there a URL". A test that asserts an absence without first proving the command arrived is a test that invents defects — this file would have invented two.

transport, edit and org are absent for the opposite reason: their runs get past the guard into the auth path and do hand back a URL. A source sweep lists them; running them clears them.

Observed, not inferred

$ capy checkout somebranch --web
  No keep.lock file found. Run capy first to initialize the project.

  What went wrong is in your browser:
  http://127.0.0.1:49657/s/b1MgZXtmUTkd3O6r5hynn0Mg2NRkc9tfHoQ7wyk1Otg

Suite: 1847 pass, 0 fail.

The systemic class, on the three paths a run actually proved. `console.error();
process.exit(1)` in a guard never throws, so the surrounding catch never runs,
so displayErrorAndExit never serves its page. rotateCommand documents this
class and its own fix; it was never applied elsewhere.

  checkout  throw into the catch that already routes correctly
  decrypt   same
  branch    not inside a try, so it calls displayErrorAndExit directly —
            that function reads web mode itself, so no flag plumbing

Framed against the invariant: a URL reaches the caller. Nothing here asserts
loopback, so moving the renderer to Keep does not rewrite these tests.

TWO COMMANDS I NEARLY REPORTED AS BROKEN AND DID NOT, because the control
caught them:

  kick      `kick --web` never reaches a guard — Commander rejects it first
            with `missing required argument 'email'`.
  checkout  `checkout --web` with no branch name does the same. The first
            draft ran exactly that, saw output with no URL, and would have
            filed a violation that does not exist. Passing `somebranch`
            reaches the real guard, which was genuinely broken and is fixed
            here.

Both failed on "did it reach its refusal", not on "was there a URL". A test
that asserts an absence without first proving the command arrived is a test
that invents defects, and this file would have invented two.

transport, edit and org are absent for the opposite reason: their runs get
past the guard into the auth path and do hand back a URL. A source sweep lists
them; running them clears them.

Observed, not inferred:
  $ capy checkout somebranch --web
    No keep.lock file found. Run capy first to initialize the project.
    What went wrong is in your browser:
    http://127.0.0.1:49657/s/...

Suite: 1847 pass, 0 fail.
@cvince
cvince merged commit 8aa98b2 into feat/portability Aug 28, 2026
2 checks passed
@cvince
cvince deleted the claude/web-refusal-url-systemic branch August 28, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant