Files
boxmaker/docs/plans/M6b/02-loopd-consult-wait.md
T
kyleandGrok 4.6 50e9cc2037 docs: M6b implementation plan
Six closed tasks for consult: registry, CONSULT_WAIT, [consult]/[secrets],
ToolName and grants, Decision body, loopback HTTP. Reference is the git bundle
~/boxmaker-refs/m6b-ref.bundle at 5fb05f0. Gate after task 06 is 1611.

Co-Authored-By: Grok 4.6 <noreply@x.ai>
2026-10-03 21:39:31 -07:00

7.1 KiB
Raw Blame History

M6b task 02: CONSULT_WAIT through timeout_for

Branch: m6b. Check it: git branch --show-current prints m6b and git status --short is empty; otherwise stop. Never switch branch. Commit subject: loopd: consult waits one hundred and eighty seconds Log row: the Task cell is M6b/02-loopd-consult-wait.

First action. Run this before any Read of crate source. Do not ls crates/loopd/tests/. Do not Read tests/support/, config.rs, docs/implementer-log.md (except the first 12 lines at the log step). Do not edit crates/loopd/tests/broker_port_ask_wait.rs or crates/loopd/src/config.rs. The quoted blocks are the only edits.

cp docs/plans/M6b/files/crates/loopd/tests/broker_port_consult_wait.rs crates/loopd/tests/

Goal

BrokerPort::timeout_for("consult") is 180 s, or [broker] timeout_ms if that is longer (spec 4.3). The default [broker] timeout_ms stays 120_000. ask_memory is unchanged.

No test sleeps (T27). This task does not talk to brokerd.

Every place that changes

Place What happens there
crates/loopd/src/broker_port.rs CONSULT_WAIT; consult_timeout on new and with_log; timeout_for arm
crates/loopd/tests/broker_port_consult_wait.rs new, given
everything else no change: not config.rs, not broker_port_ask_wait.rs

Files

  • Copy, from docs/plans/M6b/files/ (the same path under it): the new test crates/loopd/tests/broker_port_consult_wait.rs.
  • Modify: crates/loopd/src/broker_port.rs, docs/implementer-log.md.
  • Do not touch: any other file. Do not edit crates/loopd/tests/broker_port_ask_wait.rs (the_wait_for_each_tool does not list consult; leaving it unedited is required). Do not change the default timeout_ms: 120_000 in crates/loopd/src/config.rs.

Facts you need

  • Floor, not a replacement. timeout_for("consult") is self.timeout.max(self.consult_timeout). A configured 300 s wait stays 300 s.
  • Both constructors. new and with_log each name consult_timeout: CONSULT_WAIT. with_ask_wait and with_pending_cap use ..self and need no edit.
  • ASK_MEMORY_WAIT stays. Do not change its value or its arm.
  • The items the edits use. This table is complete.
    Item Signature
    BrokerPort::new new(socket: PathBuf, timeout: Duration) -> BrokerPort
    BrokerPort::with_log with_log(socket: PathBuf, timeout: Duration, log: Box<dyn Fn(&str) + Send + Sync>) -> BrokerPort
    BrokerPort::timeout_for timeout_for(&self, tool: &str) -> Duration
    crate::consult::CONSULT &str, "consult" (task 01)
    crate::memory::ASK_MEMORY &str, "ask_memory"

The edits, exactly

Each quoted "before" block occurs exactly once after task 01.

crates/loopd/src/broker_port.rs

W1. After pub const ASK_MEMORY_WAIT: Duration = Duration::from_secs(180); add:

/// The longest `BrokerPort` waits for a `consult` answer, unless `[broker] timeout_ms` is
/// longer: `brokerd`'s `[consult] timeout_ms` defaults to 180 s (M6 spec, section 4.3).
pub const CONSULT_WAIT: Duration = Duration::from_secs(180);

W2. The struct fields

    socket: PathBuf,
    timeout: Duration,
    ask_timeout: Duration,
    pending_cap: Duration,
    log: Box<dyn Fn(&str) + Send + Sync>,

