9.9 KiB
status, system, requirements
| status | system | requirements | |
|---|---|---|---|
| draft | workspaces |
|
Worktree Base Refresh System Design
Purpose and boundaries
The workspace system owns the repository checkout, remote state, and base ref
used to create a worktree. This design makes repositories.pull_before_worktree
an admission gate for new and recreated worktrees.
The task system continues to own session launch state and error presentation. It consumes preparation errors through the existing launch-failure contract in Task Launch Failure Recovery. The integration system continues to own provider credentials. The executor continues to own credentials and SSH configuration inherited from its runtime.
This design does not refresh a worktree that Kandev can reuse without recreation. It also does not change Git commands that an agent runs after launch.
Requirement mapping
| Requirement | Design section |
|---|---|
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.1 |
Refresh policy |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.2 |
Refresh routing |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.3 |
Failure and recovery |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.4 |
Base-ref selection |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.5 |
Base-ref selection |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.6 |
Multi-repository launch |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.7 |
Launch-error projection |
AC-WORKSPACES-WORKTREE-BASE-REFRESH-001.8 |
Empty remote exception |
Components and responsibilities
internal/orchestrator/executorresolves every task repository and selects the refresh route that matches its provider and task Git credential policy. It passesPullBeforeWorktree,RemoteSyncHandled, and a provider-authenticated refresh callback to the lifecycle layer. The callback is not invoked until a worktree must be materialized or recreated.internal/repoclone.Clonerperforms a strict refresh for a Kandev-managed provider checkout when provider credentials belong to the backend refresh boundary.RefreshWorkspaceRepositoryWithCredentialRequestbinds the fetch to the exact workspace, task, session, and repository scope.internal/worktree.Managerperforms strict non-interactive fetch and base-ref selection when the checkout uses the host or executor Git route. It creates no worktree until the required sync and ancestry checks succeed.internal/agent/runtime/lifecyclepropagates repository preparation errors without starting the agent runtime.- The task launch-failure projection stores and renders the resulting bounded, credential-safe error. This design does not add a parallel workspace error store.
Data and contracts
repositories.pull_before_worktree remains the persisted user policy. No
schema change is required.
The existing worktree preparation fields have these contracts:
| Field | Contract |
|---|---|
PullBeforeWorktree |
A required remote refresh remains to be completed before base-ref selection. |
RemoteSyncHandled |
A strict provider-authenticated refresh completed for the exact checkout. The worktree manager must not run a second unauthenticated fetch. |
RefreshRepository |
An optional exact-scope refresh callback. Lifecycle invokes it only when creating or recreating a worktree; valid reuse bypasses it. |
RemoteSyncHandled is valid only after a successful strict refresh. A
best-effort fetch or a failed refresh cannot set it.
Refresh policy
When PullBeforeWorktree is false, base-ref resolution keeps its offline local
behavior. This path does not claim that the checkout contains current remote
state.
When PullBeforeWorktree is true, worktree materialization requires one
successful refresh. A caller cannot convert a refresh error into a warning and
local ref. The rule applies to initial launch and to resume whenever Kandev
creates or recreates a worktree. A valid reusable worktree is returned before
the callback is invoked.
Refresh routing
The executor resolves one of two refresh routes before lifecycle preparation:
- A Kandev-managed provider route supplies a callback that calls the strict
repoclonerefresh with the exact credential request. The lifecycle layer invokes it only when it must materialize or recreate a worktree. On success, worktree creation clearsPullBeforeWorktreeand setsRemoteSyncHandled. - A host or executor route leaves
PullBeforeWorktreeset. The worktree manager uses the reconciledoriginURL and the non-interactive host Git environment. This includes an executor-inherited GitHub checkout whose origin uses the protocol selected by the hostghconfiguration.
When a managed checkout carries a pull request number, the strict refresh also
fetches refs/pull/<N>/head into a local origin/pr/<N> remote-tracking ref.
Worktree creation uses that ref for the checkout branch, including fork pull
requests, without a second unauthenticated fetch.
Provider selection must follow the existing task Git credential policy. A managed GitHub workspace uses the backend-managed credential route. An executor-inherited GitHub workspace must not replace the reconciled SSH origin with a managed HTTPS origin.
The plugin-provider strict-refresh behavior remains the model for exact credential scope. GitLab and Azure DevOps keep their existing provider-specific credential resolution.
Base-ref selection
After a successful fetch, the worktree manager compares the local base L
with the fetched remote base R:
| Relationship | Start ref | Reason |
|---|---|---|
R contains L |
R |
Includes all local commits and current remote commits. |
L contains R |
L |
Preserves local-only commits and includes current remote commits. |
| Neither contains the other | Error | The refs diverged and either choice would omit commits. |
| Ancestry cannot be proven | Error | Kandev cannot prove that the start ref is safe. |
A successful fast-forward pull normally produces the first or second state. If pull fails after fetch, the same table selects the safe ref. The manager does not reset, rebase, merge, or delete a branch.
pullBaseBranch, resolveLocalBaseRef, and
pullCurrentBranchOrFallback return errors to their callers. The errors retain
Git failure classification but exclude tokens, credential helper output, and
secret-bearing URLs.
Empty remote exception
An authenticated remote advertisement with zero refs is not a stale local fallback. It is the typed empty-remote state defined by Empty Remote Repository System Design.
This exception creates only the marked local baseline. It does not permit a launch-time remote write or relax any authentication, network, timeout, cancellation, missing-branch, or ancestry error.
Multi-repository launch
The executor resolves and prepares repository specs before agent startup. If a required refresh fails for one spec, lifecycle preparation returns an error and does not start the runtime. The error carries stable repository identity and a safe display name so same-provider sibling repositories remain distinguishable.
Preparation can leave an already refreshed checkout on disk. This state is safe and retryable. A later launch performs the required checks again. Kandev does not report a partial task launch because no agent process started.
Launch-error projection
The executor returns required-refresh errors through its existing launch failure path. The task system stores the active error in the current typed summary and renders it on desktop and mobile after reload. The generic launch failure category is sufficient unless implementation evidence shows that a distinct category enables a safe recovery action.
The bounded detail names the repository and failure class. It does not include credentials, tokens, raw authenticated URLs, or unrestricted Git output. Retry uses the normal task launch action after the user corrects network, SSH, or credential configuration.
Failure and recovery
- Fetch authentication, network, timeout, cancellation, and Git command errors stop required preparation.
- A missing fetched remote base on a non-empty remote stops preparation. It cannot fall back to a local ref when refresh is required.
- A failed ancestry probe stops preparation.
- A divergent base stops preparation and preserves both refs.
- Disabling pull-before-worktree is the explicit offline opt-out. Kandev does not disable it automatically after a failure.
- Retrying task launch reruns remote refresh and base-ref selection.
Security
Managed refresh uses the provider credential boundary and exact task, session, and repository scope. Executor refresh uses only credentials available to the selected host or executor route. Neither route copies a provider token into an error, progress event, or log field.
Git remains non-interactive. GIT_TERMINAL_PROMPT=0, batch-mode SSH, bounded
command contexts, and Git subprocess admission prevent a hidden prompt from
blocking task launch.
Observability
The existing sync progress callback reports a running event and then either a completed event or a failed event. A failed event contains the bounded failure class and repository identity, not a fallback-ref success message.
Structured logs record the repository ID, task ID, session ID, provider, configured transport, refresh route, and failure class. Logs do not record credential material or secret-bearing remote URLs.