mirror of
https://github.com/logos-co/logos-modules-state-module.git
synced 2026-08-27 13:11:12 +00:00
docs: the walkthrough raced the handshake and silently watched nothing
Running the README walkthrough end-to-end for the first time turned up two
races, both of which pass silently rather than failing loudly:
* `-D &` returns before the daemon is listening, so the `load-module` on
the next line races the socket. Poll `status` instead.
* `watch` is the one-shot subscription this README already warns about:
refused before the registry handshake, and never retried. Subscribing
~2s after load-module answers WATCH_FAILED, and because nothing retries,
every later line still succeeds while observing NOTHING. Measured on
macOS: 2s fails, 6s succeeds.
The second is the dangerous one — the walkthrough "passed" while its only
event assertion was dead. Neither is a module bug; the generated typed
wrapper uses onEventWhenAvailable and needs none of this.
Also record the verified answers, since the contract claims are now measured
rather than reasoned: module_record miss -> {"status":"ok","result":null},
a replayed seq -> "result":false, list_modules -> partial:true.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3ba7861978
commit
be88d0d32d
@@ -151,8 +151,28 @@ lm result/lib/modules_state_plugin.dylib
|
||||
LSDIR=$(mktemp -d) # per-invocation: a leaked daemon poisons later runs
|
||||
export LOGOS_MODULES_STATE_TEST_INGEST=1
|
||||
logoscore --config-dir "$LSDIR" -D -m "$PWD/result-install/modules" &
|
||||
|
||||
# WAIT for the daemon to accept commands. `-D &` returns before it is
|
||||
# listening, so a load-module issued straight after it races the socket.
|
||||
until logoscore --config-dir "$LSDIR" status >/dev/null 2>&1; do sleep 0.5; done
|
||||
|
||||
logoscore --config-dir "$LSDIR" load-module modules_state
|
||||
|
||||
# THEN WAIT AGAIN before subscribing, and do not shorten this.
|
||||
#
|
||||
# `watch` is the hand-rolled subscription this README warns about above: it is
|
||||
# ONE-SHOT and is REFUSED before the registry handshake completes. Subscribing
|
||||
# ~2s after load-module reliably answers
|
||||
# {"code":"WATCH_FAILED","message":"Failed to watch events ..."}
|
||||
# and — because it is one-shot — it never retries, so the rest of the script
|
||||
# runs and passes while silently observing nothing. Measured on macOS: 2s
|
||||
# fails, 6s succeeds. This is a race, not a module bug; the generated typed
|
||||
# wrapper (`logos.modules_state.on(...)`) uses onEventWhenAvailable and needs
|
||||
# none of this.
|
||||
sleep 6
|
||||
logoscore --config-dir "$LSDIR" watch modules_state --event module_state_changed &
|
||||
sleep 2
|
||||
|
||||
logoscore --config-dir "$LSDIR" call modules_state note_transition \
|
||||
dev chat_module 'json:null' 'json:null' unloaded loaded 'json:null' 1
|
||||
logoscore --config-dir "$LSDIR" call modules_state list_modules
|
||||
@@ -161,6 +181,12 @@ logoscore --config-dir "$LSDIR" stop
|
||||
|
||||
An empty optional in a positional slot is `'json:null'` — arity never changes.
|
||||
|
||||
A miss comes back as `{"status":"ok","result":null}` — `null` is the empty
|
||||
optional, **not** a failed call. Verified end-to-end:
|
||||
`module_record nope` answers exactly that, while `list_modules` answers
|
||||
`{"modules":[...],"partial":true,"seq":2}` and a replayed `seq` answers
|
||||
`"result":false`.
|
||||
|
||||
## Thread safety
|
||||
|
||||
Handlers are serialised today by `"concurrency": "single"`, but the registry
|
||||
|
||||
Reference in New Issue
Block a user