netscan: stop the scan wedging, and stop it overstating the LAN
The results channel was sized by the number of hosts while each worker sends once per open port, so a subnet with more open ports than addresses filled the buffer and blocked a worker forever. Nothing drains the channel until wg.Wait returns and the sends have no ctx.Done case, so the calling turn hung for the life of the process. Size it by probes. Three more claims the scanner could not back. MaxHosts was spent in order, so the second of two configured subnets got two addresses out of 254 with nothing logged. A run cut short by the cap or the deadline came back indistinguishable from a complete one, and the shipped defaults never fit the budget, so every scan was silently truncated at the top of the range. Scan now reports truncation, targets are taken round-robin, and the default rate and the budget are consistent with a /24. The spoken reply read dotted quads out loud on the voice path. It now says how many devices and what shape, and writes the address list as a note, which is also the only record that Maven put packets on the LAN. The network noun is matched whole so posetil is not a scan, the rate has a stated ceiling, and a repeat question inside two minutes reuses the answer. Both query sources claimed the turn when the capability was off, which let an unconfigured scanner and an unconfigured house swallow questions that used to reach recall. Both now fall through. Found in review of #81 and #80. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TrVSBKe3RFDF4fGYKWYQnX
This commit is contained in:
@@ -295,9 +295,13 @@ func (h *reactiveHandler) queryHome(ctx context.Context, t *queryTurn) (string,
|
||||
return "", false
|
||||
}
|
||||
if h.home == nil {
|
||||
// Claim the turn rather than fall through: "дом не подключён" is true,
|
||||
// and letting general knowledge answer would be an invented house.
|
||||
return "дом не подключён — я его не вижу.", true
|
||||
// Fall through rather than claim the turn. A capability that is off
|
||||
// must not change what an unconfigured box answers: "какая температура
|
||||
// в доме?" on a Maven with no smarthome block reached recall before
|
||||
// this source existed, and a stored fact is a better answer than
|
||||
// "дом не подключён" from a house that was never configured. The
|
||||
// unreachable case is different and homeSummary covers it.
|
||||
return "", false
|
||||
}
|
||||
ctxH, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
@@ -313,9 +317,9 @@ func (h *reactiveHandler) queryNetwork(ctx context.Context, t *queryTurn) (strin
|
||||
return "", false
|
||||
}
|
||||
if h.netscan == nil {
|
||||
// Claim the turn: "сканирование не настроено" is true, and general
|
||||
// knowledge would answer with an invented list of devices.
|
||||
return "сканирование сети не настроено.", true
|
||||
// Fall through, same as queryHome: an unconfigured scanner must not
|
||||
// swallow "сколько устройств в сети?" before recall has looked.
|
||||
return "", false
|
||||
}
|
||||
return h.netscan.scanSummary(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user