d705b3c2f3
* fix(mcp): restore live add-branch worktrees * fix(mcp): reject deferred live branch additions * docs(mcp): clarify live branch response contract
83 lines
4.9 KiB
Markdown
83 lines
4.9 KiB
Markdown
# ADR-2026-07-22-runtime-mutable-task-workspace-sources: Runtime-Mutable Task Workspace Sources
|
|
|
|
**Status:** accepted (amended by ADR-2026-07-27-legacy-add-branch-live-rescan)
|
|
**Date:** 2026-07-22
|
|
**Area:** backend, frontend, protocol
|
|
|
|
## Context
|
|
|
|
Task creation can select multiple repositories, but the UI restricts that layout to the worktree
|
|
executor. After launch, only the task-mode `add_branch_to_task_kandev` MCP path can append a source,
|
|
and it is both Git-only and worktree-only. Repository-less tasks may start in one arbitrary host
|
|
folder, but that single `workspace_path` is not a durable mixed-source model. Exposing the existing
|
|
MCP call in the Files panel would therefore report success only for a subset of tasks and could not
|
|
represent arbitrary folders.
|
|
|
|
## Decision
|
|
|
|
Task workspace sources are durable task-scoped attachments, while executor filesystems remain
|
|
materialized views of those attachments.
|
|
|
|
Existing repository identity and Git behavior stay in `task_repositories`. Arbitrary folders use a
|
|
separate `task_workspace_folders` relation rather than migrating every repository consumer to a new
|
|
polymorphic table. Services expose a combined source projection when callers need the complete
|
|
workspace.
|
|
|
|
A batch `AttachWorkspaceSources` service becomes the mutation boundary for HTTP, UI, and the
|
|
`add_workspace_sources_kandev` MCP tool. It validates the entire batch, persists attachments
|
|
transactionally, materializes them through an executor-capability interface, asks agentctl to adopt
|
|
and rescan the effective workspace root, and publishes events only after success. Failure rolls
|
|
back newly created durable records and owned filesystem entries without touching pre-existing
|
|
sources.
|
|
|
|
The legacy `add_branch_to_task_kandev` tool retains its worktree-only live-rescan behavior. It may
|
|
reuse transactional persistence helpers, but it does not use runtime workspace adoption or its
|
|
idle/restart policy. See
|
|
[ADR-2026-07-27-legacy-add-branch-live-rescan](2026-07-27-legacy-add-branch-live-rescan.md).
|
|
|
|
Executor adapters own placement and transport:
|
|
|
|
- local and worktree environments use live references to explicitly trusted host folders and may
|
|
re-root an idle execution into a Kandev-owned task root;
|
|
- Docker, SSH, Sprites, and future remote runtimes materialize repositories in their own workspace
|
|
but do not accept arbitrary host-folder attachments;
|
|
- agentctl owns workspace-root adoption, repository tracker reconciliation, and the file-tree
|
|
refresh boundary common to every runtime.
|
|
|
|
Batch workspace-source attachment is rejected while a turn or tool call is active. An idle
|
|
environment may be restarted when its process working directory cannot be changed safely in place.
|
|
The legacy worktree-only `add_branch_to_task_kandev` compatibility lane may run during its invoking
|
|
turn and updates tracker scope without changing the agent process working directory. Provider
|
|
credentials stay behind the existing backend/executor clone boundary and never enter persisted
|
|
URLs or agent-visible source metadata.
|
|
|
|
## Consequences
|
|
|
|
- The Files panel, `add_workspace_sources_kandev`, and future batch automation use one
|
|
source-attachment contract. The legacy add-branch tool remains an explicit worktree-only
|
|
compatibility exception.
|
|
- Existing repository, diff, PR, and branch consumers keep their current relational model.
|
|
- Arbitrary folders can coexist with Git sources without pretending to be repositories.
|
|
- Runtime backends must implement explicit source materialization and rollback capabilities;
|
|
previously implicit single-repository assumptions become testable interfaces.
|
|
- Folder attachment remains a host-executor capability. Remote/container callers receive an
|
|
explicit unsupported-source error instead of a partial copy with different persistence semantics.
|
|
- Idle-only mutation avoids changing a process working directory during an active command, at the
|
|
cost of making the UI wait for the current turn to finish.
|
|
|
|
## Alternatives Considered
|
|
|
|
1. **Expose `add_branch_to_task_kandev` directly in the Files panel.** Rejected because it is
|
|
worktree-only, Git-only, single-item, and cannot support the requested executor or folder scope.
|
|
2. **Replace `task_repositories` with one polymorphic source table.** Rejected because it forces a
|
|
high-risk migration across mature Git, PR, diff, and session-worktree code for no user-visible
|
|
benefit.
|
|
3. **Treat arbitrary folders as repositories.** Rejected because non-Git folders have no branch,
|
|
diff, PR, or repository identity and would leak invalid assumptions into existing consumers.
|
|
4. **Copy host folders into remote runtimes as snapshots.** Rejected because a detached copy is not
|
|
equivalent to adding the selected live folder and introduces size, retention, and stale-data
|
|
expectations.
|
|
5. **Continuously synchronize host folders with remote runtimes.** Rejected because conflict
|
|
resolution, deletion propagation, watching, and credential boundaries form a separate product
|
|
and reliability problem.
|