ouroboros/tests/test_docs_sync.py
Ouroboros ac7d1cd322 Merge branch 'ouroboros' (v6.88.0) into cxi/integration
Brings the public line's 23 commits — MiniMax direct provider, crash-safe
managed updates, the two-pass hermetic commit gate, and the Windows/release
CI fixes — into the Claudexor-integration line (v6.89.0).

Union resolutions of note (15 conflicted files):
- Version carriers stay 6.89.0 (this line IS the next feature release on top
  of 6.88.0); the README Version History carries both lines' rows.
- config.py keeps the SSOT refactors (_clamped_number_setting,
  settings_env_keys()) — the MiniMax keys ride automatically via
  SETTINGS_DEFAULTS.
- gateway/control.py restart callback carries BOTH fixes: owner=True (the
  runtime-mode re-read on owner restarts) and the bool return their restart
  serialization reads.
- supervisor/workers.py terminal emission: their terminal_task_metadata
  projection (a superset of the evolution_transaction carry) + this line's
  cost-emission discipline (`emitted`, unavailable projections never publish
  None placeholders).
- scope_review keeps the reviewer-window SSOT (the per-model window helpers
  their side still carried are deleted); MiniMax window probing moves into
  reviewer_window.reviewer_route/resolve (region-derived base_url +
  authenticated catalog probe). The delegated session branch coexists with
  their _ScopePromptContext/represent_binary call shape.
- shell.py keeps the claude_code_edit retirement (D10): their copies of the
  retired helpers are deleted, their now-unused resolver import dropped.
- platform_layer keeps OUROBOROS_BUNDLE_DIR bundled-resource bases and gains
  their ripgrep-pin dataclass; updates.js takes their redesigned
  preflight/plan/typed-apply flow whole (it subsumes this line's
  always-merge-aware intent); settings.js keeps the D10/6.1 picker removals
  and gains the MiniMax region field.

Verified: import smoke, ruff F clean, 11 focused pytest files green
(including their test_update_apply_routing), web tests 136/136.

Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 05:54:46 +03:00

172 lines
7.6 KiB
Python

