Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Redis knowledge-state input

Use Redis knowledge input when the Trustworthiness Checker needs the current value of selected Redis keys, such as a current plan, mode, or adaptation state. Use ordinary Redis Pub/Sub input (redis) for transient events such as “Analyse completed”. The two sources are different:

InformationRedis mechanismChecker source kind
Current mode, plan, anomaly, or adaptation stateSelected key plus keyspace notificationredis-knowledge
Phase completion or component eventPub/Sub channelredis

A keyspace notification is an invalidation, not the new value. The provider rereads each selected key and emits the decoded value only when it differs from the last value it emitted. It does not infer a key by changing a variable name; every knowledge key must be mapped explicitly.

Redis event and knowledge inputs A MAPLE-K phase event enters the Trustworthiness Checker through a Redis Pub/Sub channel, while current Knowledge state enters through a selected Redis key. MAPLE-K phase event Current Knowledge state Redis Pub/Sub channel Selected Redis key Trustworthiness Checker

Quickstart: monitor one key

This walkthrough runs the checker on the host and a disposable Redis server in a Docker container. Run all host commands from the repository root. Docker may pull redis:7-alpine; Podman can replace docker in these commands.

Start and check Redis

docker run --rm -d \
  --name tc-redis-knowledge \
  -p 6379:6379 \
  redis:7-alpine \
  redis-server --notify-keyspace-events KEA

The KEA setting enables the keyspace notifications used by this provider; the checker does not set it on the server. Check the Redis service and setting:

docker exec tc-redis-knowledge redis-cli ping
docker exec tc-redis-knowledge \
  redis-cli CONFIG GET notify-keyspace-events

The first command should return:

PONG

PONG proves that Redis is reachable. It does not prove that the Trustworthiness Checker is running, subscribed, or ready to evaluate input.

Seed and run the checker

This DSRV program exposes the selected state without changing it:

in robot_mode: Str
out observed_mode: Str
observed_mode = robot_mode

The repository stores this program as examples/redis-knowledge/robot-mode.dsrv. Store a JSON string in Redis database 2, the knowledge-source default:

docker exec tc-redis-knowledge \
  redis-cli -n 2 SET robot:mode '"idle"'

From the repository root, start the foreground checker:

cargo run --quiet -- examples/redis-knowledge/robot-mode.dsrv \
  --redis-knowledge-input \
  --redis-knowledge-key robot_mode=robot:mode \
  --redis-knowledge-database 2 \
  --redis-port 6379 \
  --output-stdout

publish_initial defaults to true, so the provider reads the existing key at startup. The stdout sink's exact framing is:

<output-variable>[<zero-based-output-index>] = <DSRV-source-value>

For the sequence in this walkthrough, representative stdout is:

observed_mode[0] = "idle"

The first expected line is the useful readiness observation for the checker: it shows that the source connection, initial snapshot, model evaluation, and local stdout admission have progressed. A running checker process alone proves only liveness.

Change, repeat, and delete the key

In another terminal, still using the repository's Docker container, write a new value:

docker exec tc-redis-knowledge \
  redis-cli -n 2 SET robot:mode '"active"'

The checker should emit a second line. With no other visible updates, the representative output is:

observed_mode[1] = "active"

Writing the same decoded value again sends a Redis notification but does not produce another checker input:

docker exec tc-redis-knowledge \
  redis-cli -n 2 SET robot:mode '"active"'

Delete the key:

docker exec tc-redis-knowledge \
  redis-cli -n 2 DEL robot:mode

A missing selected key becomes Value::NoVal. The stdout sink suppresses NoVal, so deletion produces no replacement line. API consumers can still observe the emitted NoVal state. The checker remains running after each change; it waits for another notification until you stop it.

MAPLE-K: current Knowledge plus phase events

The one-key run tests current state. A MAPLE-K flow commonly combines that state with transient phase events: in this representative layout, Analyse and Legitimate completion use Pub/Sub, while the selected plan uses a database-2 knowledge key. The names are deployment choices, not canonical Redis names.

Representative MAPLE-K Redis input example Analyse completion and Legitimate completion enter through Redis Pub/Sub events, while the current selected plan enters through a Redis Knowledge key. All three feed the Trustworthiness Checker. Analyse completed Current selected plan Legitimate completed Redis Pub/Sub event Redis Knowledge key Redis Pub/Sub event Trustworthiness Checker
MAPLE-K informationRedis kindRepresentative nameChecker input
Analyse completedPub/Sub channelmaple:analyse:completedanalyse_completed
Current selected planKey in database 2maple:plan:currentcurrent_plan
Legitimate completedPub/Sub channelmaple:legitimate:completedlegitimate_completed
Representative MAPLE-K Redis input example Analyse completion and Legitimate completion enter through Redis Pub/Sub events, while the current selected plan enters through a Redis Knowledge key. All three feed the Trustworthiness Checker. Analyse completed Current selected plan Legitimate completed Redis Pub/Sub event Redis Knowledge key Redis Pub/Sub event Trustworthiness Checker

The MAPLE-K example exposes the current plan only after both phase-completion events are true:

in analyse_completed: Bool
in current_plan: Str
in legitimate_completed: Bool

out legitimate_plan: Str
legitimate_plan = if analyse_completed && legitimate_completed then current_plan else "plan-not-legitimate"

The repository stores this program as examples/redis-knowledge/maple-plan.dsrv. Its mixed-source configuration, examples/redis-knowledge/maple-inputs.json5, connects the two event channels and current-plan key:

