Files
brain-of-reese/.agents/user_stories/local-directory-sources.md
T
ducoterra dbf2af26c6 refactor(agents): migrate .agent/ planning tree to .agents/
Standardize on the .agents/ directory (shared with project skills):
phases/, user_stories/, reports/, screenshots/, validate.sh, and
phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves
history; runtime artifacts move alongside).

Updates every reference in AGENTS.md, README.md, .gitignore, app
docstrings, and test story headers. Historical KB content in data/
and the runtime pipeline.log transcript are left untouched.
2026-09-05 10:57:07 -04:00

50 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Story: Local directory sources
**Phase:** `38_local_directory_sources` · **E2E:** `tests/e2e/test_local_directory_sources.py`
## Narrative
As **the admin (owner)**, some of my documents live in plain directories
that are **not git repos** — today the only way to index them is the CLI's
`--source` flag, which the web app's Sync path ignores. I want to **add an
existing local directory as a source** from the same admin page as the git
sources, and have the Sync button and `import_docs` import it alongside the
git checkouts.
- **Given** I am signed in as admin, and `~/Notes` is a plain (non-git)
directory
- **When** I add it on the sources page and click Sync
- **Then** the directory is walked and imported together with the git
checkouts in one run (pruning over the union), and a missing directory
fails the run loudly instead of importing a partial KB.
## Acceptance criteria
1. Migration 0007: `git_sources.kind TEXT NOT NULL DEFAULT 'git'` (check:
`git`|`local`) + `git_sources.path TEXT NULL` (unique; non-null only for
local) — reversible, up/down integration-tested (the 0004–0006 pattern).
2. The admin API (phase 35) accepts `kind`: `git` rows validate `url`
exactly as today; `local` rows require `path` (trimmed, expanded,
absolute, existing directory on the server → else 422 naming the path);
409 on duplicate (per kind); GET rows carry `kind` + `path` (env
fallback rows are git-only).
3. The sync pipeline and `import_docs` resolve DB **git + local** rows
together (git → clone/pull; local → direct directory walk; a missing
local dir aborts the run before importing, with the path named);
`--source` still wins; `BOR_GIT_SOURCES` stays a git-only fallback;
both-empty fails loudly ("no sources configured").
4. The page: a second "Local directory" add form (labeled path input,
inline error, never-stale button per §7.4); list rows show a kind badge
(Git/Local, distinguishable by more than color); the hint says Sync
imports git checkouts and local directories together (union prune).
5. README: the two source types + add-time validation + "the DB is the
local-source registry"; no new env var.
6. Unit + integration green, `app/` coverage >90%, story E2E green in
isolation, ruff + pyright clean, one `--no-gpg-sign` commit.
## Playwright Mapping Rule
`tests/e2e/test_local_directory_sources.py` — one story, one file, run in
isolation: the admin adds a temp local directory → it appears with the
Local badge; a missing path gets an inline error; Sync imports its fixture
file (visible via `GET /api/docs`); deleting the file and syncing again
prunes it; removing the row removes it from the list.