Skip to content

id(world-line): PR #808 — join pump --command-mode kills the session on a parse Message (SSH shows it and continues), and /logs [seconds] is parsed then discarded by both consumers #819

Closed

Description

@dezren39

Problem

PR #808 introduces the shared line grammar (pkgs/id/src/world_line.rs, branch id/phase-11) whose stated contract is that one line "works identically as an SSH command, a piped script line, and a CLI one-off" — and the PR body claims the id world join --command-mode pump and SSH command mode both speak it (#546). Two places break that parity:

1. A typo in the join pump kills the session; on SSH it just shows a message

  • world_line.rs defines WorldLine::Message(String) as "A command that did not parse; the message is shown to the user" (unknown commands, usage: /input <hex>, usage: /logs [seconds], usage: /document <name>).
  • SSH command mode honours that: pkgs/id/src/world_ssh.rs:667-672 renders {message}\r\nworld> and the session continues.
  • The join pump does the opposite: pkgs/id/src/commands/world.rs:1054-1056 maps WorldLine::Message(message) to anyhow::bail!("{message}"), and the pump loop calls pump_command_frame(line)? (commands/world.rs:1007), so the error breaks the writer loop, closes the connection, and ends id world join with a failure exit.

One mistyped /imput … or /logs soon in --command-mode therefore disconnects the user from the world instead of showing the usage line and a fresh prompt. The pump's own test even enshrines the divergence: assert!(pump_command_frame("/nope").is_err()).

2. /logs [seconds] is parsed, validated — and silently discarded by both consumers

  • world_line.rs:29, 78-87 — WorldLine::Logs { seconds: Option<u64> }; a non-numeric argument is a usage error, so the grammar promises the argument means something.
  • SSH: world_ssh.rs:846 maps WorldLine::Logs { .. } to WorldCommand::Logs, discarding seconds (the handler then prints the "event tailing is not available in command mode" stub regardless of the argument).
  • Pump: commands/world.rs:1051 maps WorldLine::Logs { .. } to {"type": "logs"} with no seconds field.

So /logs 5 and /logs 5000 behave identically everywhere, with no hint to the user. Either the frame/handler needs to carry the value, or the grammar should stop accepting (and validating) an argument nothing uses.

Why it matters

The whole point of #546 / F11.5 is one grammar with one behaviour per surface; a shared parser whose error and argument semantics differ per consumer re-creates the divergence the refactor exists to remove, and the pump case is user-hostile: a recoverable typo becomes a disconnect (and a nonzero exit for scripted/piped use of --command-mode).

Evidence

Acceptance

  • In --command-mode, a line that parses to WorldLine::Message is shown to the user and the pump keeps running (matching SSH command mode); only /quit / EOF / a real I/O error ends the session. The pump test asserts the message path does not error and a following valid line still produces its frame.
  • /logs [seconds] either takes effect identically on both surfaces (value carried into the logs request / stub message states what is ignored), or world_line rejects the argument with a usage message that says it is unsupported — in both cases, SSH and the pump behave the same.
  • A parity test runs the same line corpus through both consumers' mappings (the structural-guard style PR id: Phase 11 foundations — F11.10 module split (world.rs, world_session.rs) #808 already uses for the projection) so the two mappings cannot silently drift again.

Activity

  1. dezren39 commented on Oct 25, 2026

    @dezren39
    MemberAuthor

    Triage re-verification on current main af75c8c (2026-10-25 sweep): both halves still reproduce exactly as filed. (1) commands/world.rs:1264 maps WorldLine::Message(message) to anyhow::bail!, and the pump test at world.rs:1301 still enshrines it (pump_command_frame("/nope").is_err()); SSH at world_ssh.rs:850 maps the same variant to WorldCommand::Message and continues. The commands::world suite (5/5 PASS locally this run on a sibling branch) passes with the divergent assertion in place. (2) WorldLine::Logs { .. } discards seconds at both consumers: world.rs:1261 (frame has no seconds field) and world_ssh.rs:846. No fix attempted this run — the pump half touches the same file as PR #860 (#818), so it should land after that merges to avoid a stacked conflict; the /logs half still needs the carry-vs-drop design choice.

  2. dezren39 commented on Oct 25, 2026

    @dezren39
    MemberAuthor

    Scope narrowed by the 2026-10-25 sweep (PR #868 closed as superseded):

    Fixed/superseded on main 74b849b8:

    • Join pump: a parse Message no longer kills the session — main's pump_command() maps it to PumpLine::Say (printed, session continues), with a parity test in the shell-contract test set.
    • Join pump /logs [seconds]: main deliberately replies with a redirect message instead of sending a frame (no logs reader on the join pump; same treatment as /documents), so the "carry seconds in the pump frame" half is superseded by design.

    Still open (the only remainder):

  3. dezren39 commented on Oct 25, 2026

    @dezren39
    MemberAuthor

    Update from the 2026-10-25 13:00 CDT sweep: the remaining SSH half is now implemented in PR #909. WorldCommand::Logs carries seconds: Option<u64>, world_command() threads the parsed value through, and the command-mode reply names the requested window it ignores. Parse tests pin /logs → None and /logs 5 → Some(5). #909 carries Fixes #819 and closes this on merge.

  4. added
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/sweepFiled or worked by an issue-sweep job
    on Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

source/sweepFiled or worked by an issue-sweep jobstatus/needs-triageNot yet triaged; needs a first looktask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions