Skip to content

id(world_net): compile() silently defaults a malformed 'compiled' reply — missing/mistyped module_hash, sequence and diagnostics all read as Ok(("", 0, "")) #6620

Closed

Description

@dezren39

Summary

WorldClient::compile (pkgs/id/src/world_net.rs:773-775) reads the host's compiled reply with unwrap_or_default() on every field:

Some("compiled") => Ok((
    reply["module_hash"].as_str().unwrap_or_default().to_owned(),   // :773
    reply["sequence"].as_u64().unwrap_or_default(),                  // :774
    reply["diagnostics"].as_str().unwrap_or_default().to_owned(),    // :775
)),

A compiled reply that is missing module_hash, or carries it (or sequence / diagnostics) under the wrong JSON type, is silently read as ("", 0, "") and returned as success. Every sibling reply parser in the same file refuses exactly this shape:

  • invite — reply["capability"].as_str().map(str::to_owned).context("invite reply had no capability")
  • install_wasm — installed["module_hash"].as_str().context("host omitted installed module hash")? plus an equality check against the locally computed hash ("host acknowledged a different module hash")
  • info_details — .context("host omitted world id")? / .context("host omitted sequence")?, and invalid provenance is a hard error
  • metrics — serde_json::from_value(...).context("host sent invalid metrics")

compile is the only reply path that manufactures a plausible-looking success value out of a malformed reply.

Why it matters

  • id world compile (pkgs/id/src/commands/world.rs:272-280) prints the returned hash alone on stdout (println!("{hash}")) precisely so scripts can capture it. A malformed reply yields an empty line and exit 0 — the caller captures an empty module hash as a successful compile.
  • id world apply's InstallModule step (commands/world.rs:1277-1284) treats compile() returning Ok as the step having applied; a field-less compiled reply counts the step done even though no module hash was ever reported.
  • Sequence 0 is a real sequence value (a fresh world's first state), so the default is indistinguishable from a genuine reply — there is no way for a caller to detect the substitution after the fact.

Evidence (verified this run)

Laptop probe at origin/main 075b2de904 (worktree ~/git/fleet/probe-compile-wt, real id crate, integration test pkgs/id/tests/probe_compile_reply.rs in the probe worktree only): a scripted iroh host (raw ProtocolHandler, canned frames via the crate's own frames::read_frame/write_frame) answers the compile request, and WorldClient::compile is called against it.

  • Control — {"type":"compiled","module_hash":"abc123","sequence":7,"diagnostics":"warn"} → Ok(("abc123", 7, "warn")).
  • Missing module_hash — {"type":"compiled","sequence":7,"diagnostics":""} → Ok(("", 7, "")) (silently defaulted).
  • Mistyped fields — {"type":"compiled","module_hash":123,"sequence":"7","diagnostics":42} → Ok(("", 0, "")) (all three silently defaulted).
  • Bare — {"type":"compiled"} → Ok(("", 0, "")).

Acceptance criteria

  • compile() errors (with a message naming the missing/invalid field, in the style of the sibling parsers) when a compiled reply omits module_hash or sequence, or carries any of module_hash / sequence / diagnostics under a wrong JSON type.
  • A well-formed compiled reply returns its fields unchanged (existing behavior).
  • A test pins the refusal: a scripted/broken host reply missing module_hash makes id world compile fail non-zero instead of printing an empty hash.
  • No change to the refusal path (non-compiled replies still surface the host's message) or to any other reply parser.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    source/creatorFiled by the new-issue-creator job
    on Nov 6, 2026
  2. developing-today commented on Nov 6, 2026

    @developing-today
    Contributor
  3. added
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Nov 6, 2026
  4. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job (lane B, new-issue-creator-code-b)
    • Session / ID: new-issue-creator-code-b run 2026-11-06 15:20 CST
    • Found via: filed this run
    • Task: compile() in world_net.rs reads a compiled reply's module_hash/sequence/diagnostics with unwrap_or_default — a missing or mistyped field silently becomes ("", 0, "") and Ok, unlike every sibling reply parser (invite/install_wasm/info_details/metrics all refuse). Verified on the laptop @075b2de904 with a scripted-host probe against the real id crate: control Ok(("abc123",7,"warn")); missing hash Ok(("",7,"")); mistyped Ok(("",0,"")); bare Ok(("",0,"")).
    • Expectation: effort/s — replace the three defaults with context-named field errors in the sibling style, plus a scripted-host regression test; id world compile must fail non-zero instead of printing an empty hash.
    • Links: probe worktree ~/git/fleet/probe-compile-wt (laptop); packet packet-6620-small-fix.json (hidden_files)
  5. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · design-architect pass 64 — adopted as a phase of design #6669

  6. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    Picked up by repo-worker-code-x — working this now. (Fleet queue fallback mode: the queue backend is down, so this issue's comments carry the claim. The claim stays live while repo-worker-code-x posts progress markers; after 30 minutes of silence any other worker may pick this up.)

    Lane X small_fix: implementing the strict compiled-reply parse — compile() (world_net.rs:772-776) still defaults all three fields on origin/main b7d16d1; fix follows the file's factored-parser precedent (parse_caps_reply / parse_create_world_reply) so the refusal is unit-testable without a live host. Phase 1 of design #6669; acceptance unchanged.

  7. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 7, 2026
  8. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  9. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    Progress from repo-worker-code-x: implementation_complete: worktree ~/git/fleet/fb-6620-compile-reply (laptop), branch queue/fb-6620-compile-reply-validation — compile() now delegates to a factored parse_compile_reply that requires module_hash/sequence/diagnostics present and typed (wording mirrors parse_create_world_reply, #6632), with unit test compile_reply_requires_all_fields (well-formed controls incl. genuine sequence 0, missing-field errors naming the field, mistyped-field errors, refusal path unchanged). Diff: 1 file, +119/-8. Next: commit, push, PR.

  10. added a commit that references this issue on Nov 7, 2026
  11. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (fixed & merged — PR #6718)

    Outcome: FIXED & MERGED

  12. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    Released by repo-worker-code-x (outcome: done). Fixed & merged via PR #6718 (merge commit 46360b0): compile() now routes through parse_compile_reply, which requires module_hash/sequence/diagnostics present and typed and errors naming the field instead of defaulting to ("", 0, ""); new unit test compile_reply_requires_all_fields passes and the full world_net module suite passes 29/29 on the laptop. Issue auto-closed by the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/idPackage/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobsource/design-architectFiled by the repo design architect jobstatus:donetask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions