phase: 119_name_signal_read_chips
Build and Push Containers / build-and-push-app (push) Successful in 2m1s
Build and Push Containers / build-and-push-db (push) Successful in 18s

All verification complete. Final report:

**Phase 119 final verification pass — all criteria verified, one stale pin fixed.**
- Verified implementation of all 6 tasks: D1 component name-hit rule (`name_hit` flag, titles never matched, retired length tie-break), D2 `BOR_NAME_HIT_BONUS` (0.005 default, 0 = byte-identical kill switch, negative fails startup, selection-layer only, `eval_retrieval` `suggested:` line), D3 suggested-folder lines (after `SUGGEST_INTRO`, before first block), D4 cite-discipline `SUGGEST_INTRO` sentence (PERSONA/LOW/`TOOLS_SECTION` byte-pins intact), D5 `done.sources` = read docs only (frontend no-op on empty confirmed), D6 mock `repeat your folder map` echo + new suite + telemetry.
- Battery (replica restored per skill, fingerprint docs=1000/chunks=8866 verified, `eval_retrieval --from-file tests/fixtures/retrieval_battery.txt` re-run): **GATE PASS** — gitea README #4 in suggested top-5, forgejo 5/5 (README #1), gateway README in top-5 (#4), qwen3.8-27b quadlets top-5, Mongolia HIGH/fts=5 unchanged.
- New E2E in isolation: `4 passed` ×2 (deterministic). All 27 modified E2E suites in isolation: 26 green; **1 stale pin fixed** — `test_source_chip_quality.py` durable-record order pin pre-dated the D1 re-rank (`aliases` stem sub-component name-hits `ssh_aliases.txt`, deterministically lifting `backups.md` over `kubernetes.md`; probe-verified 0.016277 vs 0.016036, 4/4 stable) — re-pinned with the phase-119 rationale; suite green ×2.
- Gates: `uv run pytest --cov=app --cov-report=term-missing` → **2547 passed, app coverage 99%** (>90%); `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors.
- Completion criteria: 1 ✅ (battery, recorded), 2 ✅ (folder lines; block/LOW byte-identical pins green), 3 ✅ (read-only chips, zero-read chips nothing, related row + durable record untouched — unit+E2E agree), 4 ✅ (all green), 5 → commit/phase-move left to the harness per pass rules (nothing committed).
- Deviations: battery output + real-model telemetry recorded in `.agents/reports/119_name_signal_read_chips/task06_battery_and_e2e.md` and `TOOL_CALLING_TESTING.md` §11 (task files in `complete/` are immutable to this pass); gateway canonical doc at #4 vs overview's #3 was already documented at task 06 (containment gate met).
- Next pending phase: **none** — `todo/` holds only phase 119.
This commit is contained in:
2026-09-16 15:50:48 -04:00
parent 795fb56425
commit a5b63f83ad
89 changed files with 4377 additions and 655 deletions
+49 -14
View File
@@ -132,21 +132,30 @@ _KB_INTRO = (
)
#: The ``<documents>`` section's start-here intro (phase 118, task 03 —
#: the owner directive, TODO L3): the seeded blocks are the SUMMARIES of
#: the top-ranked documents for the question, opt-in starting points —
#: start here if one seems right; ``read`` the document's combined
#: ``source/path`` to add its FULL content before answering specifics
#: (the full text is NOT in the prompt until you read it); cite the
#: document(s) you used, by path. Rendered BEFORE the first block, only
#: when at least one block is present. The ``<documents>`` tag and the
#: per-block ``<document>`` markup stay byte-stable around it (the E2E
#: mock's block parser and the ``read``-tool copy key off both).
#: the owner directive, TODO L3; phase 119, task 04, LOCKED A5 — the
#: final sentence re-cut to the cite discipline): the seeded blocks are
#: the SUMMARIES of the top-ranked documents for the question, opt-in
#: starting points — start here if one seems right; ``read`` the
#: document's combined ``source/path`` to add its FULL content before
#: answering specifics (the full text is NOT in the prompt until you
#: read it); cite ONLY the documents you read (or the suggested document
#: you answered from without reading it) — never one you neither read
#: nor used. The discipline sentence closes the phase-119 live
#: confabulation — the model's "Docs used:" line cited a file it never
#: read, confabulated from the suggestion blocks sitting in context —
#: and retires the phase-118 "cite the document(s) you used, by path"
#: sentence. Rendered BEFORE the first block, only when at least one
#: block is present. The ``<documents>`` tag and the per-block
#: ``<document>`` markup stay byte-stable around it (the E2E mock's
#: block parser and the ``read``-tool copy key off both).
SUGGEST_INTRO = (
"The blocks below are the summaries of the top-ranked documents for "
"your question — start here if one seems right to you: call `read` "
"with that document's combined `source/path` to add its full content "
"before answering specifics (its full text is not in the prompt until "
"you read it). Cite the document(s) you used, by path."
"you read it). Cite only the document(s) you read — or, if you "
"answered from a suggested summary without reading it, cite that "
"suggested document — never a document you neither read nor used."
)
#: The ``<tools>`` instructions section — **HIGH prompt only** (phase 37,
@@ -416,6 +425,7 @@ def build_high_prompt(
documents: Sequence[Document],
notes: Sequence[str] | None = None,
kb_overview: str | None = None,
folder_lines: Sequence[str] = (),
) -> str:
"""Grounded turn: locked persona (+ steering, + KB overview) + the
top-ranked documents' SUMMARY blocks + the ``<tools>`` instructions
@@ -423,7 +433,8 @@ def build_high_prompt(
``grep`` shapes; phase 72: the document-identity contract up front;
phase 118, LOCKED A6 re-revising A7: the ``<documents>`` section
seeds SUMMARIES, never full texts — full text enters the context
only through the capped ``read`` tool).
only through the capped ``read`` tool; phase 119, LOCKED A4: the
suggested-folder context lines, below).
Section order: ``<relevance>`` → ``<knowledge_base>`` → ``<tuning>``
→ ``<documents>`` → ``<tools>``; empty steering/overview omit their
@@ -435,11 +446,28 @@ def build_high_prompt(
start-here :data:`SUGGEST_INTRO` line (before the first block — the
phase-15 ``_STEERING_INTRO`` / phase-31 ``_KB_INTRO`` precedent): the
blocks are the summaries of the top-ranked documents, ``read`` adds
the full text, and the answer cites the document(s) used by path.
This is NOT the reverted phase-72 in-context reminder (that copy
the full text, and the answer cites only the documents it read (or
the suggested document it answered from without reading — the
phase-119 cite discipline, LOCKED A5; the phase-118 "cite what you
used, by path" sentence is retired). This is NOT the reverted
phase-72 in-context reminder (that copy
taught the seed documents as already-read context; this one teaches
the summary-as-starting-point contract the A6 re-revision requires).
*folder_lines* (phase 119, D3, LOCKED A4): the suggested-folder
context lines (``app.rag.agent.suggested_folder_lines``) — the
direct children of each suggested document's parent folder, so the
model ``read``s the right file in round 1 instead of walking the
``ls`` drill-downs. When blocks are present AND the lines are
non-empty, the ``<documents>`` body is ``SUGGEST_INTRO``, then the
folder lines (each on its own line, immediately after the intro
line), a blank line, then the first ``<document>`` block. They are
PLAIN lines — no new markup/tag (the E2E mock keys off the
``<documents>`` marker and the LAST block's tail, so the lines must
never land after a summary). Empty *folder_lines* ⇒ the phase-118
build is byte-identical (pinned in
``tests/unit/test_prompts.py``).
Each ``<document>`` block carries the identity attributes
``source`` / ``path`` / ``title`` — and, since phase 106 (D5),
``date`` (the row's ``created_at`` UTC date part, ``YYYY-MM-DD``,
@@ -466,7 +494,14 @@ def build_high_prompt(
"(no documents matched — do not invent specifics)"
)
if blocks:
body = SUGGEST_INTRO + "\n\n" + body
if folder_lines:
# Phase 119 (D3, LOCKED A4): the folder lines ride immediately
# after the intro line, one per line, a blank line, then the
# first block — plain lines, no new markup (the <document>
# block markup AND body stay byte-identical around them).
body = SUGGEST_INTRO + "\n" + "\n".join(folder_lines) + "\n\n" + body
else:
body = SUGGEST_INTRO + "\n\n" + body
prompt = _base("HIGH")
for part in (build_kb_section(kb_overview or ""), build_steering_section(notes or [])):
if part: