plans: fix phase 2 read contract to chunk-rendered

This commit is contained in:
CREDO23 2026-07-24 19:33:59 +02:00
parent 0feccfe3af
commit ea5fbec911

View file

@ -5,35 +5,37 @@
## Objective
A `GitTreeBackend` implementing deepagents' `BackendProtocol` over the Phase-1 `GitRepoService`, so the agent's `ls/read/write/edit/mv/rm`/`glob`/`grep` operate on real files in the workspace git repo instead of faked-over-Postgres rows.
A `GitTreeBackend` implementing deepagents' `BackendProtocol` over the Phase-1 `GitRepoService`, so the agent's `ls/glob/grep`/structure comes from the **real git tree** instead of the `path_resolver` + DB folder walk — **without regressing `read_file`'s chunk-level citations** (see [`00c-shared-contract.md`](00c-shared-contract.md) C2).
## Locked model
- **Same tool interface, new backend.** Implement the exact `BackendProtocol` surface `KBPostgresBackend` implements: `als_info`, `aread`, `awrite`, `aedit`, `aglob_info`, `agrep_raw`, `alist_tree_listing` (return the upstream `WriteResult`/`EditResult`/`FileInfo`/`GrepMatch` shapes — no extra fields).
- **Reads hit git; writes stage in the working tree** (commit happens at end of turn — Phase 3). Reuse the same staging/`Command.update` pattern the current wrappers use, but backed by the working tree rather than the `files` cache + Postgres.
- **`path_resolver` retires for flagged workspaces** — virtual `/documents/...` paths become **real repo paths**. Keep `DOCUMENTS_ROOT` as the repo-relative prefix for continuity.
- **Structure from git; `read_file` content still renders from chunks (v1).** `als_info`/`aglob_info`/`alist_tree_listing`/existence read the git working tree. But `read_file` today renders XML from `Chunk` rows and registers `[n]` citations (`aload_document``render_full_document`) — v1 **keeps that render path** (sourced from the derived chunks, one-way from git) so citations don't regress. `grep` may scan working-tree source directly (its matches are already coarse `<chunk-match>` snippets). See C2.
- **Writes stage in the working tree** (commit at end of turn — Phase 3). Reuse the current staging/`Command.update` pattern, backed by the working tree rather than the `files` cache.
- **`path_resolver` path computation retires for flagged workspaces** — folder walk + collision suffixing is replaced by real repo paths (filename rules still reused, C1). Keep `DOCUMENTS_ROOT` as the repo-relative prefix for continuity.
- Selected via the resolver behind `KB_GIT_ENABLED`.
## Work items
1. New `.../filesystem/backends/git_tree.py``GitTreeBackend(workspace_id, runtime)` implementing `BackendProtocol` over `GitRepoService`.
- Map protocol calls → `GitRepoService` primitives (`aread``read_file`, `aglob_info``list_tree`+`fnmatch`, `agrep_raw`→tree scan, etc.).
- Preserve read rendering behavior the agent expects (document text/XML view) so reads never regress.
- Structure calls → `GitRepoService` primitives (`als_info`/`alist_tree_listing``list_tree`, `aglob_info``list_tree`+`fnmatch`, `agrep_raw`working-tree scan).
- `read_file`/`aread`/`aedit` existence + content: **reuse the existing chunk-render path** (`aload_document`/`render_full_document`) so `[n]` citations are unchanged in v1.
2. Wire into `.../filesystem/backends/resolver.py::build_backend_resolver`: when `KB_GIT_ENABLED` and `workspace_id is not None`, return `GitTreeBackend(workspace_id, runtime)` instead of `KBPostgresBackend`.
3. Gate `path_resolver`/`kb_postgres` usage behind the flag (keep both paths compilable during rollout).
## Tests
- For a seeded repo, `ls`/`read`/`glob`/`grep` return results **identical** to `KBPostgresBackend` for the same content (golden comparison).
- `read` of a nested path returns file content; `glob("**/*.md")` lists the tree; `grep` respects the existing match caps.
- For a seeded repo, `ls`/`glob`/`grep`/`list_tree` return results **identical** to `KBPostgresBackend` for the same content (golden comparison).
- `read_file` of a nested path returns the rendered document view and registers the **same `[n]` citations** as the Postgres backend (no citation regression).
- Resolver returns `GitTreeBackend` only when the flag is on; falls back to `KBPostgresBackend`/`StateBackend` otherwise.
## Out of scope
- End-of-turn commit → Phase 3. Index refresh → Phase 4.
- Desktop-local (`MultiRootLocalFolderBackend`) path — unchanged.
- **Raw-git-blob reads with per-document citations** — deferred (C2); revisit with the `raw/`+`wiki/` content model.
## Open questions
## Resolved (see [`00c-shared-contract.md`](00c-shared-contract.md))
1. Read rendering: serve raw markdown from git vs. reproduce the current rendered-document view (citations). Confirm what the agent contract needs.
2. Whether `grep`/`glob` scan the working tree directly or use git plumbing (`git grep` semantics via dulwich) for large repos.
- **Read rendering:** structure from git, `read_file` content keeps the chunk-render + citation path in v1 (C2).
- **glob/grep source:** working-tree scan via `GitRepoService` (dulwich plumbing optimization deferred).