Skip to content

id(peers): a negative --depth is an undocumented unlimited crawl — --depth=-1 maps to i32::MAX and stops only when the frontier runs out #2125

Closed

Description

@dezren39

Problem

id peers --depth accepts negative values, and the crawl treats any negative depth as unlimited — a sentinel that is documented nowhere a user can find it:

  • pkgs/id/src/cli.rs:1191-1193 — the flag is a plain i32 with default_value = "1" and no range validation. Its help text documents only 0 = no crawl, 1 = query direct peers (default), N = recursively query up to N levels deep.
  • pkgs/id/src/commands/peers.rs:292 — let max_depth = if depth < 0 { i32::MAX } else { depth };
  • The module doc (peers.rs:26-38) likewise documents only depth 0/1/N and lists the safeguards as --max-peers, --timeout, and visited tracking.

So --depth=-1 (the = form; clap rejects the space form) silently selects an unbounded crawl. There is no overall deadline: the crawl loop (peers.rs:295-347) queries frontier peers sequentially, each allowed the full per-query timeout (--timeout, default 30s, peers.rs:319), so wall-clock grows with frontier size × timeout. The only stops are the frontier running out or the max-peers check — and per #1765 that cap is not hard on all paths (the crawl inserts a whole ListPeers response without re-checking it, peers.rs:328-335).

Evidence (verified this run, main 42796be)

Probe on the laptop (~/git/fleet/probe-2026-10-29-laneB-peersdepth/): the clap derive replicated exactly from cli.rs (clap 4, #[arg(long, default_value = "1")] depth: i32) plus the crawl_peers loop structure copied from peers.rs:291-347 with an in-memory chain graph (peer i announces peer i+1), per-peer timeout dropped (it only makes the negative case slower, never shorter):

CLI --depth=-1 parses to depth=-1
CLI --depth=-7 parses to depth=-7
CLI --depth -1 (space form) rejected: error: unexpected argument '-1' found
depth=  0 -> discovered 1 peers (chain of 51)
depth=  1 -> discovered 2 peers (chain of 51)
depth=  2 -> discovered 3 peers (chain of 51)
depth=  3 -> discovered 4 peers (chain of 51)
depth= -1 -> discovered 51 peers (chain of 51)
depth= -7 -> discovered 51 peers (chain of 51)
depth=-1 max_peers=10 -> discovered 10 peers (cap is the only stop)

Why it matters

A typo, a script that computes a depth and underflows below zero, or a user guessing that -1 means "one level less" turns a quick lookup into a crawl of the whole reachable network — up to the 1000-peer default cap at up to 30s per sequential query in the worst case (hours), issuing a connection + ListPeers RPC to every node it visits. Nothing in --help, the module doc, or any output line tells the user an unlimited mode was selected. Everywhere else this CLI parses numbers strictly and answers misuse with a usage error (e.g. world_line /logs, the REPL's strict parsers); this flag is the outlier.

Related but distinct: #1765 (max-peers is not a hard cap — different defect, the cap check placement; this issue is the depth sentinel). Fixing #1765 does not fix this, and vice versa.

Acceptance criteria

  • Triage pins the contract: either (a) negative --depth is refused at parse time with a clear error (preferred — matches the CLI's strict-parser convention and the documented 0/1/N range), or (b) negative depth is kept as an intentional unlimited mode and is documented in the --help text and module doc, with a startup warning line naming the max-peers bound.
  • A test pins the chosen contract: --depth=-1 either fails to parse / errors before any crawl starts, or (under (b)) crawls past a positive bound in a stubbed-graph unit test of crawl_peers.
  • Positive depths 0/1/N behave exactly as today (existing peers/cli tests pass).
  • If (a): programmatic PeersOptions with a negative depth cannot reach the unlimited branch either (the guard lives at, or below, the crawl_peers entry — not only in clap).

Activity

  1. developing-today commented on Oct 29, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/lowNice to have; do when convenient
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 29, 2026
  3. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed on Nov 1, 2026
  5. 22 remaining items

  6. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

  7. added a commit that references this issue on Nov 2, 2026
  8. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
  9. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    agent-note:v1
    state: triaged (coverage pass)
    Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/low). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
    Found via: coverage pass 2026-11-03

  10. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: triaged — already done; closed with evidence (task 7833, lane code-c, 2026-11-03)

    The fix this issue asked for has landed and the issue was simply never closed:

    • Contract (a) was pinned by triage task 3132 (2026-11-01): refuse negative --depth at parse time and at the crawl entry.
    • Implementation task 5101 opened PR fix(id): refuse negative peers --depth at parse and crawl entry (#2125) #4093, MERGED 2026-11-02T15:41Z at dbe4170 (branch queue/5101-2125-negative-peer-depth).
    • Verified fresh on current main today: pkgs/id/src/commands/peers.rs:124-126 guards the command entry ('peer crawl depth must be non-negative'), peers.rs:324-325 bails at crawl_peers entry on depth < 0, the old 'depth < 0 -> i32::MAX' unlimited sentinel is gone, and the regression test crawl_peers_refuses_negative_depth_before_networking is present at peers.rs:526. cli.rs carries the parse-side range guard.
      Closed as completed via PR fix(id): refuse negative peers --depth at parse and crawl entry (#2125) #4093 by task 7833 on 2026-11-03 (this note was prepared the same run; the original post attempt hit the GitHub secondary rate limit and it is delivered via the action outbox).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientqueue/queuedHas a queued task in the Supabase agent queuesource/creatorFiled by the new-issue-creator 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