become

    socket: PathBuf,
    timeout: Duration,
    ask_timeout: Duration,
    consult_timeout: Duration,
    pending_cap: Duration,
    log: Box<dyn Fn(&str) + Send + Sync>,

W3. Inside new, the fields

            socket,
            timeout,
            ask_timeout: ASK_MEMORY_WAIT,
            pending_cap: MAX_PENDING_WAIT,
            log: Box::new(|l| eprintln!("{l}")),

become

            socket,
            timeout,
            ask_timeout: ASK_MEMORY_WAIT,
            consult_timeout: CONSULT_WAIT,
            pending_cap: MAX_PENDING_WAIT,
            log: Box::new(|l| eprintln!("{l}")),

W4. The comment and body of timeout_for

    /// The wait for one call of `tool`, used wherever the port waits for that call: the timeout,
    /// or for `ask_memory` the longer of the timeout and its own wait.
    pub fn timeout_for(&self, tool: &str) -> Duration {
        if tool == crate::memory::ASK_MEMORY {
            self.timeout.max(self.ask_timeout)
        } else {
            self.timeout
        }
    }

become

    /// The wait for one call of `tool`, used wherever the port waits for that call: the timeout,
    /// or for `ask_memory` and `consult` the longer of the timeout and that tool's own wait.
    pub fn timeout_for(&self, tool: &str) -> Duration {
        if tool == crate::memory::ASK_MEMORY {
            self.timeout.max(self.ask_timeout)
        } else if tool == crate::consult::CONSULT {
            self.timeout.max(self.consult_timeout)
        } else {
            self.timeout
        }
    }

W5. Inside with_log, the fields

            socket,
            timeout,
            ask_timeout: ASK_MEMORY_WAIT,
            pending_cap: MAX_PENDING_WAIT,
            log,

become

            socket,
            timeout,
            ask_timeout: ASK_MEMORY_WAIT,
            consult_timeout: CONSULT_WAIT,
            pending_cap: MAX_PENDING_WAIT,
            log,

Steps

  • 1. Copy the given test.

    cp docs/plans/M6b/files/crates/loopd/tests/broker_port_consult_wait.rs crates/loopd/tests/
    
  • 2. See it fail. cargo test -p loopd --test broker_port_consult_wait, timeout 600000 ms: the test target does not compile (E0432 unresolved CONSULT_WAIT).

  • 3. The edits. W1–W5. cargo check -p loopd prints no error and no warning. wc -l crates/loopd/src/broker_port.rs ≤ 500.

  • 4. The tests. cargo test -p loopd --test broker_port_consult_wait --test broker_port_ask_wait: every test passes, 1 in broker_port_consult_wait. the_wait_for_each_tool still passes.

  • 5. Run the gate. cargo fmt --all, then make gate, timeout 600000 ms. Last line gate: ok. Test count 1593 (1592 before, plus 1). After gate: ok, do not add up test result: lines.

  • 6. Log and commit. Task cell M6b/02-loopd-consult-wait. Read only the first 12 lines of docs/implementer-log.md; insert the row under the header. Stage with git add crates/loopd docs/implementer-log.md Cargo.lock, then commit as AGENTS.md says.

Done when

  • make gate prints gate: ok with 1593 tests.
  • git diff HEAD~1 --stat lists only crates/loopd/src/broker_port.rs, crates/loopd/tests/broker_port_consult_wait.rs and the log.

Stop and report if

  • The branch check fails; a "before" block is missing or duplicated; step 2 compiles; you edit broker_port_ask_wait.rs or config.rs; cargo check warns; the_wait_for_each_tool fails; a test outside the named files fails in the gate (git stash -u, rerun, git stash pop, report both).

What the given tests pin

CONSULT_WAIT is 180 s. timeout_for("consult") is 180 s when the port timeout is 120 s, and 300 s when the port timeout is 300 s. timeout_for("recall") stays the port timeout. with_log matches new.