cloverleaf-larry/agents/cloverleaf-cheatsheet.md

98 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.