Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions src/agent_comms/commander_parity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""Parity declarations own matrix generation and the cutover decision.
"""The historical capability matrix and optional native workflow diagnostics.

Delete this transition package when both machines run the native commander.
The declared native phases own completion; this transition package never grants cutover.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from collections.abc import Callable, Iterable
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar
Expand All @@ -15,7 +15,6 @@

if TYPE_CHECKING:
from ..plan_phases import PlanPhase
from ..todos import Todo


class ParityComparison(ABC):
Expand Down Expand Up @@ -48,10 +47,6 @@ class ParityRow(
phases: ClassVar[tuple[type[PlanPhase], ...]]
comparison: ClassVar[Callable[[], ParityComparison]] = UnverifiedParity

@classmethod
def compare(cls, todos: Iterable[Todo]) -> ParityComparison:
return UnverifiedParity()

@classmethod
def verify(cls) -> ParityComparison:
"""Run this declared workflow now; a run is not durable cutover authority."""
Expand All @@ -65,11 +60,6 @@ def rows(cls) -> tuple[type[ParityRow], ...]:
raise ValueError("Parity declarations require unique positive row numbers")
return rows

@classmethod
def done(cls, todos: Iterable[Todo]) -> bool:
history = tuple(todos)
return all(row.compare(history).passed for row in cls.rows())

@classmethod
def matrix(cls) -> str:
"""Render declared facts only; no mutable completion column lives here."""
Expand Down
103 changes: 0 additions & 103 deletions src/agent_comms/commander_parity/measurements.py

This file was deleted.

10 changes: 0 additions & 10 deletions src/agent_comms/commander_parity/rows.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@
StrikeLimitCase,
verify_order_progress,
)
from agent_comms.commander_parity.measurements import StorageComparison
from agent_comms.commander_parity.story import StoryCase
from agent_comms.commander_parity.verdicts import VerdictComparison
from agent_comms.commander_parity.wording import (
ApplicationRunComparison,
DecisionAlertsComparison,
OrderWordingComparison,
PlainWordsComparison,
UnitWordingComparison,
)
from agent_comms.plan_phases import (
Expand Down Expand Up @@ -112,10 +110,6 @@ class PlainWordsParityRow(ParityRow):
native = "`PlainText`, `StrikeReason`"
phases = ()

@classmethod
def verify(cls) -> ParityComparison:
return PlainWordsComparison.read()


class OrderWordingParityRow(ParityRow):
number = 10
Expand Down Expand Up @@ -199,10 +193,6 @@ class StorageHygieneParityRow(ParityRow):
native = "`StorageViolation.scan_observed`, `DiskLow.violations`; live `StorageRule` thresholds"
phases = (ControlPlanePhase,)

@classmethod
def verify(cls) -> ParityComparison:
return StorageComparison.read()


class OrderOnlyContactParityRow(ParityRow):
number = 20
Expand Down
61 changes: 11 additions & 50 deletions src/agent_comms/commander_parity/wording.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import io
import json
import os
from collections.abc import Callable, Iterable
from collections.abc import Callable
from contextlib import redirect_stderr, redirect_stdout
from dataclasses import dataclass, replace
from functools import partial
Expand All @@ -15,7 +15,7 @@

from agent_comms.child_process import ProcessIdentity
from agent_comms.commander.config import CommanderConfig
from agent_comms.commander.order import CommanderContext, OrderFile, refuse
from agent_comms.commander.order import CommanderContext, OrderFile
from agent_comms.commander_parity import ParityComparison, UnverifiedParity
from agent_comms.commander_parity.lifecycle import (
InstalledEvidenceCase,
Expand Down Expand Up @@ -75,62 +75,23 @@ def messages(context: CommanderContext) -> tuple[Message, ...]:


@dataclass(frozen=True)
class WordingComparison(ParityComparison):
observations: tuple[tuple[WordingOutcome, WordingOutcome], ...]
native_owner: ClassVar[type[OrderWords]]
class OrderWordingComparison(ParityComparison):
"""Compare distinct CLI and native request boundaries, never one constructor with itself."""

@staticmethod
def agrees(current: WordingOutcome, native: WordingOutcome) -> bool:
return current == native
observations: tuple[tuple[WordingOutcome, WordingOutcome], ...]
native_owner: ClassVar[type[OrderWords]] = OrderText

@property
def passed(self) -> bool:
return bool(self.observations) and all(self.agrees(a, b) for a, b in self.observations)
return bool(self.observations) and all(
current.accepted == native.accepted for current, native in self.observations
)

def describe(self) -> str:
return (
f"observed={len(self.observations)}; "
f"mismatches={sum(not self.agrees(a, b) for a, b in self.observations)}; "
f"current_refusals={sum(not a.accepted for a, _ in self.observations)}; "
f"native_refusals={sum(not b.accepted for _, b in self.observations)}; "
f"native={self.native_owner.__module__}.{self.native_owner.__qualname__}; "
"compared actual refusal and warning results; no publication"
)

@classmethod
def compare_texts(cls, texts: Iterable[str]) -> ParityComparison:
observed = tuple(
(
WordingOutcome.observe(partial(refuse, text, cls.native_owner)),
WordingOutcome.observe(partial(cls.native_owner, text)),
)
for text in texts
)
return cls(observed) if observed else UnverifiedParity("No actual wording input exists.")


class PlainWordsComparison(WordingComparison):
native_owner = PlainText

@classmethod
def read(cls) -> ParityComparison:
return cls.compare_texts(
strike.reason for todo in history(selected_context()) for strike in todo.strikes
)


class OrderWordingComparison(WordingComparison):
native_owner = OrderText

@staticmethod
def agrees(current: WordingOutcome, native: WordingOutcome) -> bool:
# This row asks whether soft orders are refused, not whether surrounding
# CLI prose emits the same unrelated wording notes as the native request.
return current.accepted == native.accepted

def describe(self) -> str:
return super().describe() + (
f"; current={OrderFile.problems_found.__qualname__}; "
f"mismatches={sum(a.accepted != b.accepted for a, b in self.observations)}; "
f"current={OrderFile.problems_found.__qualname__}; "
f"native_entry={OrderGoalAction.require_ready.__qualname__}"
)

Expand Down
11 changes: 2 additions & 9 deletions src/agent_comms/phase_evidence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar

from agent_comms.commander_parity import ParityRow
from agent_comms.field_codec import FieldCodec
from agent_comms.head_review import HeadReview
from agent_comms.pinned_audit import ForeignAbsenceProbe, GodFunction, ParsedModule
Expand Down Expand Up @@ -351,14 +350,8 @@ def describe(self) -> str:


@dataclass(frozen=True)
class ParityEvidence(PhaseEvidence):
"""The native/current comparison rows, which own the cutover decision."""

def holds(self, reading: PlanReading) -> bool:
return ParityRow.done(reading.todos)

def describe(self) -> str:
return "every parity row passes"
class ParityEvidence(AllEvidence):
"""Native owners supply the facts; the historical comparison matrix cannot overrule them."""


@dataclass(frozen=True)
Expand Down
26 changes: 14 additions & 12 deletions src/agent_comms/plan_phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,6 @@ class ControlPlanePhase(CommanderNativePhase):
)


class ParityPhase(CommanderNativePhase):
after = (RecordPlanePhase, ReviewQueuePhase, ControlPlanePhase)
evidence = ParityEvidence()


class CutoverPhase(CommanderNativePhase):
"""The parity gate passes and the machine-wide commander configuration is gone."""

after = (RecordPlanePhase, ReviewQueuePhase, ControlPlanePhase, ParityPhase)
evidence = AllEvidence((ParityEvidence(), PatternAbsent(r"\bCommanderConfig\b")))


OUTSIDE_PARITY = ("src", ":!src/agent_comms/commander_parity")


Expand Down Expand Up @@ -234,6 +222,20 @@ class CommanderPagePhase(CommanderNativePhase):
)


class ParityPhase(CommanderNativePhase):
"""The native capability owners, not a second matrix of demonstrations, decide completion."""

after = (RecordPlanePhase, ReviewQueuePhase, ControlPlanePhase, CommanderPagePhase)
evidence = ParityEvidence(tuple(phase.evidence for phase in after))


class CutoverPhase(CommanderNativePhase):
"""The native evidence passes and the machine-wide commander configuration is gone."""

after = (ParityPhase,)
evidence = AllEvidence((ParityPhase.evidence, PatternAbsent(r"\bCommanderConfig\b")))


class SkillPhase(CommanderNativePhase):
"""The skill names no script."""

Expand Down
9 changes: 1 addition & 8 deletions tests/test_commander_parity.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
from pathlib import Path

from agent_comms.commander_parity import ParityComparison, ParityRow
from agent_comms.commander_parity import ParityRow

PLAN = Path(__file__).resolve().parents[1] / "plans/commander-native-plan.md"


class MatchingComparison(ParityComparison):
passed = True




def test_generated_prose_is_not_input_to_the_gate(tmp_path):
plan = tmp_path / "plan.md"
plan.write_text(
Expand All @@ -21,4 +15,3 @@ def test_generated_prose_is_not_input_to_the_gate(tmp_path):
assert rendered.startswith("Before\n## Parity matrix\n\n")
assert rendered.endswith("**Dropped deliberately:** historical text\nAfter\n")
assert "Hand edited" not in rendered
assert not ParityRow.done(())
Loading