macp-sdk-python 0.9.0__tar.gz → 0.9.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {macp_sdk_python-0.9.0/src/macp_sdk_python.egg-info → macp_sdk_python-0.9.1}/PKG-INFO +1 -1
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/pyproject.toml +1 -1
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/base_projection.py +42 -4
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1/src/macp_sdk_python.egg-info}/PKG-INFO +1 -1
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/LICENSE +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/README.md +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/setup.cfg +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/__init__.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/_logging.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/__init__.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/cancel_callback.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/dispatcher.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/participant.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/runner.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/strategies.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/transports.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/agent/types.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/auth.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/base_session.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/client.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/commitment_hash.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/constants.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/decision.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/envelope.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/errors.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/handoff.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/policy.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/projections.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/proposal.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/proto_registry.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/py.typed +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/quorum.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/retry.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/task.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/validation.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk/watchers.py +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk_python.egg-info/SOURCES.txt +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk_python.egg-info/dependency_links.txt +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk_python.egg-info/requires.txt +0 -0
- {macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk_python.egg-info/top_level.txt +0 -0
|
@@ -207,7 +207,7 @@ class BaseProjection(ABC):
|
|
|
207
207
|
#
|
|
208
208
|
# What this does NOT cover: self.phase (assigned directly on
|
|
209
209
|
# BaseProjection by subclasses — see projections.py:84,
|
|
210
|
-
# task.py:
|
|
210
|
+
# task.py:102, handoff.py:70) and any subclass-owned collection
|
|
211
211
|
# (evaluations, objections, accepts, rejections, updates,
|
|
212
212
|
# completions, failures) are never rolled back, because this
|
|
213
213
|
# method has no way to know what a subclass mutated. That is safe
|
|
@@ -219,7 +219,7 @@ class BaseProjection(ABC):
|
|
|
219
219
|
# mutates subclass state and then raises. This is a
|
|
220
220
|
# raise-before-mutate invariant that _apply_mode_message
|
|
221
221
|
# implementations must preserve. BaseProjection is exported for
|
|
222
|
-
# third-party subclassing (see __init__.py:
|
|
222
|
+
# third-party subclassing (see __init__.py:151), and upcoming
|
|
223
223
|
# first-wins/anomaly-tracking logic must keep fallible work ahead
|
|
224
224
|
# of mutations to keep this guarantee honest.
|
|
225
225
|
#
|
|
@@ -242,7 +242,7 @@ class BaseProjection(ABC):
|
|
|
242
242
|
# above is the only mutation of transcript between there and
|
|
243
243
|
# here, so transcript[-1] is the entry this call just
|
|
244
244
|
# appended. But BaseProjection is a public ABC (exported at
|
|
245
|
-
# __init__.py:
|
|
245
|
+
# __init__.py:151) that third parties may subclass, so guard
|
|
246
246
|
# with an identity check rather than popping unconditionally.
|
|
247
247
|
# The two ways the guard could see something else at [-1] are:
|
|
248
248
|
# - a subclass's _apply_mode_message appending to
|
|
@@ -267,7 +267,45 @@ class BaseProjection(ABC):
|
|
|
267
267
|
|
|
268
268
|
@abstractmethod
|
|
269
269
|
def _apply_mode_message(self, envelope: envelope_pb2.Envelope) -> None:
|
|
270
|
-
"""Handle a mode-specific (non-Commitment) envelope.
|
|
270
|
+
"""Handle a mode-specific (non-Commitment) envelope.
|
|
271
|
+
|
|
272
|
+
**Implementations MUST do all fallible work before any mutation**
|
|
273
|
+
("raise-before-mutate"). Parse the payload (``ParseFromString``, the
|
|
274
|
+
one operation that realistically raises here), validate it, and
|
|
275
|
+
decide what to do — *then* assign ``self.phase`` or touch any
|
|
276
|
+
subclass collection. Never mutate and then run something that can
|
|
277
|
+
raise.
|
|
278
|
+
|
|
279
|
+
This is a real contract, not style advice, and it is what makes
|
|
280
|
+
``apply_envelope``'s rollback sufficient. That rollback restores
|
|
281
|
+
``transcript`` and the ``message_id`` dedup set only — it cannot
|
|
282
|
+
restore subclass state, because the base class has no way to know
|
|
283
|
+
what a subclass mutated (a slotted subclass has no ``__dict__`` to
|
|
284
|
+
snapshot, and deep-copying every projection per envelope would be a
|
|
285
|
+
real per-message cost). An implementation that mutates and then
|
|
286
|
+
raises therefore leaves *its own* state half-applied while
|
|
287
|
+
``apply_envelope`` reports a clean rollback and invites the caller
|
|
288
|
+
to retry — a partial apply the base class cannot detect or undo.
|
|
289
|
+
|
|
290
|
+
Every implementation in this SDK honors this today (see the
|
|
291
|
+
per-branch parse-then-mutate ordering in ``projections.py``,
|
|
292
|
+
``quorum.py``, ``task.py``, ``handoff.py``, and ``proposal.py``).
|
|
293
|
+
Two branches come close to the line: ``handoff.py``'s
|
|
294
|
+
``HandoffAccept`` writes the record before reading
|
|
295
|
+
``getattr(p, "implicit", False)``, and ``proposal.py``'s ``Reject``
|
|
296
|
+
appends before reading ``p.terminal`` and ``self.proposals.get(...)``.
|
|
297
|
+
Both are safe only because a defaulted ``getattr``, a protobuf field
|
|
298
|
+
read, and ``dict.get`` cannot raise — not because the ordering there
|
|
299
|
+
is exemplary.
|
|
300
|
+
|
|
301
|
+
``tests/unit/test_projection_rollback_invariant.py`` pins the
|
|
302
|
+
ordering by feeding each branch a payload that cannot parse and
|
|
303
|
+
asserting no derived state moved. Note what that does *not* reach: a
|
|
304
|
+
branch that mutates and then does something else fallible (a raising
|
|
305
|
+
property, an ``int()``, a strict lookup) is not caught, because a
|
|
306
|
+
malformed payload never gets that far. The contract is broader than
|
|
307
|
+
the test — hence stating it here.
|
|
308
|
+
"""
|
|
271
309
|
|
|
272
310
|
def _record_anomaly(
|
|
273
311
|
self,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{macp_sdk_python-0.9.0 → macp_sdk_python-0.9.1}/src/macp_sdk_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|