"""Guardrails for architecture docs after UI/routing overhaul.
README prose pins were retired in v5.8.3-rc.5 — the README is intentionally
allowed to evolve its marketing copy without dragging tests along; the
ARCHITECTURE.md pins below are the load-bearing rationale-layer guards
(P6) that must survive every doc-touch commit.
"""
import os
import pathlib
REPO = pathlib.Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def _read(rel: str) -> str:
return (REPO / rel).read_text(encoding="utf-8")
def test_architecture_mentions_shared_log_grouping_and_direct_provider_review_fallback():
arch = _read("docs/ARCHITECTURE.md")
assert "log_events.js" in arch
assert "live task card" in arch
assert "grouped task cards" in arch
# Direct-provider fallback covers official OpenAI, Anthropic, MiniMax, Cloud.ru,
# and GigaChat, while still excluding OpenRouter/OpenAI-compatible/mixed-provider configs.
# Keep the generalized name ("Direct-provider review fallback") and a
# reference to the legacy "OpenAI-only review fallback" phrase for
# discoverability, and pin the honest scope language so the doc cannot
# silently re-expand to claim symmetric coverage it does not have yet.
assert "Direct-provider review fallback" in arch
assert "OpenAI-only review fallback" in arch # legacy name still referenced for discoverability
assert "official OpenAI, Anthropic, MiniMax, Cloud.ru, and GigaChat" in arch
assert "_exclusive_direct_remote_provider_env" in arch
# v4.34.0: direct-provider fallback now documents the
# `main_model.startswith(provider_prefix)` guard in get_review_models —
# previously absent, allowing OpenAI/Anthropic-only setups with a
# cross-provider free-text main model to silently miss the fallback.
assert "migrate_model_value" in arch
assert "already start with the exclusive provider prefix" in arch
# v4.34.0: Claude Runtime Status doc widened to cover both backend and
# browser-side `catch` block paths that set `claudeRuntimeHasError`.
assert "refreshClaudeCodeStatus" in arch
assert "transport failure" in arch
def test_architecture_documents_skill_schedule_lifecycle_and_evolution_light_block():
arch = _read("docs/ARCHITECTURE.md")
# v6.9 RC2: skill schedule readiness SSOT, lifecycle resync, tombstone
# retention, DST contract, and the evolution light-mode hard block.
assert "resync_skill_schedules()" in arch
assert "skill_readiness_for_execution()" in arch
assert "DST-aware system" in arch
assert "hard-blocked in `light` runtime mode" in arch
# Experience Review memory write-back data flow is documented.
assert "MEMORY_ACTIONS_JSON" in arch
assert "apply_memory_actions" in arch
assert "never auto-written to `identity.md`" in arch
def test_consciousness_prompt_matches_scope_limited_contracts():
consciousness = _read("prompts/CONSCIOUSNESS.md")
assert "schedule subagents" in consciousness
assert "wait on subagents" in consciousness
assert "Update your scratchpad or identity" in consciousness
assert "Message the user proactively" in consciousness
assert "recent_tasks" in consciousness
def test_phase3_governance_language_is_pinned_without_new_qa_surface():
bible = _read("BIBLE.md")
development = _read("docs/DEVELOPMENT.md")
system = _read("prompts/SYSTEM.md")
authoring = _read("docs/CREATING_SKILLS.md")
architecture = _read("docs/ARCHITECTURE.md")
checklists = _read("docs/CHECKLISTS.md")
development_flat = " ".join(development.split())
assert (
"Uncertainty calls for judgment, not permission: within its legitimate "
"authority, Ouroboros decides autonomously."
) in bible
assert (
"Structural depth is not scope breadth: choose the smallest change that "
"eliminates the proven failure class."
) in bible
for principle in (
"Single Responsibility Principle",
"Open/Closed Principle",
"Liskov Substitution Principle",
"Interface Segregation Principle",
"Dependency Inversion Principle",
):
assert principle in development
assert "DI container" in development
assert "AST analyzer" in development
assert "Diff size, line count, and file count alone are not findings" in development
assert "Mutable external-fact inventory" in development
for column in (
"Location",
"Fact",
"Mutability",
"Current authority",
"Live/probe option",
"Risk",
"Recommendation",
):
assert f"| {column} " in development
assert "does not migrate their runtime representations" in development_flat
for text in (development, system, authoring, architecture, checklists):
flat = " ".join(text.split())
assert "real consumer flow" in flat
assert "screenshot" in flat.lower()
assert "vision" in flat.lower()
assert "not a universal" in flat or "not universal" in flat or "no universal" in flat
assert "No visual-QA runner, endpoint, ledger" in " ".join(architecture.split())
def test_phase3_widget_authoring_docs_match_recursive_schema_v1():
development = _read("docs/DEVELOPMENT.md")
authoring = _read("docs/CREATING_SKILLS.md")
architecture = _read("docs/ARCHITECTURE.md")
checklists = _read("docs/CHECKLISTS.md")
authoring_flat = " ".join(authoring.split())
for text in (development, authoring, architecture, checklists):
for component in ("group", "metric", "callout"):
assert component in text
assert "maximum depth of 8" in authoring
assert "256 nodes" in authoring
assert "stable tree path" in authoring
assert "transitively passive" in authoring_flat
assert "dynamic_ui_schema" in authoring
def test_architecture_mirror_matches_the_split_axes_contracts():
"""XG-2.2/XG-2.3 (v6.87.28 review gate): the P6 mirror tracks schedule-vs-dispatch.
Every pin here failed on the pre-fix docs: the module map claimed
`swarm_efficiency.lanes_used` while `_build_swarm_efficiency` emits
`lanes_requested`; `subagents.py` was said to own task-group compaction after
`compact_task_group` was deleted; the control map said `schedule_subagent`
surfaces effective lane(s) after `_finalize_schedule_emission` went
request-only; the `swarm_fanout` enumeration promised requested/effective
lanes after `_emit_swarm_fanout` dropped `effective_model_lanes`; and both
`wait_tasks` field enumerations omitted the emitted `capability_delta`.
"""
arch = _read("docs/ARCHITECTURE.md")
development = _read("docs/DEVELOPMENT.md")
arch_flat = " ".join(arch.split())
dev_flat = " ".join(development.split())
# swarm_efficiency reports the REQUEST: lanes_requested, never lanes_used.
assert "lanes_requested" in arch
assert "lanes_used" not in arch
# Task-group compaction left with the degenerate lane fan-out (v6.87.28).
assert "task-group compaction" not in arch
assert "compact_task_group" not in arch
# schedule_subagent reports the request only; the axes resolve at dispatch.
assert "schedule_subagent surfaces effective_lane(s)" not in arch_flat
assert "schedule_subagent reports the requested lane only" in arch_flat
# swarm_fanout carries the requested lane; a wave event written before any
# child starts cannot know what the children ran on.
assert "requested/effective lanes" not in arch
# Both wait_tasks projection enumerations disclose capability_delta.
assert "trace_summary, capability_delta when the child has something to disclose" in arch_flat
assert "trace_summary, capability_delta when disclosable, duplicate_of" in dev_flat