Skip to content

fix(workspace): default an unstated access tier to what the target ca… - #1567

Merged
zfy0701 merged 1 commit into
mainfrom
claude/workspace-gitaccess-default
Aug 28, 2026
Merged

fix(workspace): default an unstated access tier to what the target ca…#1567
zfy0701 merged 1 commit into
mainfrom
claude/workspace-gitaccess-default

Conversation

@zfy0701

@zfy0701 zfy0701 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

…rries

Creating an agent and replacing its workspace disagreed on the default access tier: creation reads gitAccess ?? 'write', while SetAgentWorkspaceBody declared .default('read'). An API caller who omitted the field therefore got write at creation and read on the very next edit — and on GitLab that silently re-clamped the agent's own account from Developer down to Reporter, since the membership level is derived from the workspace tier.

The tier now follows what the target can actually carry, which is the rule creation already applied. An App-backed GitHub repository and a managed GitLab binding both mint credentials, so an unstated tier is write there, and the identity gate holds the caller to it. An anonymous checkout has nothing to push with, so it stays read; an explicit write against one is still refused.

The console always sends the field, so this only changes what an API caller gets, and only toward the tier the same caller would receive from creation.

…rries

Creating an agent and replacing its workspace disagreed on the default
access tier: creation reads `gitAccess ?? 'write'`, while
`SetAgentWorkspaceBody` declared `.default('read')`. An API caller who
omitted the field therefore got write at creation and read on the very
next edit — and on GitLab that silently re-clamped the agent's own
account from Developer down to Reporter, since the membership level is
derived from the workspace tier.

The tier now follows what the target can actually carry, which is the rule
creation already applied. An App-backed GitHub repository and a managed
GitLab binding both mint credentials, so an unstated tier is write there,
and the identity gate holds the caller to it. An anonymous checkout has
nothing to push with, so it stays read; an explicit write against one is
still refused.

The console always sends the field, so this only changes what an API
caller gets, and only toward the tier the same caller would receive from
creation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@agentconnect-md-test agentconnect-md-test Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking findings.

The omitted field now reaches the route instead of being prematurely rewritten to read. For GitHub, the route defaults to write only after finding a live covering installation, passes that resolved tier through the existing user-identity authorization gate, and still forces an anonymous checkout to read while rejecting explicit anonymous write access. For GitLab, the resolved write default is persisted and passed into inline account provisioning, so a workspace edit no longer re-clamps the agent from Developer to Reporter. The OpenAPI description, design contract, and web client type all describe the same behavior, and the focused integration case covers both credential-backed and anonymous GitHub defaults.

git diff --check HEAD^1..HEAD passed. I could not execute the control-plane typecheck or focused integration suite in this isolated checkout because dependencies are absent and pnpm stopped before project code on its unwritable store database; a fresh task-scoped Corepack cache then could not resolve the npm registry. I treated that as a runner verification gap, not a code failure.

sent by review-bot (Codex · gpt-5.6-sol) · open in session

@zfy0701
zfy0701 merged commit 37e6c6c into main Aug 28, 2026
13 checks passed
@zfy0701
zfy0701 deleted the claude/workspace-gitaccess-default branch August 28, 2026 13:50
zfy0701 added a commit that referenced this pull request Aug 28, 2026
* docs(design): the host-neutral git workspace model

The workspace discriminant is the code host today (scratch|github|gitlab),
which bakes a UI notion into the wire, the database, and two independently
written route validations — the root shared by #1561 and #1567. The daemon
never adopted that model: it collapses the arms into git-repo|from-scratch
plus an independent gitCredential on arrival.

This design promotes the daemon's model outward: mode answers "is there a
repository", a credential union answers "who vouches for it". Provenance
is derived server-side by one function shared by creation, replacement,
and a resolve endpoint the console's badges call, so the picker can no
longer disagree with the write path. Provider tiles stay in the console —
they carry lexicon and guidance — but all produce the same payload, and a
"From a Git URL" tile plus GitLab public-project candidates fall out of
the neutral shape. Rollout is readers-first behind a workspace-git-v1
daemon feature so an old daemon never receives an arm it fatals on.

Records the decided rules: provenance fixed at write time and never
auto-upgraded, bare Git rides the anonymous arm on host credentials,
unstated access takes the highest tier the target carries, and a covered
owner's ungranted repository refuses rather than degrading to anonymous.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(design): actor-scoped derivation and the persisted read shape

From review: the shared derivation cannot run the per-user identity gate
without the acting user, so the actor and requested tier join its contract
— provenance stays a function of (orgId, gitRepo), eligibility and ceiling
are the actor's. And the console renders a stored workspace from the
persisted credential in the agent DTO, never the live resolver, or an
owner installing the App would re-badge an anonymous workspace in place —
the auto-upgrade the design rules out. Also notes the gitlab
daemon-feature gates re-key onto the credential provider before dual
encoding begins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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