{
  sources: {
    "maple-events": {
      kind: "redis",
      host: "localhost",
      routes: {
        analyse_completed: "maple:analyse:completed",
        legitimate_completed: "maple:legitimate:completed",
      },
    },
    "maple-knowledge": {
      kind: "redis-knowledge",
      host: "localhost",
      database: 2,
      publish_initial: true,
      keys: {
        current_plan: "maple:plan:current",
      },
    },
  },
}

Stop the one-key checker first if it is still running, then seed and start the mixed-input checker from the repository root:

docker exec tc-redis-knowledge \
  redis-cli -n 2 SET maple:plan:current '"inspect-area"'

cargo run --quiet -- examples/redis-knowledge/maple-plan.dsrv \
  --input-config examples/redis-knowledge/maple-inputs.json5 \
  --redis-port 6379 \
  --output-stdout

Publish the two phase events from another terminal:

docker exec tc-redis-knowledge \
  redis-cli PUBLISH maple:analyse:completed true

docker exec tc-redis-knowledge \
  redis-cli PUBLISH maple:legitimate:completed true

After both true values have been observed, stdout should contain a line framed like:

legitimate_plan[<zero-based-output-index>] = "inspect-area"

The exact index is representative rather than fixed because it depends on which input ticks produce a visible output. Change the selected plan:

docker exec tc-redis-knowledge \
  redis-cli -n 2 SET maple:plan:current '"return-to-base"'

The latest phase values remain retained for the sparse inputs, so the later key update can produce a line framed like:

legitimate_plan[<later-zero-based-index>] = "return-to-base"

Without an input window, the key snapshot and each Pub/Sub event are independent logical ticks. A later plan update does not implicitly start a new MAPLE-K cycle; it is evaluated using the latest retained input values.

The atomic-step window is a timing reduction, not a transaction

A count-bounded variant is:

cargo run --quiet -- examples/redis-knowledge/maple-plan.dsrv \
  --input-config examples/redis-knowledge/maple-inputs.json5 \
  --redis-port 6379 \
  --input-window-mode atomic-step \
  --input-window-update-limit 3 \
  --output-stdout

A time-bounded variant is:

cargo run --quiet -- examples/redis-knowledge/maple-plan.dsrv \
  --input-config examples/redis-knowledge/maple-inputs.json5 \
  --redis-port 6379 \
  --input-window-mode atomic-step \
  --input-window-ms 10 \
  --output-stdout

atomic-step is applied after the sources have been composed. The 10 ms option is a local timing window: updates observed within that window are reduced with last-update-wins per variable. Events near the boundary can fall into different windows. The window does not provide cross-source or global atomicity, does not make Redis writes transactional, and does not guarantee that all events of one MAPLE-K iteration are grouped together. An update limit is likewise a flush threshold; a logical tick is never split merely to satisfy the limit.

Values, options, and limits

Knowledge keys are decoded as JSON5 first, then as plain UTF-8 text:

Stored valueChecker value
trueBoolean
42Integer
3.5Floating-point value
"active"String
{mode: "active"}Object/map
[1, 2, 3]List
inspection robotPlain string fallback
Missing keyNoVal

Python pickle and arbitrary binary values are not supported. A stored JSON5 null is a decoded value and is distinct from a missing key.

OptionEffect
--redis-knowledge-inputSelect knowledge keys as the single input source
--redis-knowledge-key INPUT=KEYExplicitly map a checker input to a key; repeat it
--redis-knowledge-database NSelect the database; default is 2
--redis-knowledge-publish-initial true|falseOverride startup snapshot emission
--redis-knowledge-no-initialDisable the startup snapshot
--input-config PATHCombine named redis-knowledge and other sources
--redis-port PORTFallback port when a source has no port

With --redis-knowledge-no-initial, no startup output is expected from the knowledge snapshot; the first visible result must follow a changed-key notification. The provider subscribes before taking a snapshot and refetches dirty keys, but keyspace notifications are not a durable change log. Rapid writes may be coalesced, so every transient state is not guaranteed to be observed.

Transport failures retry indefinitely by default, starting at 250 ms and backing off to a maximum of 5 seconds. --redis-knowledge-retry-max-attempts N, --redis-knowledge-retry-forever, --redis-knowledge-retry-initial-delay-ms N, and --redis-knowledge-retry-max-delay-ms N adjust that policy. A knowledge source carries data only; it cannot declare the reconfiguration control route.

Redis knowledge is incompatible with MSTLO. --language mstlo uses a dedicated MSTLO runtime, while this provider produces ordinary Value input; the checker rejects the combination with:

Redis knowledge input produces ordinary `Value` input and is unsupported for MSTLO

Use an MSTLO-compatible source and codec instead of a Redis knowledge key when monitoring an MSTLO model.

Troubleshooting

No update appears after SET

Check the notification setting and the exact database/key used by the checker:

docker exec tc-redis-knowledge \
  redis-cli CONFIG GET notify-keyspace-events
docker exec tc-redis-knowledge \
  redis-cli -n 2 GET robot:mode

KEA must be enabled for this provider, and a knowledge mapping must name the same key explicitly.

The initial value is missing

Check whether --redis-knowledge-no-initial was supplied. If it was not, verify the selected database and key, then distinguish PONG (Redis reachability) from the first checker stdout line (source snapshot and evaluation progress).

Pub/Sub works but knowledge does not

Check that the event is under a source's routes, the current value is under a redis-knowledge source's keys, and the key was written in that source's database. Pub/Sub channels do not replace knowledge-key mappings.

Stop and clean up

Stop the foreground Trustworthiness Checker with Ctrl-C before stopping Redis. Then remove the disposable container:

docker stop tc-redis-knowledge

Because it was started with --rm, Docker removes the container after it stops. If an interrupted run leaves the name occupied, use the explicit cleanup:

docker rm -f tc-redis-knowledge