mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
Second rolling sync of the campaign tree with the live upstream branch (40 upstream commits since the previous merge-basef3fbfdbb). Automerge resolved 18 of the 25 files both sides touched; the seven textual conflicts and the six semantic ones the automerge hid were resolved by class: - generated: ouroboros/size_ratchet_manifest.py taken from upstream and regenerated on the merged tree (the upstream test tests/test_ui_smoke_project_continuity.py entered the 1001-1500 band; its upstream rationale is carried verbatim); domains, inventories regenerated (FROZEN_CONTRACTS_INVENTORY.md). - protected prose: prompts/SAFETY.md takes upstream's compressed shape; the retired OUROBOROS_SCOPE_REVIEW_FLOOR control (removed outright by v7next ABI-5, owner Q10=A) is dropped from the owner-only controls sentence and the protected-path mirror is regenerated from the merged runtime_mode_policy (36 paths + the contracts prefix). prompts/SYSTEM.md (rewritten upstream) gets the v7next safety-critical set (registry split organs, tool_result). Both mirrors are pinned by tests/test_packaging_sync.py. - tests: upstream's Windows/CRLF/argv fixes win over the campaign's interim shims (capability predicates argv lists, golden _posix fold, telegram parity pytest-timeout instead of signal.alarm, chat_plain_system_rows CRLF normaliser, quarantine test import). Upstream's new governance and terminal-receipt tests are adapted to the v7 contracts they meet on this tree: the module-level registry_guard_process._run_shell_safety_check and the typed ToolResult code SKILL_STATE_WRITE_BLOCKED (D02/D04), the shell_outputs home of _sensitive_output_component_reason, and the ABI-2 task-result stamp (unstamped fixture rows are quarantined by the reader, owner Q8=B) in tests/test_terminal_delegation_receipt.py. The git catalog schema pin in tests/test_git_extraction.py moves to the bytes produced by upstream's advisory_review -> preflight_review description rename (332a02f1); the catalog itself is unchanged. Gates on the merged tree: ruff F, check_domains, inventories --check, size_ratchet --check, v7next_adoption, git diff --check all rc 0; the targeted suites for every conflicted or both-sides-touched file and web node --test (847) pass. The full CI-shape battery follows as a separate evidence run.
153 lines
5.9 KiB
Python
153 lines
5.9 KiB
Python
"""Structural contracts for the semantic-no-op git tool extraction.
|
|
|
|
v7next transplant note (oracle ouroboros_v7_wip @ 9f691656): the reference pin
|
|
also freezes the tool-module inventory through ``ouroboros.tool_module_inventory``,
|
|
a v7 leaf absent from this tree — that clause returns with its owner. The
|
|
reference's ``_publish_git_error`` / ``_publish_review_blocked`` rows are the
|
|
typed-result cutover (F2 organ, not carried) and ``_refuse_capped_attempt``
|
|
was retired upstream by 386e9417 (Max Review Cycles), so neither appears in
|
|
the owner map below. Size bounds are re-based on tip bytes: the tip facade
|
|
retains the paid-cycle gate family, the deferred update entry points and the
|
|
catalog the oracle-era monolith did not have.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ast
|
|
import hashlib
|
|
import json
|
|
import pathlib
|
|
|
|
from ouroboros.tools import (
|
|
git,
|
|
git_evolution,
|
|
git_plumbing,
|
|
git_repo_edit,
|
|
git_review_cycle,
|
|
git_vcs_ops,
|
|
)
|
|
|
|
|
|
REPO = pathlib.Path(__file__).parents[1]
|
|
TOOLS = REPO / "ouroboros" / "tools"
|
|
|
|
_LEAVES = (git_plumbing, git_review_cycle, git_evolution, git_repo_edit, git_vcs_ops)
|
|
|
|
_MOVED_OWNERS = {
|
|
"_BINARY_EXTENSIONS": git_plumbing,
|
|
"_acquire_git_lock": git_plumbing,
|
|
"_binding_repo_rel": git_plumbing,
|
|
"_binding_targets_system_repo": git_plumbing,
|
|
"_current_runtime_mode": git_plumbing,
|
|
"_ensure_gitignore": git_plumbing,
|
|
"_protected_paths_block_message": git_plumbing,
|
|
"_release_git_lock": git_plumbing,
|
|
"_sanitize_git_error": git_plumbing,
|
|
"_unstage_binaries": git_plumbing,
|
|
"_DOC_ONLY_EXTENSIONS": git_review_cycle,
|
|
"_diff_is_doc_only": git_review_cycle,
|
|
"_finalize_blocked_review": git_review_cycle,
|
|
"_fingerprint_staged_diff": git_review_cycle,
|
|
"_handle_revalidation_failure": git_review_cycle,
|
|
"_mark_failed_bypass_advisory_stale": git_review_cycle,
|
|
"_review_binding_precondition_error": git_review_cycle,
|
|
"_review_cycle_infra_failure": git_review_cycle,
|
|
"_run_non_committing_review_cycle": git_review_cycle,
|
|
"_run_reviewed_stage_cycle": git_review_cycle,
|
|
"_stage_candidate_for_review": git_review_cycle,
|
|
"_verify_reviewed_commit_binding": git_review_cycle,
|
|
"_check_evolution_commit_stage": git_evolution,
|
|
"_evolution_commit_authority": git_evolution,
|
|
"_evolution_publication_stopped_result": git_evolution,
|
|
"_preserve_evolution_orphan": git_evolution,
|
|
"_record_evolution_commit_receipt": git_evolution,
|
|
"_CONTENT_OMITTED_PREFIX": git_repo_edit,
|
|
"_check_shrink_guard": git_repo_edit,
|
|
"_repo_write": git_repo_edit,
|
|
"_str_replace_editor": git_repo_edit,
|
|
"_binding_relative_path": git_vcs_ops,
|
|
"_ff_pull": git_vcs_ops,
|
|
"_git_diff": git_vcs_ops,
|
|
"_git_status": git_vcs_ops,
|
|
"_limit_git_output": git_vcs_ops,
|
|
"_pull_from_remote": git_vcs_ops,
|
|
"_restore_to_head": git_vcs_ops,
|
|
"_revert_commit": git_vcs_ops,
|
|
"_vcs_binding": git_vcs_ops,
|
|
"_vcs_result": git_vcs_ops,
|
|
}
|
|
|
|
|
|
def test_git_leaves_are_non_catalog_owners_without_git_backedges():
|
|
for module in _LEAVES:
|
|
source_path = pathlib.Path(module.__file__)
|
|
tree = ast.parse(source_path.read_text(encoding="utf-8"))
|
|
assert not any(
|
|
isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
|
|
and node.name == "get_tools"
|
|
for node in tree.body
|
|
)
|
|
# No import-time backedge onto the facade: the leaves reach parent-owned
|
|
# helpers only at call time through their _git() handle.
|
|
for node in tree.body:
|
|
if isinstance(node, ast.ImportFrom):
|
|
assert node.module != "ouroboros.tools.git", module.__name__
|
|
if isinstance(node, ast.Import):
|
|
assert all(a.name != "ouroboros.tools.git" for a in node.names), module.__name__
|
|
|
|
|
|
def test_git_catalog_schema_bytes_and_handler_owners_are_stable():
|
|
entries = git.get_tools()
|
|
assert tuple(entry.name for entry in entries) == (
|
|
"commit_reviewed",
|
|
"vcs_commit_reviewed",
|
|
"vcs_status",
|
|
"vcs_diff",
|
|
"vcs_pull_ff",
|
|
"vcs_restore",
|
|
"vcs_revert",
|
|
)
|
|
schema_bytes = json.dumps(
|
|
[entry.schema for entry in entries],
|
|
sort_keys=True,
|
|
ensure_ascii=False,
|
|
separators=(",", ":"),
|
|
).encode()
|
|
assert hashlib.sha256(schema_bytes).hexdigest() == (
|
|
"729fdf1425126168c7408e431611f70ddd11139fa1c4161628fbcec7a27bf8ec"
|
|
)
|
|
assert {
|
|
entry.name: (entry.handler.__module__, entry.handler.__name__)
|
|
for entry in entries
|
|
} == {
|
|
"commit_reviewed": ("ouroboros.tools.git", "_repo_commit_push"),
|
|
"vcs_commit_reviewed": ("ouroboros.tools.git", "_repo_commit_push"),
|
|
"vcs_status": ("ouroboros.tools.git_vcs_ops", "_git_status"),
|
|
"vcs_diff": ("ouroboros.tools.git_vcs_ops", "_git_diff"),
|
|
"vcs_pull_ff": ("ouroboros.tools.git_vcs_ops", "_pull_from_remote"),
|
|
"vcs_restore": ("ouroboros.tools.git_vcs_ops", "_restore_to_head"),
|
|
"vcs_revert": ("ouroboros.tools.git_vcs_ops", "_revert_commit"),
|
|
}
|
|
|
|
|
|
def test_git_facade_reexports_every_moved_identity():
|
|
"""``tools/git.py`` keeps the exact objects, so existing importers and
|
|
``inspect.getsource`` consumers see no identity change."""
|
|
for name, owner in _MOVED_OWNERS.items():
|
|
assert hasattr(git, name), name
|
|
assert getattr(git, name) is getattr(owner, name), name
|
|
owned = {name for module in _LEAVES for name in vars(module)}
|
|
assert set(_MOVED_OWNERS) <= owned
|
|
|
|
|
|
def test_git_extraction_size_bounds_have_meaningful_headroom():
|
|
counts = {
|
|
module.__name__: len(
|
|
pathlib.Path(module.__file__).read_text(encoding="utf-8").splitlines()
|
|
)
|
|
for module in (git, *_LEAVES)
|
|
}
|
|
assert counts["ouroboros.tools.git"] <= 1800
|
|
assert all(count <= 1000 for name, count in counts.items()
|
|
if name != "ouroboros.tools.git")
|
|
assert 700 <= counts["ouroboros.tools.git_review_cycle"] <= 1000
|