Connect shared book sources to deep and skill reviews

NOT_REVIEWED private integration checkpoint. Use physical chapter composition and exact native coverage while preserving legacy evidence labels. Keep authored shared knowledge orientation resident with complete source-addressed navigation. Focused book, deep, skill and docs tests pass. Final required-manifest wiring, chapter migration and authoritative review remain pending.
This commit is contained in:
Ouroboros 2026-09-13 02:32:53 +03:00
parent 45a816d5a4
commit 43dacbebe8
9 changed files with 382 additions and 49 deletions

View file

@ -610,21 +610,25 @@ def build_knowledge_sections(
# One mind keeps its authored common orientation across rooms. The generated
# inventory is navigation, not a substitute for that understanding; a
# project's shelf adds focus without hiding the common corpus.
from ouroboros.knowledge import INDEX_FILE, OVERVIEW_TOPIC, read_knowledge_note, resolve_knowledge_address
from ouroboros.knowledge import (INDEX_FILE, OVERVIEW_TOPIC, inventory_knowledge,
read_knowledge_note, render_knowledge_index, resolve_knowledge_address)
pid = str(project_id or "").strip()
global_address = resolve_knowledge_address(env.drive_root, OVERVIEW_TOPIC, "global")
global_address = resolve_knowledge_address(env.drive_path("memory").parent, OVERVIEW_TOPIC, "global")
authored_overview = False
try:
overview = read_knowledge_note(global_address)
overview_text = overview.source.text_at(overview.source.body_span) if overview.source else overview.text
if overview_text.strip():
sections.append("## Shared understanding\n\n" + overview_text)
authored_overview = overview.source is not None
sections.append(f"## Shared understanding\n\nSource: knowledge_read(topic='{OVERVIEW_TOPIC}', scope='global').\n\n" + overview_text)
except FileNotFoundError:
pass # The generated index retains prior orientation until one is authored.
except (OSError, UnicodeDecodeError) as exc:
sections.append(f"Shared understanding source unavailable: knowledge_read(topic='{OVERVIEW_TOPIC}', scope='global'). {type(exc).__name__}.")
knowledge_indexes = [(global_address.shelf / INDEX_FILE,
"## Knowledge base", "knowledge index")]
"## Knowledge base\n\nGlobal navigation: knowledge_list(scope='global'); read linked topics with knowledge_read(topic=..., scope='global').",
"knowledge index")]
if pid:
from ouroboros.project_facts import project_knowledge_dir
@ -633,7 +637,8 @@ def build_knowledge_sections(
if include_pattern_body:
knowledge_indexes.append((env.drive_path("memory/knowledge/patterns.md"), pattern_header, "patterns register"))
for path, header, label in knowledge_indexes:
text = safe_read(path)
text = (render_knowledge_index(inventory_knowledge(global_address), include_summaries=False)
if authored_overview and path == global_address.shelf / INDEX_FILE else safe_read(path))
if not text.strip():
continue
if warn_large and len(text) > _LARGE_CONTEXT_SECTION_CHARS:

View file

@ -27,6 +27,7 @@ receipts, coverage and completeness so consecutive reports stay comparable.
from __future__ import annotations
import logging
import json
import pathlib
import posixpath
import time
@ -53,6 +54,7 @@ from ouroboros.utils import atomic_write_json, estimate_tokens, utc_now_iso # n
from ouroboros.config import get_context_mode # noqa: E402
from ouroboros.provider_models import provider_for_model, provider_has_credentials # noqa: E402
from ouroboros.context_layout import generate_doc_nav_map # noqa: E402
from ouroboros.reference_books import BOOK_ENTRYPOINTS, compose_book, load_reference_book, overview_book # noqa: E402
from ouroboros.reviewer_slot_config import ( # noqa: E402
ROUTE_KIND_API,
ROUTE_KIND_SESSION,
@ -138,8 +140,10 @@ How to work: you are reading the repository yourself with read-only tools. Read
`BIBLE.md` IN FULL first (about {bible_chars:,} chars — in bounded chunks): every
finding is checked against it, and a report that did not read it is not a deep
self-review. The memory files below are inlined byte-exact; `docs/ARCHITECTURE.md`,
`docs/DEVELOPMENT.md` and `docs/CHECKLISTS.md` are given as navigation maps — read the
sections you need on demand. Then inspect the code (search_code, query_code,
`docs/DEVELOPMENT.md` are book entrypoints; their overviews identify the actual
physical chapter sources. `docs/CHECKLISTS.md` has its own navigation map. Read
the needed sources on demand, using lines local to the physical file you open,
never treating composed-book line numbers as an entrypoint address. Then inspect the code (search_code, query_code,
read_file), cross-reference interactions between modules and follow call chains out
of the files you open. Prioritize: CRITICAL > IMPORTANT > ADVISORY.
@ -335,27 +339,37 @@ def build_review_pack(
memory = _append_memory_whitelist(memory_parts, skipped, drive_root=drive_root)
memory_text = "\n".join(memory_parts)
# Low context mode: render ARCHITECTURE.md as a navigation map (full sections
# read on demand) and exclude it from the atlas full-file selection instead of
# inlining ~32K tokens. Reuses the atlas ``already_included`` mechanism so the
# shared commit-gate atlas (scope / plan review) is unaffected.
# The atlas still owns repository selection. Composed books have one
# physical closure, included once here and excluded from duplicate atlas
# content. Legacy Max monoliths retain their original atlas delivery.
nav_parts: list[str] = []
already_included: frozenset[str] = frozenset()
if get_context_mode() == "low":
book_parts: list[str] = []
book_views: list[dict] = []
already_included: set[str] = set()
low = get_context_mode() == "low"
for book_id, entrypoint in BOOK_ENTRYPOINTS.items():
if entrypoint not in tracked:
continue
try:
arch_text = (repo_dir / "docs" / "ARCHITECTURE.md").read_text(encoding="utf-8")
except Exception:
arch_text = ""
if arch_text.strip():
nav_parts.append(
generate_doc_nav_map(
arch_text, title="ARCHITECTURE.md", rel_path="docs/ARCHITECTURE.md"
)
book = load_reference_book(repo_dir, book_id)
except (OSError, ValueError) as exc:
return "", {"file_count": 0, "total_chars": 0, "skipped": [f"FATAL: {entrypoint} book unavailable: {exc}"]}
if book.legacy and not (low and book_id == "architecture"):
continue
sources = (book.entrypoint, *book.chapters)
partial = low and book_id == "architecture"
already_included.update(s.source_path for s in sources)
book_views.append({"book_id": book_id, "delivery": "overview" if partial else "full",
"sources": [{"path": s.source_path, "sha256": s.sha256, "size": len(s.raw)} for s in sources]})
if partial:
navigation = (generate_doc_nav_map(book.entrypoint.text, title="ARCHITECTURE.md", rel_path=entrypoint)
if book.legacy else overview_book(book).text)
nav_parts.append(navigation
+ "\n\nNote for this deep self-review call: this surface has no tool loop, "
"so the navigation map is an index of omitted sections, not an actionable "
"read_file instruction. Flag any needed full ARCHITECTURE.md section explicitly."
)
already_included = frozenset({"docs/ARCHITECTURE.md"})
"read_file instruction. Flag any needed full Architecture chapter explicitly.")
else:
book_parts.append(f"## Reference book: {entrypoint}\n\n" + compose_book(book))
# Reserve the (bounded) omission section inside the atlas's fixed budget —
# it is appended to the pack after the atlas fills, so an unreserved section
@ -363,6 +377,7 @@ def build_review_pack(
atlas_fixed_tokens = (
int(fixed_prompt_tokens)
+ estimate_tokens(memory_text)
+ estimate_tokens("\n".join(book_parts))
+ estimate_tokens("\n".join(nav_parts))
+ _OMISSION_SECTION_RESERVE_TOKENS
)
@ -375,7 +390,7 @@ def build_review_pack(
ReviewContextAtlasRequest(
repo_dir=repo_dir,
tracked_paths=tuple(tracked),
already_included=already_included,
already_included=frozenset(already_included),
fixed_prompt_tokens=atlas_fixed_tokens,
target_total_tokens=min(850_000, hard_budget),
hard_total_tokens=hard_budget,
@ -408,10 +423,17 @@ def build_review_pack(
for record in atlas.omitted
if record.disposition not in {"already_included", "manifest_only"}
)
parts = [atlas.text]
if book_views:
atlas.manifest["reference_book_views"] = book_views
for row in atlas.manifest.get("coverage", []):
view = next((v for v in book_views if any(s["path"] == row.get("path") for s in v["sources"])), None)
if view:
row["reason"] = ("physical book source included in full composition" if view["delivery"] == "full"
else "book overview only; full chapter text omitted from this one-packet delivery")
parts = [*book_parts, atlas.text]
parts.extend(nav_parts)
parts.extend(memory_parts)
file_count = len(atlas.selected) + memory["inlined"]
file_count = len(atlas.selected) + memory["inlined"] + sum(len(v["sources"]) for v in book_views if v["delivery"] == "full")
_append_omission_section(parts, skipped)
pack_text = "\n".join(parts)
@ -635,7 +657,10 @@ def _repo_relative(path: Any, repo_dir: pathlib.Path) -> str:
def _native_read_coverage(usage: Dict[str, Any], repo_dir: pathlib.Path) -> Dict[str, Dict[str, Any]]:
"""R8: how much of each mandatory read the host OBSERVED, from the episode's
"""Prefer the native operation's exact manifest-bound source coverage.
Historical receipts retain only their explicitly labelled line evidence.
R8: how much of each mandatory read the host OBSERVED, from the episode's
receipts — the merged line intervals of every executed repository-root
``read_file`` receipt for the path (a single result is capped, so a full
read of BIBLE.md is multi-chunk by construction).
@ -656,6 +681,27 @@ def _native_read_coverage(usage: Dict[str, Any], repo_dir: pathlib.Path) -> Dict
traversal shapes before dispatch — see ``_repo_relative``). Disclosure,
never a refusal: the report is delivered with the flag in its header.
"""
exact = usage.get("native_read_coverage")
sources = exact.get("sources") if isinstance(exact, dict) else None
if isinstance(sources, list) and sources:
out = {}
for index, source in enumerate(sources):
source = source if isinstance(source, dict) else {}
root, path = str(source.get("root") or ""), str(source.get("path") or f"source[{index}]")
address = path if root in _REPO_ROOTS else f"{root}:{path}"
if address in out:
address = f"{root}:{path}@{source.get('source_revision', index)}"
total, covered = source.get("complete_chars"), source.get("covered_chars")
known = (type(total) is int and type(covered) is int and 0 <= covered <= total
and isinstance(source.get("source_revision"), str) and len(source["source_revision"]) == 64)
state = ("read" if source.get("status") == "complete" and known else
"partial" if source.get("status") == "incomplete" and known and covered else
"missing" if source.get("status") == "incomplete" and known else "unobserved")
out[address] = {**source, "state": state, "covered_chars": covered if known else 0,
"complete_chars": total if known else 0,
"fraction": round(covered / total, 3) if known and total else 1.0 if state == "read" else 0.0,
"evidence_basis": "source_ranges"}
return out
receipts = [r for r in (usage.get("native_tool_receipts") or []) if isinstance(r, dict)]
capped = int(usage.get("native_tool_calls") or 0) > len(receipts)
out: Dict[str, Dict[str, Any]] = {}
@ -666,6 +712,7 @@ def _native_read_coverage(usage: Dict[str, Any], repo_dir: pathlib.Path) -> Dict
named = r.get("opened_path") if isinstance(r.get("opened_path"), str) and r.get("opened_path") else r.get("path")
root = r.get("opened_root") if isinstance(r.get("opened_root"), str) and r.get("opened_root") else str(r.get("root") or "")
if (r.get("tool") != "read_file" or r.get("outcome") != "executed"
or r.get("delivered") is False
or root not in _REPO_ROOTS or _repo_relative(named, repo_dir) != rel):
continue
if not all(isinstance(r.get(k), int) for k in ("start_line", "end_line", "total_lines")):
@ -691,7 +738,8 @@ def _native_read_coverage(usage: Dict[str, Any], repo_dir: pathlib.Path) -> Dict
else:
state = "partial" if covered else "missing"
out[rel] = {"state": state, "covered_lines": covered, "total_lines": total,
"fraction": round(covered / total, 3) if total else 0.0}
"fraction": round(covered / total, 3) if total else 0.0,
"evidence_basis": "legacy_lines"}
return out
@ -723,7 +771,11 @@ def _delivery_incomplete(delivery: str, usage: Dict[str, Any], message: Optional
sets no usage finish reason at all) — meaning the report hit the output
reserve; a session's completeness is not host-observable."""
if delivery == "native_tool_rounds":
return str(usage.get("native_incomplete") or "") or "none"
reported = str(usage.get("native_incomplete") or "")
coverage = usage.get("native_read_coverage") or {}
if not reported and coverage.get("sources") and coverage.get("status") != "complete":
reported = "required_source_coverage_incomplete"
return reported or "none"
if delivery == "api_packet":
msg = message if isinstance(message, dict) else {}
cut = (str(usage.get("response_finish_reason") or "") == "length"
@ -761,6 +813,7 @@ def _provenance_header(delivery: str, model: str, usage: Dict[str, Any], memory:
"end_reason": usage.get("native_end_reason", ""),
"transcript": f"{usage.get('native_transcript_chars', 0)}/{usage.get('native_transcript_bound', 0)}",
"landing": f"{usage.get('native_landing_notified', False)}/{usage.get('native_landing_sent', False)}",
"coverage_basis": usage.get("deep_review_coverage_basis", "legacy_lines"),
})
elif delivery == "api_packet":
facts["attestation"] = "packed"
@ -798,7 +851,8 @@ def _failed(text: str, *, reason_code: str, usage: Optional[Dict[str, Any]] = No
return text, out
def _retrieving_task(repo_dir: pathlib.Path, drive_root: pathlib.Path) -> Tuple[str, Dict[str, Any]]:
def _retrieving_task(repo_dir: pathlib.Path, drive_root: pathlib.Path, *,
required_sources_ref: Optional[dict] = None) -> Tuple[str, Dict[str, Any]]:
"""The route-owned task text for a retrieving row: role + method, the
memory whitelist inline (byte-exact, as the packed pack carries it), and
the governance navigation maps. BIBLE.md is a mandatory READ, never
@ -811,8 +865,18 @@ def _retrieving_task(repo_dir: pathlib.Path, drive_root: pathlib.Path) -> Tuple[
memory_parts: list[str] = []
skipped: list[str] = []
memory = _append_memory_whitelist(memory_parts, skipped, drive_root=drive_root)
navigation = []
for book_id, entrypoint in BOOK_ENTRYPOINTS.items():
if not (repo_dir / entrypoint).is_file():
navigation.append(f"[Missing reference book: {entrypoint}]")
continue
book = load_reference_book(repo_dir, book_id)
navigation.append(generate_doc_nav_map(book.entrypoint.text, title=entrypoint, rel_path=entrypoint)
if book.legacy else overview_book(book).text)
navigation.append(governance_nav_maps(repo_dir, tuple(p for p in _NAV_MAP_DOCS if p not in BOOK_ENTRYPOINTS.values())))
parts = [
_ROLE_PROMPT + _RETRIEVING_METHOD.format(bible_chars=len(bible)),
*navigation,
"## Memory (runtime data root, inlined byte-exact)",
*memory_parts,
# EVERY whitelisted entry gets its disposition here — the omission
@ -821,7 +885,9 @@ def _retrieving_task(repo_dir: pathlib.Path, drive_root: pathlib.Path) -> Tuple[
f"Memory dispositions ({memory['total']} whitelisted): "
+ "; ".join(f"{rel} {d}" for rel, d in memory["dispositions"].items()),
]
parts.append(governance_nav_maps(repo_dir, _NAV_MAP_DOCS))
if required_sources_ref:
parts.append("Read the complete required source manifest through its exact source handle and cover every listed source across your working views: "
+ json.dumps(required_sources_ref, ensure_ascii=False))
return "\n\n".join(parts), {"memory": memory, "bible_chars": len(bible)}
@ -834,6 +900,8 @@ def _run_retrieving_review(
*,
task_id: str,
deadline_at: str,
required_sources: Optional[list] = None,
required_sources_ref: Optional[dict] = None,
) -> Tuple[str, Dict[str, Any]]:
"""A retrieving row (native episode or delegated session) through the
shared executor seam, exactly like the advisory: hand-built request, slot
@ -847,7 +915,10 @@ def _run_retrieving_review(
from ouroboros.review_substrate import ReviewRequest
from ouroboros.usage_accounting import UsageScope, current_usage_scope, usage_scope
task_text, task_facts = _retrieving_task(repo_dir, drive_root)
task_text, task_facts = _retrieving_task(repo_dir, drive_root, required_sources_ref=required_sources_ref)
policy = {"output_contract": _REPORT_CONTRACT, "native_data_root": str(drive_root)}
if required_sources is not None:
policy.update(native_required_sources=required_sources, native_required_sources_ref=required_sources_ref or {})
request = ReviewRequest(
surface="deep_self_review",
goal="Deep self-review of the whole Ouroboros system against BIBLE.md.",
@ -859,7 +930,7 @@ def _run_retrieving_review(
# REAL runtime root (R5), readable by the reviewer's own tools; memory
# coverage itself is the inline whitelist in the task (byte-exact,
# disposition-disclosed) — never receipts.
policy={"output_contract": _REPORT_CONTRACT, "native_data_root": str(drive_root)},
policy=policy,
deadline_at=deadline_at,
)
# The logical window: the task's absolute ceiling narrowed by the owner
@ -930,17 +1001,21 @@ def _run_retrieving_review(
reason_code="deep_self_review_error", usage=usage)
if delivery == "native_tool_rounds":
detail = _native_read_coverage(usage, repo_dir)
usage["deep_review_coverage_basis"] = "source_ranges" if any(c["evidence_basis"] == "source_ranges" for c in detail.values()) else "legacy_lines"
coverage = {rel: (f"partial({c['fraction']:.2f})" if c["state"] == "partial" else c["state"])
for rel, c in detail.items()}
for rel, c in detail.items():
if c["state"] != "read":
covered, total, unit = (c["covered_chars"], c["complete_chars"], "characters") if c["evidence_basis"] == "source_ranges" else (c["covered_lines"], c["total_lines"], "lines")
missing = f"no delivered range matching the required source revision of {rel}" if c["evidence_basis"] == "source_ranges" else f"no executed repository-root read_file receipt for {rel}"
unobserved = f"the exact required source extent of {rel} is unobserved" if c["evidence_basis"] == "source_ranges" else f"the {rel} read extent is unobserved (receipts capped or extent not recorded)"
usage["capability_delta"].append({
"kind": "capability_delta",
"requested": f"mandatory full read of {rel}",
"effective": {
"partial": f"{c['covered_lines']} of {c['total_lines']} lines of {rel} delivered (merged receipts)",
"missing": f"no executed repository-root read_file receipt for {rel}",
}.get(c["state"], f"the {rel} read extent is unobserved (receipts capped or extent not recorded)"),
"partial": f"{covered} of {total} {unit} of {rel} delivered (merged receipts)",
"missing": missing,
}.get(c["state"], unobserved),
"reason": f"deep_review_mandatory_read_{c['state']}",
})
else:
@ -969,10 +1044,12 @@ def _run_retrieving_review(
completeness = "complete" if incomplete == "none" else (
"completeness not host-observed" if incomplete == "unobserved" else f"INCOMPLETE ({shown_reason})")
if delivery == "native_tool_rounds":
reads = "; ".join(
f"{rel} " + (f"{c['fraction']:.0%} read ({c['covered_lines']}/{c['total_lines']} lines)" if c["state"] == "partial"
else {"read": "read in full", "missing": "NOT read"}.get(c["state"], "read extent unobserved"))
for rel, c in detail.items())
reads = []
for rel, c in detail.items():
covered, total, unit = (c["covered_chars"], c["complete_chars"], "characters") if c["evidence_basis"] == "source_ranges" else (c["covered_lines"], c["total_lines"], "lines")
reads.append(f"{rel} " + (f"{c['fraction']:.0%} read ({covered}/{total} {unit})" if c["state"] == "partial"
else {"read": "read in full", "missing": "NOT read"}.get(c["state"], "read extent unobserved")))
reads = "; ".join(reads)
human = (
f"Deep self-review: native inspection episode on {shown_model} — {int(usage.get('native_rounds') or 0)} rounds, "
f"{int(usage.get('native_tool_calls') or 0)} tool calls ({len(usage.get('native_tool_receipts') or [])} host-observed receipts); "
@ -1283,6 +1360,8 @@ def run_deep_self_review(
task_id: str = "",
deadline_at: str = "",
slot: Optional[ConfiguredReviewerSlot] = None,
required_sources: Optional[list] = None,
required_sources_ref: Optional[dict] = None,
) -> Tuple[str, Dict[str, Any]]:
"""Execute the deep self-review on the configured row.
@ -1297,6 +1376,9 @@ def run_deep_self_review(
refusal is budget vocabulary for the agent's budget-pause rail, not a
review error.
``slot`` overrides the configured row (tests, callers that already resolved it).
``required_sources`` and its exact source handle come from the caller's
existing immutable review assembler; this consumer never infers the
complete required surface from a working-tree scan.
"""
try:
try:
@ -1313,6 +1395,7 @@ def run_deep_self_review(
if row.retrieves:
return _run_retrieving_review(
repo_dir, drive_root, llm, emit_progress, row, task_id=task_id, deadline_at=deadline_at,
required_sources=required_sources, required_sources_ref=required_sources_ref,
)
return _run_packed_review(repo_dir, drive_root, llm, emit_progress, row, str(model or ""))
except BudgetExceeded:

View file

@ -180,14 +180,15 @@ def _label(value: str) -> str:
return value.replace("\\", "\\\\").replace("[", "\\[").replace("]", "\\]").replace("*", "\\*")
def render_knowledge_index(rows: tuple[dict[str, Any], ...], legacy_context: str = "") -> str:
def render_knowledge_index(rows: tuple[dict[str, Any], ...], legacy_context: str = "",
*, include_summaries: bool = True) -> str:
"""Generated navigation is separate from authored understanding."""
entries = []
for row in rows:
topic, title = str(row["topic"]), str(row.get("title") or row["topic"])
line = f"- **{_label(topic)}**: [{_label(title)}](<{quote(topic + '.md', safe='/')}>)"
summary = row.get("summary")
if isinstance(summary, str) and summary:
if include_summaries and isinstance(summary, str) and summary:
line += "\n" + "\n".join(" " + part for part in summary.splitlines())
if row.get("read_error") or row.get("parse_error"):
line += "\n (source metadata unavailable; read the original note)"

View file

@ -101,7 +101,13 @@ _SINGLE_CONTENT = (
_SESSION_RETRIEVAL = (
"Use native read/search tools inside the source-repository session root. Read "
"`BIBLE.md`, `docs/ARCHITECTURE.md`, and `docs/DEVELOPMENT.md` in full; read "
"`BIBLE.md` in full. Read the `docs/ARCHITECTURE.md` and `docs/DEVELOPMENT.md` "
"book entrypoints in full, then every physical chapter in each entrypoint's "
"`Chapters` membership list in full, in the order you choose. Resolve each chapter link "
"relative to its entrypoint; a legacy monolith without `Chapters` is already "
"the complete book. Cite physical file paths and file-local lines, never "
"line numbers in a composed book. Reading an entrypoint alone does not "
"cover its chapters; report any missing or unread chapter explicitly. Read "
"the `Skill Review Checklist` section of `docs/CHECKLISTS.md`; then read "
"`docs/CREATING_SKILLS.md`, `ouroboros/contracts/plugin_api.py`, and "
"`ouroboros/extension_ui_validation.py` in full. Treat those source reads as "

View file

@ -16,6 +16,7 @@ import logging
import pathlib
from typing import Any, Dict, List
from ouroboros.reference_books import BOOK_ENTRYPOINTS, compose_book, load_reference_book
from ouroboros.skill_review_history import count_attempts as _count_attempts_for_content
from ouroboros.skill_review_status import CRITICAL_ITEMS
from ouroboros.tools.review_helpers import (
@ -67,6 +68,12 @@ def _load_governance_artifact(
"""Load governance context with an explicit omission marker on failure."""
from ouroboros.tools.review_helpers import load_governance_doc
for book_id, entrypoint in BOOK_ENTRYPOINTS.items():
if relpath == entrypoint:
try:
return compose_book(load_reference_book(repo_root, book_id))
except (OSError, ValueError) as exc:
return f"[⚠️ OMISSION: {relpath} book could not be loaded: {exc}]"
return load_governance_doc(repo_root, relpath, on_missing="explicit")
@ -126,11 +133,11 @@ review enforcement mode.
## Governance context — docs/ARCHITECTURE.md
Use Section 10 (Key Invariants), Section 12 (Host Service / Companion /
Chat IDs), and Section 13 (External Skills Layer)
as the binding description of what the skill is allowed to touch. In
particular invariant 11 is the authoritative rule: skills must not write
to the self-modifying repo, and reviewed execution is the primary gate.
Use the named sections "Key Invariants", "Host Service, Companion Processes,
and Chat IDs", and "External Skills Layer" as the binding description of what
the skill is allowed to touch. The "Skill gates do not collapse" criterion
keeps executable review, owner grants, dependencies, enablement, and execution
distinct; apply the Skill Review Checklist's `no_repo_mutation` item.
{architecture_text}

View file

@ -106,3 +106,18 @@ def test_large_nano_task_retains_exact_owner_source_without_changing_max(tmp_pat
assert plan.messages_for("max")[-1]["content"] == task_text
assert "FINAL OWNER CRITERION" in json.loads(core.user_content_json)
assert plan.nano_projection.estimated_tokens < 81920
def test_authored_common_understanding_is_resident_without_every_note_summary(tmp_path):
from ouroboros.knowledge import resolve_knowledge_address, write_knowledge_note
env, _core, task = _capture(tmp_path)
write_knowledge_note(resolve_knowledge_address(env.drive_root, "overview"),
"Our shared understanding includes context-sensitive preferences.")
write_knowledge_note(resolve_knowledge_address(env.drive_root, "people/alex"),
"---\ntype: relationship\ntitle: Alex\nsummary: Details belong to their source.\n---\nDetailed source.")
sections = "\n".join(context.build_knowledge_sections(env))
assert "context-sensitive preferences" in sections
assert "people/alex" in sections and "Alex" in sections
assert "Details belong to their source" not in sections
assert "scope='global'" in sections

View file

@ -0,0 +1,142 @@
"""Deep review composes complete books and consumes revision-bound coverage."""
import hashlib
import json
import pytest
from ouroboros import deep_self_review as deep
from ouroboros.artifacts import read_actor_source_bytes
from ouroboros.reference_books import compose_book, load_reference_book
from tests.test_deep_review_slot import _native_row, _ScriptedLLM, _tool_call
def _corpus(root):
files = {
"BIBLE.md": "# Constitution\n\nThe constitutional source.\n",
"docs/CHECKLISTS.md": "# Checklists\n\n## Review\n\nCheck the actual contract.\n",
"worker.py": "def work(): return True\n",
}
for book_id, entry in (("architecture", "docs/ARCHITECTURE.md"), ("development", "docs/DEVELOPMENT.md")):
files[entry] = f"# {book_id.title()}\n\nPurpose of the {book_id} book.\n\n## Chapters\n\n- [Flow]({book_id}/flow.md)\n- [State]({book_id}/state.md)\n"
for name in ("flow", "state"):
files[f"docs/{book_id}/{name}.md"] = (
f"# {name.title()}\n\nIntroduction to {book_id} {name}.\n\n## Contract\n\nExact {book_id} {name} contract body.\n")
for rel, text in files.items():
target = root / rel
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(text)
return files
def _required(root, rel):
raw = (root / rel).read_bytes()
normalized = raw.decode().replace("\r\n", "\n").replace("\r", "\n")
return {"root": "system_repo", "path": rel, "source_revision": hashlib.sha256(raw).hexdigest(),
"complete_sha256": hashlib.sha256(normalized.encode()).hexdigest(), "complete_chars": len(normalized),
"range_basis": "unicode_text_universal_newlines"}
def test_packed_chaptered_books_are_complete_once_and_stable_before_atlas(tmp_path, monkeypatch):
monkeypatch.setattr(deep, "get_context_mode", lambda: "max")
monkeypatch.setattr(deep, "_compute_graph_centrality", lambda *a: {})
prefixes = []
for name in ("first", "second"):
repo, data = tmp_path / name, tmp_path / f"{name}-data"
files = _corpus(repo)
monkeypatch.setattr(deep, "_dulwich_tracked_paths", lambda *a: (list(files), []))
monkeypatch.chdir(tmp_path)
pack, stats = deep.build_review_pack(repo, data)
for rel, text in files.items():
if rel.startswith(("docs/architecture/", "docs/development/")):
assert pack.count(text) == 1
prefix = "\n".join(f"## Reference book: docs/{book_id.upper()}.md\n\n" + compose_book(load_reference_book(repo, book_id))
for book_id in ("architecture", "development"))
assert pack.startswith(prefix)
assert str(repo) not in prefix
assert all(view["delivery"] == "full" for view in stats["context_manifest"]["reference_book_views"])
prefixes.append(prefix)
assert prefixes[0] == prefixes[1]
def test_low_packed_architecture_overview_does_not_reinline_omitted_chapters(tmp_path, monkeypatch):
repo, data = tmp_path / "repo", tmp_path / "data"
files = _corpus(repo)
monkeypatch.setattr(deep, "get_context_mode", lambda: "low")
monkeypatch.setattr(deep, "_compute_graph_centrality", lambda *a: {})
monkeypatch.setattr(deep, "_dulwich_tracked_paths", lambda *a: (list(files), []))
pack, stats = deep.build_review_pack(repo, data)
assert "Introduction to architecture flow." in pack
assert "Exact architecture flow contract body." not in pack
assert "Exact development flow contract body." in pack
assert "docs/architecture/flow.md" in pack
row = next(r for r in stats["context_manifest"]["coverage"] if r["path"] == "docs/architecture/flow.md")
assert "overview only" in row["reason"]
def test_missing_declared_chapter_never_becomes_a_successful_partial_packed_book(tmp_path, monkeypatch):
repo = tmp_path / "repo"
files = _corpus(repo)
(repo / "docs/architecture/state.md").unlink()
monkeypatch.setattr(deep, "_dulwich_tracked_paths", lambda *a: (list(files), []))
pack, stats = deep.build_review_pack(repo, tmp_path / "data")
assert pack == "" and "book unavailable" in stats["skipped"][0]
assert "state.md" in stats["skipped"][0]
def test_retrieving_book_navigation_uses_only_physical_chapter_addresses(tmp_path, monkeypatch):
repo, data = tmp_path / "repo", tmp_path / "data"
_corpus(repo)
# This legacy mapper must not be fed a composed book with invented entrypoint lines.
monkeypatch.setattr(deep, "generate_doc_nav_map", lambda *a, **k: pytest.fail("chaptered book mapped as monolith"))
task, _facts = deep._retrieving_task(repo, data)
assert "Source: `docs/architecture/flow.md`" in task
assert "Source: `docs/development/state.md`" in task
assert "Introduction to architecture state." in task
assert "Exact architecture state contract body." not in task
assert "file you open" in task
assert task.index("Introduction to architecture flow.") < task.index("## Memory")
def test_exact_coverage_overrides_complete_legacy_lines_without_rebinding_current_file(tmp_path):
files = _corpus(tmp_path)
row = {**_required(tmp_path, "BIBLE.md"), "status": "incomplete", "covered_chars": 7,
"missing_ranges": [[7, len(files["BIBLE.md"])]]}
usage = {"native_read_coverage": {"status": "incomplete", "sources": [row]},
"native_tool_receipts": [{"tool": "read_file", "outcome": "executed", "path": "BIBLE.md",
"root": "system_repo", "start_line": 1, "end_line": 99, "total_lines": 99}]}
(tmp_path / "BIBLE.md").write_text("Changed after the observed review source.\n")
detail = deep._native_read_coverage(usage, tmp_path)["BIBLE.md"]
assert detail["state"] == "partial" and detail["covered_chars"] == 7
assert detail["source_revision"] == row["source_revision"]
assert detail["evidence_basis"] == "source_ranges" and "covered_lines" not in detail
assert deep._delivery_incomplete("native_tool_rounds", usage) == "required_source_coverage_incomplete"
def test_legacy_line_evidence_stays_explicit_and_unsent_reads_never_complete_it(tmp_path):
receipt = {"tool": "read_file", "outcome": "executed", "path": "BIBLE.md", "root": "system_repo",
"start_line": 1, "end_line": 5, "total_lines": 5}
usage = {"native_tool_receipts": [receipt]}
detail = deep._native_read_coverage(usage, tmp_path)["BIBLE.md"]
assert detail["state"] == "read" and detail["evidence_basis"] == "legacy_lines"
assert "source_revision" not in detail
receipt["delivered"] = False
assert deep._native_read_coverage(usage, tmp_path)["BIBLE.md"]["state"] == "missing"
def test_native_deep_review_reports_exact_chapter_gap_without_changing_the_finding(tmp_path, monkeypatch):
repo, data = tmp_path / "repo", tmp_path / "data"
_corpus(repo)
monkeypatch.setenv("OPENROUTER_API_KEY", "fixture-only")
report = "Read: Constitution.\n\nCRITICAL: a real consumer violates the contract."
llm = _ScriptedLLM([
{"tool_calls": [_tool_call("read_file", {"path": "BIBLE.md"})]}, {"content": report}])
required = [_required(repo, "BIBLE.md"), _required(repo, "docs/architecture/flow.md")]
text, usage = deep.run_deep_self_review(repo, data, llm, lambda m: None,
slot=_native_row(), task_id="book-review", required_sources=required)
assert text.endswith(report)
assert usage["deep_review_coverage_basis"] == "source_ranges"
assert usage["native_incomplete"] == "required_source_coverage_incomplete"
assert "docs/architecture/flow.md NOT read" in text
history = json.loads(read_actor_source_bytes(data, "book-review", usage["native_history_source"]))
assert history["required_sources"] == required

View file

@ -558,3 +558,73 @@ def test_review_skill_persist_false_does_not_write(tmp_path, monkeypatch):
# Default state: nothing written.
assert persisted.status == "pending"
assert persisted.content_hash == ""
@pytest.mark.parametrize("chaptered", [False, True], ids=["legacy", "chapters"])
def test_skill_governance_is_complete_and_stable_across_checkouts(tmp_path, monkeypatch, chaptered):
import ouroboros.skill_review_prompt as prompt_owner
corpus = {"BIBLE.md": "# Constitution\n\nConstitutional body.\n"}
for book_id, entrypoint in (
("architecture", "docs/ARCHITECTURE.md"),
("development", "docs/DEVELOPMENT.md"),
):
corpus[entrypoint] = f"# {book_id.title()}\n\nThe {book_id} introduction.\n"
if chaptered:
corpus[entrypoint] += (
f"\n## Chapters\n\n- [First]({book_id}/first.md)\n"
f"- [Second][second]\n\n[second]: {book_id}/second.md\n"
)
for name in ("first", "second"):
corpus[f"docs/{book_id}/{name}.md"] = (
f"# {name.title()}\n\nThe {book_id} {name} introduction.\n"
f"\n## Details\n\nThe complete {book_id} {name} body.\n"
)
else:
corpus[entrypoint] += f"\n## Details\n\nThe complete {book_id} monolith.\n"
monkeypatch.setattr(prompt_owner, "load_checklist_section", lambda _: "Checklist body.")
monkeypatch.setattr(prompt_owner, "build_skill_host_context", lambda _: "Host contract body.")
monkeypatch.chdir(tmp_path)
stable_prefixes = []
for name in ("checkout-one", "checkout-two"):
root = tmp_path / name
for path, text in corpus.items():
target = root / path
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(text, encoding="utf-8")
monkeypatch.setattr(prompt_owner, "_REPO_ROOT", root)
prompt, boundary = prompt_owner._build_review_prompt(
name, root / "external-skill", "{}", name, f"PAYLOAD-{name}",
)
stable = prompt[:boundary]
stable_prefixes.append(stable)
for text in corpus.values():
assert stable.count(text) == 1
assert str(root) not in stable
assert "PAYLOAD-" not in stable
assert "Skill gates do not collapse" in stable
assert "invariant 11" not in stable
assert prompt[boundary:].startswith("## Skill identity")
assert f"PAYLOAD-{name}" in prompt[boundary:]
assert stable_prefixes[0] == stable_prefixes[1]
@pytest.mark.parametrize("chapter_body", [None, "# Chapter\n\n## Missing introduction\n\nBody.\n"])
def test_skill_governance_discloses_unavailable_book_without_partial_body(tmp_path, chapter_body):
from ouroboros.skill_review_prompt import _load_governance_artifact
docs = tmp_path / "docs"
docs.mkdir()
(docs / "ARCHITECTURE.md").write_text(
"# Architecture\n\nEntrypoint body must not stand in for the whole book.\n"
"\n## Chapters\n\n- [Runtime](architecture/runtime.md)\n",
encoding="utf-8",
)
if chapter_body is not None:
(docs / "architecture").mkdir()
(docs / "architecture" / "runtime.md").write_text(chapter_body, encoding="utf-8")
text = _load_governance_artifact(tmp_path, "docs/ARCHITECTURE.md")
assert "OMISSION" in text and "docs/ARCHITECTURE.md" in text
assert "runtime.md" in text
assert "Entrypoint body must not stand in" not in text

View file

@ -121,6 +121,10 @@ def test_chunked_passes_keep_the_full_row_plan_and_exact_session_evidence():
assert "STABLE::" not in call["session_task"]
assert all(path in call["session_task"] for path in (
"BIBLE.md", "docs/CHECKLISTS.md", "ouroboros/contracts/plugin_api.py"))
assert "every physical chapter" in call["session_task"]
assert "`Chapters` membership list in full, in the order you choose" in call["session_task"]
assert "legacy monolith without `Chapters`" in call["session_task"]
assert "physical file paths and file-local lines" in call["session_task"]
assert f"PART {idx} of 2" in call["session_task"]