Protocol Action Packet Migration Contract

September 20, 2026 ยท View on GitHub

Release Boundary

PR #4794 retires protocol_action_packet from freshly constructed quota decisions. The cutover is the first official LoopX release whose source contains this change; source and prerelease builds containing it use the same behavior. Published v1.1.0 artifacts are not changed or silently backported. The release tag identifies that source boundary; this PR does not create a release or choose its date.

The change applies to normal quota, paused quota, live required-read and capability-intent projection, and unsettled-host recovery, including full JSON and Markdown output. It is independent of the opt-in TurnEnvelope view. There is no new runtime flag, replacement summary field, or second decision owner. The existing Envelope and signature schema identifiers stay at v0: the packet was already optional to their readers. New signatures omit its capsule witness; they need not equal signatures of older packet-bearing outputs.

Supported Consumers and Upgrade Order

The supported consumer set for this migration is explicit:

ConsumerNew outputStored v0 input
Bundled quota CLI and Markdown rendererRead interaction_contract, work_lane_contract, scheduler_hint and exact CLI actions; no legacy summary lineContinue displaying the packet when a stored decision contains it
TypeScript Effect reader and Python bridgeprotocol_summary=null; typed obligations and next effects remain authoritativeKeep the supplied summary as an observation, never as execution authority
Python/TypeScript TurnEnvelope builders/readersNo contract_capsule.protocol_action_packet; other signed dimensions remainPreserve verified reconstruction, residue and opaque-summary fallback
Bundled host authority extractionVerify the canonical document and hashes before accepting the actionVerify the stored document and hashes without rebuilding its source

Upgrade readers before changing producers. LoopX v1.1.0 is the tested rollback reader baseline and already accepts missing packets. A client that requires this field or parses its summary must migrate to the typed contracts above before adopting the new producer, or remain on v1.1.0 until adapted. Such a client is not automatically covered by this migration's compatibility claim. No compatibility promise is made for unidentified external clients, changed private forks, or older executable releases that have not been qualified.

Historical Format Support

Support is bounded by format rather than record age: valid protocol_action_packet_v0 observations and their existing v0 Envelope/capsule representation remain readable while the v0 reader contract is supported. There is no scheduled removal of these readers in this migration. A future breaking protocol revision must separately declare its reader-removal and data migration policy; this writer removal cannot authorize it. Storage retention policies and execution-time identity/permission checks remain independent.

Keep protocol_action_packet_fields(), ordered summary reconstruction, verified_with_residue, and unverified_retain_summary. Do not rewrite stored records, regenerate their signatures, or replace an opaque historical summary with today's action text. Missing/mismatched signatures and changed signed fields still fail host admission. Successful historical readback does not re-authorize a stale task or bypass fresh receipt, lease or capability checks.

Qualification and Rollback

The committed historical fixture is produced by actual v1.1.0 source 607c11d75, with synthetic public-safe input. Its stored envelopes and signature hashes are immutable test inputs: current readers must accept valid examples and reject tampering without regenerating the expected signature. The ordinary compatibility fixtures additionally cover absent, v0, opaque and residue forms, quiet waits and user gates. These examples qualify the specified formats and readers, not an unknown production archive.

The repeatable version check exercises eight fresh packet-free decisions (normal, paused, operator gate and exhausted, each ordinary/settled) plus the four frozen release records through actual v1.1.0 reader/host code. It checks canonical source/envelope agreement, host admission and unchanged input records:

# Prepare this pinned checkout and its Node dependencies once; no live state is used.
git worktree add --detach ../loopx-v1.1.0 v1.1.0
npm ci --prefix ../loopx-v1.1.0 --ignore-scripts
uv run --extra test python scripts/verify_protocol_packet_migration.py --reader-checkout ../loopx-v1.1.0
uv run --extra test python -m pytest tests/control_plane/test_protocol_packet_history.py tests/control_plane/test_protocol_packet_retirement_cli.py

The verifier rejects a different or modified reader revision; it does not fetch or install anything itself. Source/envelope canonical documents and host admission must agree. An installed wheel is checked for packaged TS/JSON resources, the real bridge, normal/paused output and signed host admission. Real CLI replay and the combined required-read/capability-intent path are regression tests in this PR.

For rollback, stop starting new host turns, retain all runtime records unchanged, and switch producer and reader together to the tagged v1.1.0 baseline. That producer emits the old packet again; the old reader continues to accept the packet-free records covered above. This is rollback of this field migration, not certification that v1.1.0 can undo unrelated protocol or storage changes. Reverting the writer-removal commit is also possible after resolving intervening code changes; it must not rewrite stored signatures or receipts.

Operating Boundary

Routine quota/status/heartbeat routing stays deterministic and makes no model or external-provider call to replace the summary. Cold summarizer experiments remain explicit, isolated and sidecar-only; they must not persist raw stderr, private session traces or credentials. No other legacy field is retired by this contract. PR approval accepts this scoped migration; normal maintainer merge/release controls remain, and #4447 has its own remaining obligations.