phase: 102_extensionless_filenames
Build and Push Containers / build-and-push-app (push) Successful in 1m38s
Build and Push Containers / build-and-push-db (push) Successful in 13s

All verification complete — every gate green, no defects found in previously completed work.

**Phase 102 final verification pass — report**

Verified (all three task files present in `complete/`; working-tree implementation matches D1–D5 design):
- `match_extension` choke point in `app/rag/importer.py` (walk + `formats` counter), `doc_format` name-token badge in `app/api/docs.py`, config/`.env.example` docs, fixture `tests/fixtures/extensionless_kb/`, integration + E2E suites — all present and correct
- Completion criteria: end-to-end sync (✓ integration + E2E), case matrix incl. `mydockerfile`/`Dockerfile.dev`/`.dockerfile` exclusions (✓ unit), `formats=dockerfile:1` not `unknown` (✓ log-line assertion), badge `dockerfile`/`containerfile` + `text` fallback + suffixed unchanged (✓ unit/integration/E2E), prune-on-token-removal (✓ `pruned==2`), suffixed-path rule byte-identical (✓ single-line swap, existing cases untouched)

Test / lint results (exact commands):
- `uv run pytest --cov=app --cov-report=term-missing` → 2084 passed, **99%** coverage (>90% gate)
- `uv run pytest tests/e2e/test_extensionless_import.py -v --no-cov` → 2 passed, isolated, DB up
- Regressions isolated: `test_import_documents` 3✓, `test_import_extensions_env` 2✓, `test_quadlet_jinja_import` 4✓, `test_document_viewer` 7✓, `test_kb_tree` 8✓
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings

Notable: commit intentionally not made (harness commits the phase); 102's task files already sit in `complete/`, overview stays in `todo/` for the harness.
Next pending phases: 98, 99, 103, 104, 105 (numeric next after 102: `103_suggestions_session_openers`).
This commit is contained in:
2026-09-12 15:56:43 -04:00
parent 4dbac1660a
commit 3b2dea5685
29 changed files with 1276 additions and 11 deletions
+40 -1
View File
@@ -2,7 +2,9 @@
Python side:
* ``doc_format`` — format from the path suffix (incl. ``.markdown`` and the
no-suffix fallback);
no-suffix fallback) + the phase-102 extensionless name-token rule
(``Dockerfile`` → ``dockerfile`` with a configured token, suffixes still
unconditional, no-arg calls byte-identical to the suffix-only rule);
* the content endpoint's 200/404 mapping — tested WITHOUT a database by
stubbing the session via FastAPI's dependency override (unknown pairs and
traversal-style paths map to 404 ``{detail: "document not found"}``;
@@ -74,6 +76,43 @@ def test_doc_format_from_suffix(path: str, expected: str) -> None:
assert doc_format(path) == expected
def test_doc_format_no_args_extensionless_falls_back_to_text() -> None:
"""The no-arg contract: default ``extensions=frozenset()`` keeps the
pre-phase-102 result for every path — an extensionless name that LOOKS
like a configured token still badges ``text`` without the token set."""
assert doc_format("Dockerfile") == "text"
assert doc_format("README") == "text"
#: A token set in the dotted form ``import_extension_set`` passes it.
_TOKEN_EXTS = frozenset({".md", ".dev", ".dockerfile", ".containerfile"})
@pytest.mark.parametrize(
("path", "extensions", "expected"),
[
# Name-token branch (phase 102): suffix-less name in the set.
("services/api/Dockerfile", _TOKEN_EXTS, "dockerfile"),
("DOCKERFILE", _TOKEN_EXTS, "dockerfile"), # case-insensitive name
("Containerfile", _TOKEN_EXTS, "containerfile"),
# Suffix precedence: display never depends on the import list.
("Dockerfile.dev", _TOKEN_EXTS, "dev"), # suffixed → its suffix rules
("readme.rst", _TOKEN_EXTS, "rst"), # out-of-scope suffix still badges
("notes/README.dev", _TOKEN_EXTS, "dev"),
("dockerfile.bak", _TOKEN_EXTS, "bak"), # lookalike → suffix, not name
("kubernetes.md", frozenset(), "md"), # empty set: suffix unconditional
# Extensionless names NOT in the set fall back to text — exact
# name only, no partial names.
("README", _TOKEN_EXTS, "text"),
("mydockerfile", _TOKEN_EXTS, "text"),
],
)
def test_doc_format_with_token_set(
path: str, extensions: frozenset[str], expected: str
) -> None:
assert doc_format(path, extensions) == expected
# ---------------------------------------------------------------------------
# Content endpoint mapping — stubbed session, no database required
# ---------------------------------------------------------------------------