chore(agent): track .agent/ planning tree in git
Remove the blanket .agent/ gitignore so the phase roadmap, user stories, reports, and PLAN.md are versioned with the code. Only runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log) remain ignored. Update AGENTS.md git protocol rule to match.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Phase 47 — Import quadlet + jinja files
|
||||
|
||||
**Source:** `TODO.md` L10–L11 — "Add '.container', '.network', '.volume' and other quadlet files to the list of allowed/parsed files" / "Add '.j2' jinja files to the list of allowed/parsed files"
|
||||
**Story:** `.agent/user_stories/quadlet-jinja-import.md`
|
||||
**Context:** A9 (LOCKED, revised 2026-08-21): default import formats `md, markdown, txt, yaml, yml, json, py`; `app/config.py::_ALLOWED_IMPORT_EXTENSIONS` bounds `BOR_IMPORT_EXTENSIONS` (narrow-only); `app/rag/chunker.py::_FORMAT_CHUNKERS` maps suffix → chunker (unknown suffix → `chunk_text` fallback). The owner-locked revision (2026-08-27, roadmap R1): ten new formats join the allowed **and** default set — the full Podman quadlet family (`container, network, volume, image, pod, kube, swap, os, endpoint`) plus `j2` — chunked as plain text.
|
||||
|
||||
## Objective
|
||||
Quadlet unit files and Jinja templates are indexed like any other A9 format: allowed + default in config, dispatched to plain-text chunking, and provable end to end (import → catalog → viewer → retrieval).
|
||||
|
||||
## Dependencies
|
||||
- `46_mobile_hamburger_nav` (todo) — sequential only (no shared files: this phase is `app/` + `scripts/` + tests + fixtures + docs).
|
||||
- `38_local_directory_sources` / `28_git_based_sources` (complete) — the import path the new formats ride (`import_sources` / sync).
|
||||
- `02_story_import_documents` (complete) — the A9 format machinery (walk, title, delta, prune) the new formats inherit unchanged.
|
||||
|
||||
## Tasks
|
||||
1. `01_config_formats.md` — allowed + default extension sets, `.env.example`, config unit tests.
|
||||
2. `02_chunker_dispatch_fixtures.md` — chunker dispatch for the ten suffixes + the fixture files.
|
||||
3. `03_importer_integration.md` — importer walk/delta/prune parity + integration test.
|
||||
4. `04_quadlet_e2e_and_docs_commit.md` — story E2E + README + PLAN A9 revision note + commit.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit: `test_config.py` (allowed set contains all ten; the default CSV carries them after the original seven; the env validator accepts the new names and still rejects unknown ones; `import_extension_set` dotted form); `test_chunker.py` (dispatch for **every** new suffix → `chunk_text` semantics: a quadlet TOML fixture and a jinja fixture chunk under `HARD_MAX_CHARS`, paragraph packing behaves); `test_importer.py` (a directory walk with the new files indexes them; hidden dirs + exclusions still filter).
|
||||
- Integration: import over a temp tree with quadlet+j2 files → `documents` + `chunks` rows, delta re-import idempotent.
|
||||
- Coverage: **>90%** on `app/` — config/chunker/importer changes fully covered.
|
||||
- E2E (mandatory, A16): `tests/e2e/test_quadlet_jinja_import.py`, run in isolation.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] A default-extensions import indexes `.container` / `.network` / `.volume` / `.image` / `.pod` / `.kube` / `.swap` / `.os` / `.endpoint` / `.j2` files (fixture-proven); no env configuration needed.
|
||||
- [ ] The Sources table lists them; the viewer shows a `.container` file's TOML content with the stem as title.
|
||||
- [ ] A question containing a `.j2` sentinel is non-deflected with the `.j2` doc as a source chip (A8 FTS-OR honesty gate).
|
||||
- [ ] `BOR_IMPORT_EXTENSIONS` still rejects truly unknown extensions (validator intact).
|
||||
- [ ] README + `.env.example` + PLAN.md A9 revision note record the extended set.
|
||||
- [ ] `uv run pytest` green; `uv run pytest --cov=app --cov-report=term-missing` >90%.
|
||||
- [ ] `uv run pytest tests/e2e/test_quadlet_jinja_import.py -v --no-cov` green in isolation (DB up).
|
||||
- [ ] Regression E2E suites green in isolation: `test_import_documents.py`, `test_sync_button.py`, `test_git_sources_admin.py`.
|
||||
- [ ] `uv run ruff check . && uv run pyright` clean.
|
||||
- [ ] One `--no-gpg-sign` commit; phase dir moved to `.agent/phases/complete/`.
|
||||
|
||||
## Locked decisions
|
||||
- **Owner-locked revision (2026-08-27, roadmap R1):** A9's format set is **revised** — ten formats added to the allowed + default set (the full quadlet family + `j2`); plain-text chunking (no TOML/Jinja-aware splitters); recorded as a PLAN.md A9 revision note with owner permission — a recorded revision, not a silent deviation (AGENTS.md rule 3).
|
||||
- **A9 invariants kept:** hidden (dot) directories still skipped; the exclusion list unchanged; narrow-only `BOR_IMPORT_EXTENSIONS` validator; sha256 delta / prune unchanged; `HARD_MAX_CHARS` (1200) honored by the `chunk_text` dispatch.
|
||||
- **A17 honoured** — one atomic commit.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Task 04 — Quadlet/jinja E2E + docs (README, PLAN A9 revision) + commit
|
||||
|
||||
**Phase:** `47_quadlet_jinja_import` · **Source:** `TODO.md:10–11` — "Add '.container', '.network', '.volume' and other quadlet files to the list of allowed/parsed files" / "Add '.j2' jinja files to the list of allowed/parsed files"
|
||||
**Story:** `.agent/user_stories/quadlet-jinja-import.md`
|
||||
|
||||
## Objective
|
||||
Prove the story end to end (import → catalog → Sources table → viewer → FTS retrieval), record the A9 revision in the docs, run the regressions, and commit the phase.
|
||||
|
||||
## Work
|
||||
1. `tests/e2e/test_quadlet_jinja_import.py` (new) — mock-only, DB up, per the story's Playwright Mapping Rule (the import happens out-of-band against the session mock, exactly like `test_import_documents.py`: truncate the KB, `import_sources([FIXTURES], LLMClient(settings))` in a thread — reuse that file's helpers/pattern; the task-02 fixtures are already in the tree):
|
||||
- `test_quadlet_and_jinja_indexed` — after the module import, `GET /api/docs` lists `quadlet/compose.container`, `quadlet/lan.network`, `quadlet/cache.volume`, `templates/deploy.j2`, each with a non-zero chunk count and the stem as title;
|
||||
- `test_sources_table_shows_them` — admin: `/sources.html` renders rows for the four files (path links present, `.doc-link`);
|
||||
- `test_container_content_viewable` — open `compose.container` from the Sources table (modal, phase 26): the content area contains the `[Container]` section text and the `RESE-QUADLET-SENTINEL-77aa` sentinel; the title is the stem (`compose`);
|
||||
- `test_jinja_retrievable_not_deflected` — ask a question containing `RESE-JINJA-SENTINEL-33dd` (the A8 gate: an FTS hit among the candidates keeps it honest-positive — LOW requires **zero** FTS hits): the brain bubble is **not** `.is-deflected` and a source chip names `templates/deploy.j2` (the mock's answer shape is deterministic; the assertion is on the gate + the chips, not the prose).
|
||||
- module fixture: truncate `documents`/`chunks`/`query_log` per test module (the house E2E pattern) and re-import — note: this file's re-import changes the KB for the session; it is run in **isolation** (A16), so no cross-suite interference.
|
||||
2. **Docs:**
|
||||
- `README.md` — wherever the import format list is documented (the "Import & update" section mirrors PLAN §11 / A9), extend it with the ten new formats (the 2026-08-27 A9 revision, plain-text chunking);
|
||||
- `.agent/PLAN.md` — **the only PLAN edit in this phase** (owner-locked revision R1): in the §2 anchors table, the A9 row's decision text gains the extension — append to the A9 row (keep the original wording, mark the revision in the row's notes/status or in a revision note under the table, the established style): "**A9 revision (phase 47, owner permission 2026-08-27):** the format set extends with the Podman quadlet family (`container, network, volume, image, pod, kube, swap, os, endpoint`) and `j2` (Jinja templates) — plain-text chunking (`chunk_text`), owner: `TODO.md` L10–L11. The narrow-only `BOR_IMPORT_EXTENSIONS` rule and the hidden-dir/exclusion invariants are unchanged." Update PLAN §5's chunking-policy format line and §11's workflow line to list the extended set (same note style). Touch **nothing else** in PLAN.md.
|
||||
3. Regression pass (isolation runs): `test_import_documents.py` (task 02's count-constant update must hold — the tree now has four more files), `test_sync_button.py`, `test_git_sources_admin.py`.
|
||||
4. `uv run pytest` green; `uv run pytest --cov=app --cov-report=term-missing` >90%; `uv run ruff check . && uv run pyright` clean.
|
||||
5. Commit (Conventional Commits, `--no-gpg-sign`), e.g. `feat(import): index quadlet unit files and jinja templates (A9 revision)`, staging this phase's files **including the force-added `.agent/PLAN.md`** (AGENTS.md rule 8) and the phase dir move `.agent/phases/todo/47_quadlet_jinja_import/` → `.agent/phases/complete/`.
|
||||
|
||||
## Testing & Quality
|
||||
- E2E: `uv run pytest tests/e2e/test_quadlet_jinja_import.py -v --no-cov` green in isolation.
|
||||
- Coverage: **>90%** on `app/` (tasks 01–03 carry it).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] The story E2E suite passes in isolation (all four tests); the three regression suites pass in isolation.
|
||||
- [ ] README + `.env.example` (task 01) + PLAN.md (A9 row + §5 + §11) record the extended set; no other PLAN change.
|
||||
- [ ] One atomic `--no-gpg-sign` commit; phase dir moved to `.agent/phases/complete/`.
|
||||
Reference in New Issue
Block a user