Skip to content
Merged
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
3 changes: 1 addition & 2 deletions loopx/control_plane/quota/cli_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,7 @@ def _reference_context(
result = _turn_envelope_result("reference_context", payload=payload,
task_title=task_title, explore_guidance=explore_guidance,
**({"diagnostics": diagnostics} if diagnostics is not None else {}))
# Existing reference-only callers keep their historical wire contract.
return result if diagnostics is None else _apply_context_projection_changes(payload, result)
return _apply_context_projection_changes(payload, result)


def _apply_context_projection_changes(
Expand Down
4 changes: 3 additions & 1 deletion loopx/control_plane/quota/turn_envelope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,9 @@ export function evaluateTurnEnvelope(value: unknown): JsonObject {
if (jsonObject(request.diagnostics)) payload = projectQuotaDiagnostics(payload, request.diagnostics as JsonObject);
if (request.task_title === true) payload = referenceCurrentTaskTitle(payload);
if (request.explore_guidance === true) payload = referenceExploreGuidance(payload);
return jsonObject(request.diagnostics) ? contextProjectionChanges(source, payload) : payload;
// References and diagnostic caps share one edit transport. Untouched facts
// stay in the original caller, including numbers JSON.parse cannot retain.
return contextProjectionChanges(source, payload);
}
if (operation === "build") return buildTurnEnvelope(request);
if (operation === "context_delivery") return prepareContextDelivery(request, LEGACY_QUOTA_CONTEXT_FIELDS);
Expand Down
55 changes: 52 additions & 3 deletions tests/control_plane/test_quota_context_reference_owner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Shared context references preserve full instructions across existing entrypoints."""
from copy import deepcopy
import hashlib
import json

import pytest
Expand Down Expand Up @@ -52,10 +51,15 @@ def test_shared_guidance_reaches_existing_readers_without_changing_settlement(ca
if captured:
projected = _turn_envelope_result("replan_cli_view", payload=shared)
assert graph(projected) == graph(source)
digest = "sha256:" + hashlib.sha256(json.dumps(shared, ensure_ascii=False,
sort_keys=True, separators=(",", ":")).encode()).hexdigest()
# Use the existing source signature, also embedded in captured read
# commands. Python's numeric spelling is not its canonical hash codec.
digest = envelope["action_signature"]["source_decision_hash"]
writer = _turn_envelope_result("replan_view", payload=shared, source_hash=digest, stage="writeback")
assert writer["writeback"]["settlement_plan"] == source["interaction_contract"]["cli_channel"]["settlement_plan"]
changed = deepcopy(shared)
changed["reason"] += " Mutated capture."
with pytest.raises(RuntimeError, match="matching source hash"):
_turn_envelope_result("replan_view", payload=changed, source_hash=digest, stage="writeback")


@pytest.mark.parametrize("mutation", ["different", "wrong-step", "wrong-capability", "missing-owner", "short", "wrong-source"])
Expand Down Expand Up @@ -193,3 +197,48 @@ def unavailable(*args, **kwargs):
for source in ({"ok": False, "diagnostic": "unavailable"},
{"interaction_contract": {"agent_channel": {"work_context": {"sources": []}}}}):
assert _reference_context(source) is source


@pytest.mark.parametrize("value", [1.0, -0.0, 2**60 + 1, float(2**60), 0.000001])
@pytest.mark.parametrize("entrypoint", ["reference", "diagnostics", "cli-detail"])
def test_context_sharing_keeps_original_numeric_facts(value, entrypoint):
from loopx.control_plane.quota.cli_projection import compact_quota_should_run_cli_payload
source, _ = packet()
facts = {"future_measurement": value, "nested": [value, False, None]}
source["future_facts"] = deepcopy(facts)
attachment(source)["future_facts"] = deepcopy(facts)
original = json.dumps(source)

def project(payload):
if entrypoint == "cli-detail":
return compact_quota_should_run_cli_payload(payload,
include_todo_summary_detail=True, include_user_todo_summary_detail=True)
return _reference_context(payload, **({"diagnostics": {}} if entrypoint == "diagnostics" else {}))

shared = project(source)
# JSON spelling distinguishes float/int, negative zero and adjacent large
# integers; Python equality alone cannot establish that facts survived.
assert json.dumps(shared["future_facts"]) == json.dumps(facts)
assert json.dumps(attachment(shared)["future_facts"]) == json.dumps(facts)
assert graph(shared)["result_writeback_guidance_ref"].endswith("optional_attachments[0].guidance")
assert json.dumps(project(shared)) == json.dumps(shared)
assert json.dumps(source) == original


def test_reference_transport_does_not_return_untouched_material(monkeypatch):
from loopx.control_plane.quota import turn_envelope
source, _ = packet()
body = "Untouched supporting material. " * 2048
source["future_facts"] = {"body": body}
responses, real = [], turn_envelope._turn_envelope_result

def observed(operation, **params):
result = real(operation, **params)
responses.append(json.dumps(result))
return result

monkeypatch.setattr(turn_envelope, "_turn_envelope_result", observed)
shared = _reference_context(source)
assert shared["future_facts"]["body"] == body
assert len(responses) == 1
assert body not in responses[0]
Loading