Skip to content

[Task]: expose a read-only Turn journal inspection surface #3197

Description

@ObVious55

Task ID or area

turn / effect program

Intent

I need design feedback before implementation

Summary

PR #3189 introduced the read-only interpret_turn_journal lens, which projects an existing fenced Turn journal into the canonical EffectTurn shape. It reports exact goal, owner, and Turn-key identity consistency, ordered transaction-phase prefixes, terminal tombstone retention, replay legality, and stable typed violations.

The lens currently has a Python API, focused tests, and reference documentation, but no developer-facing command for inspecting an existing journal. Diagnosing a journal therefore requires reading raw JSON or writing an ad hoc Python caller, which can duplicate interpretation rules and expose more journal data than necessary.

I would like design feedback on a small read-only consumer:

loopx turn inspect-journal \
  --goal-id <goal-id> \
  --agent-id <agent-id> \
  --turn-key <sha256:...> \
  --format json

The command would locate an existing journal through the canonical Turn journal path, reuse the existing schema and locking boundary, call interpret_turn_journal, and render a compact JSON or Markdown inspection result.
PR #3193 owns fail-closed enforcement in the actual settlement replay path. This proposal does not change or duplicate that execution responsibility: it will not participate in resume or settlement, and its result will not be used as execution authority. It only exposes the read-only interpretation already provided by #3189.

Proposed scope

In scope:

  • Add one read-only loopx turn inspect-journal subcommand.
  • Accept exact goal_id, agent_id, and turn_key inputs.
  • Resolve the journal through the canonical runtime root and Turn journal path.
  • Reuse the existing journal schema check and file-locking read boundary.
  • Call interpret_turn_journal as the only source of identity, phase-order, terminal-status, replay-legality, and violation semantics.
  • Render compact JSON and Markdown through the existing CLI output mechanism.
  • Expose only public-safe interpretation fields:
    • journal status;
    • replay legality;
    • goal, owner, and Turn-key match results;
    • ordered phase-prefix result;
    • completed phases;
    • tombstone retention;
    • typed violations;
    • empty next_effect.
  • Treat replay_blocked as a successfully inspected state.
  • Return a non-zero result only when inspection cannot be completed, such as a missing journal, malformed JSON, unsupported schema, or invalid command identity.
  • Add focused synthetic tests proving that inspection does not mutate the journal or invoke any effect.

Out of scope:

  • No arbitrary --journal-path input.
  • No raw journal, stored plan, host result, receipt body, prompt, transcript, credential, private evidence, or local path output.
  • No new replay or journal ledger.
  • No changes to interpret_turn_journal violation semantics in the first slice.
  • No resume or retry decision.
  • No call to execute_turn_driver_settlement.
  • No changes to PR fix(turn): fail closed on key/owner-mismatched settlement replay (GH-C83 M7.1 parity) #3193 settlement identity enforcement.
  • No receipt generation or re-attribution.
  • No state writeback, quota spend, scheduler action, or model/host invocation.
  • No status, dashboard, or attention-queue integration.

Design questions:

  1. Should interpret_turn_journal gain a public read-only CLI consumer, or remain a Python-only refactor/test lens?
  2. Should the JSON output expose the canonical four EffectTurn slots directly, or use a smaller inspection projection?
  3. Should successful inspection with replay_legal=false exit zero, keeping replay legality as diagnostic data?

My preference is to serialize the existing EffectTurn slots, return zero whenever inspection succeeds, and reserve non-zero exits for failures to load or interpret the requested journal.

Relevant files or commands

Likely files:

  • loopx/cli_commands/turn.py
  • loopx/control_plane/effect_program.py
  • loopx/control_plane/turn_driver/executor.py, or the maintainer-preferred bounded home for the existing journal reader
  • tests/control_plane/test_effect_turn_turn_journal.py
  • a focused CLI test such as tests/test_loopx_turn_journal_inspection.py
  • docs/reference/effect-interpreter-packet.md
  • docs/reference/protocols/loopx-turn-v0.md

Existing reference behavior:

  • interpret_turn_journal
  • turn_journal_path
  • _load_journal
  • load_loopx_turn_plan_from_journal
  • loopx turn plan
  • loopx turn run-once

Validation plan

Focused lens and CLI tests:

python -m pytest -q \
  tests/control_plane/test_effect_turn_turn_journal.py \
  tests/test_loopx_turn_journal_inspection.py

Existing Turn regression coverage:

python -m pytest -q \
  tests/test_loopx_turn_executor.py \
  tests/test_loopx_turn_transaction.py \
  tests/test_loopx_turn_driver.py

Existing fake-host walkthrough:

python examples/loopx-turn-fake-host-walkthrough-smoke.py

Additional validation:

  • Run targeted Ruff and Python compilation checks on changed files.
  • Cover legal, blocked, malformed, missing, and unsupported-schema cases.
  • Confirm the journal bytes remain unchanged after inspection.
  • Confirm no host execution, settlement, receipt creation, writeback, quota spend, or scheduler action occurs.

Run:

loopx check \
  --scan-path loopx/cli_commands/turn.py \
  --scan-path loopx/control_plane/effect_program.py \
  --scan-path docs/reference/effect-interpreter-packet.md \
  --scan-path docs/reference/protocols/loopx-turn-v0.md

git diff --check

Run the repository risk-based premerge validation selected for the final diff.

Public/private boundary

  • This issue does not include private benchmark traces, verifier output, credentials, internal document links, raw agent sessions, or local runtime state.
  • I will not run or duplicate maintainer-owned benchmark cases unless a maintainer explicitly splits out a public task.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNeeds maintainer triage or routing.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions