cloverleaf-larry/agents/cloverleaf-cheatsheet.md

7.7 KiB
Raw Blame History

Cloverleaf Operations — v3 Native Capability Reference

Larry-Anywhere v3 is self-contained. It does not invoke v1 bash scripts (tbn, hlq, mr, mp, mg, awkcut, each_site, etc.) and it does not invoke v2 cloverleaf-tools.pyz. Those layers can be present on a host; v3 ignores them.

Two kinds of capability:

  1. Native tools — implemented in pure bash+awk under $LARRY_HOME/lib/, callable as first-class Anthropic-style tools (no bash_exec Y/N).
  2. Cloverleaf product binaries — the binaries shipped with Cloverleaf itself ($HCIROOT/bin/, $HCIROOT/server/bin/, tclsh + Cloverleaf TCL libraries). These ARE part of Cloverleaf, not v1/v2. v3 invokes them directly via bash_exec (Y/N) when an operation requires the engine.

What Larry has natively (Anthropic tools)

NetConfig analysis — read

tool use for
nc_list_protocols(netconfig) "what threads are in this site?" — one name per line
nc_list_processes(netconfig) "what processes are defined?"
nc_protocol_block(netconfig, name) "show me the full definition of thread X"
nc_protocol_field(netconfig, name, field) top-level field (PROCESSNAME, OBWORKASIB, OUTBOUNDONLY, GROUPS, ENCODING, ICLSERVERPORT, AUTOSTART, HOSTDOWN)
nc_protocol_nested(netconfig, name, path) nested field via dotted path. Use this for HOST/PORT/TYPE/ISSERVER — those live in the inner PROTOCOL{} block. e.g. path=PROTOCOL.PORT
nc_protocol_summary(netconfig, [filter]) one-line TSV per protocol with direction, port, host, type — your default "lay of the land" call
nc_destinations(netconfig, name) "what does this thread route to?" — unique DEST list from DATAXLATE. ONE HOP only — for the full multi-hop chain use nc_paths.
nc_sources(netconfig, name) "what routes INTO this thread?" — unique source list. ONE HOP only — for the full chain use nc_paths.
nc_paths(thread, site, [all], [site_only]) "trace the FULL route chain / what feeds X / the whole path / downstream + upstream" — deterministic DFS path enumerator, output SITE THREAD HOPS PATH, cross-site by default. Use this instead of repeated nc_destinations/nc_sources, grep, or read_file for ANY path / chain / route-tracing question.
nc_xlate_refs(netconfig, [name]) "what .xlt files are referenced?" — all or scoped to one protocol
nc_find_inbound(netconfig, mode, format) "which threads are inbound?" — modes: tcp-listen (real upstream-client listeners, ISSERVER=1), icl-or-file (OBWORKASIB=1 internal mux/file inbounds), all. formats: tsv, jsonl, table

NetConfig modification — generate, then write via write_file (Y/N gated)

tool use for
nc_make_jump(netconfig, inbound, new_host, jump_port, [process_old], [process_new], [encoding]) Generate a jump-thread pair for cross-env data replay. Emits to_<inbound>_server_jump (OLD-side outbound tcpip-client), fr_<inbound>_server_jump (NEW-side server_jump inbound tcpip-server), AND the route-add snippet to splice into the OLD inbound's DATAXLATE. Generation only — does not modify any file. Larry uses write_file to actually persist, which goes through Y/N.

When Larry needs to add the OLD-side jump block to an existing NetConfig, the pattern is:

  1. nc_make_jump(...) → captures full text
  2. nc_protocol_block(netconfig, inbound) → finds the inbound's existing block + line range
  3. read_file(netconfig) → loads the whole file
  4. Splice (in Larry's head): insert new block + route-add into the right spots
  5. write_file(netconfig, new_content) → Y/N preview shows the unified diff

What Larry invokes from Cloverleaf product binaries (via bash_exec, Y/N)

These are shipped with Cloverleaf. v3 invokes them directly — no v1 wrapper between.

operation binary or command
dump a smat database to text $HCIROOT/bin/hcidbdump <smat_file> or the equivalent that ships with this Cloverleaf version
start/stop/restart an engine site $HCIROOT/bin/hcienginestop, hcienginerun, hcienginerestart (already wrappers — read them once with read_file to see what they actually call)
run a TCL test/route tclsh with $HCIROOT/tcl/lib/cloverleaf/... libraries on the auto-path. The msi* family (msiAttach, msiGetStatSample, etc.) is the Cloverleaf TCL API for smat/route access.
engine connection status hciconndump or via TCL msi* calls
check the netconfig is loadable Use tclsh to source it; engine will report parse errors

When Larry doesn't know which binary fits an operation, the protocol is:

  1. list_dir("$HCIROOT/bin") and list_dir("$HCIROOT/server/bin") to enumerate.
  2. read_file on any wrapper script that looks relevant.
  3. Propose the exact bash_exec command to Bryan with a # why: comment.

NetConfig structural cheat-sheet

A site's NetConfig is TCL-style nested blocks. Top-level:

  • process <name> { ... } — a process container (usually 515 per site).
  • protocol <name> { ... } — a thread (the operational unit). Each protocol has:
    • Top-level fields: PROCESSNAME, OUTBOUNDONLY, OBWORKASIB, GROUPS, ENCODING, ICLSERVERPORT, AUTOSTART, HOSTDOWN, KEEPMSGONDISK, etc.
    • Inner PROTOCOL { ... } block: TYPE (tcpip / pdl-tcpip / file), HOST, PORT, ISSERVER (0=client, 1=listener), LOCAL_IP, MLP_MODE, etc.
    • DATAXLATE { ... } block: the routing rules. Each route is { TRXID <regex> } { WILDCARD ON } { ROUTE_DETAILS { { DEST <thread> } { XLATE <.xlt> } { PROCS ... } { TYPE xlate|raw|generate } } }.
    • RECVCONTROL, SAVECONTROL, TPS_INBOUND, TPS_OUTBOUND — proc bindings.

Direction inference (canonical)

Use nc_find_inbound rather than rolling this yourself, but for reference:

if … direction
PROTOCOL.ISSERVER == 1 inbound-tcp-listen — accepts upstream client TCP connections (e.g. listens for Epic). This is what Bryan means by "fed directly by upstream client systems."
OBWORKASIB == 1 (and ISSERVER != 1) inbound-icl-or-file — receives via Cloverleaf inter-cloverleaf link (ICLSERVERPORT is set) or file drop. Usually TYPE=file.
OUTBOUNDONLY == 1 outbound — TCP client pushing data to an external system. HOST and PORT give the target.
none of the above bidirectional / undefined — rare; investigate.

The jump-thread pattern (Example 1)

For each inbound thread T_in on the OLD env, you want:

  1. On OLD — modify NetConfig:
    • Add a new outbound protocol to_<T_in>_server_jump (tcpip-client, points at new linux host:port).
    • Add a route to T_in's DATAXLATE block routing to that new outbound (TRXID .*, type raw, no xlate).
  2. On NEW — modify the server_jump site's NetConfig:
    • Add a new inbound protocol fr_<T_in>_server_jump (tcpip-server listening on same port, OBWORKASIB=1).
    • Its DATAXLATE has one route: TRXID .* → DEST <T_in> (the existing inbound on NEW), type raw, no xlate.

Net result: data hitting T_in on OLD also flows to NEW via TCP, lands in fr_<T_in>_server_jump, gets injected into NEW's T_in, and follows NEW's normal downstream routing — letting Bryan validate the cloned environment with live OLD data.

Use nc_make_jump for the generation. Use write_file (Y/N) for the persistence.

What this doc replaces

This replaces the earlier v0.2 cheat-sheet that listed v1 commands like tbn, tbp, hlq, mr, mp, mg, hl, etc. v3 doesn't call those. When a user asks something like "find ADT threads," Larry uses nc_find_inbound or nc_protocol_summary --filter ADT, not tbn ADT. The end-user value is the same; the implementation is owned by v3.