From 5bc3195f983f2474f9858a672dc1f02be3072766 Mon Sep 17 00:00:00 2001 From: Bryan Johnson Date: Thu, 28 May 2026 18:28:21 -0700 Subject: [PATCH] =?UTF-8?q?v0.8.30:=20write/mutate=20tool=20validation=20p?= =?UTF-8?q?ass=20=E2=80=94=202=20fixes;=20rollback=20proven=20reliable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested all mutating tools (nc_table/nc_add_route/nc_insert_protocol/ nc_create_thread/nc_make_jump/nc_tclgen) on a throwaway copy: every change is journaled and rolls back byte-identical across --session/--entry/--target/ --last granularities. Fixed nc-create-thread --host brace-collision (emitted invalid TCL { HOST x} }; now balanced { HOST x }, and { HOST {} } when omitted) and lessons.sh:142 printf option-injection. Read fixture verified untouched. Co-Authored-By: Claude Opus 4.7 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ MANIFEST | 10 +++++----- VERSION | 2 +- larry.sh | 2 +- lib/lessons.sh | 2 +- lib/nc-create-thread.sh | 8 +++++++- 6 files changed, 49 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd9f55..9cb5ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,40 @@ All notable changes to `cloverleaf-larry` / `larry-anywhere` are recorded here. Versioning is loose-semver; bumps trigger the in-process self-update on every running client via `LARRY_BASE_URL` + `MANIFEST`. +## v0.8.30 — 2026-05-28 + +**★ WRITE/MUTATE TOOL VALIDATION PASS + journal-rollback foundation verified — +2 real bugs found & fixed.** Ran every config-mutating tool against a COPY of the +real 24-site Cloverleaf integrator fixture (`/tmp/clvf_writetest_integrator`, the +read fixture left untouched), proving each mutation (a) applies, (b) journals, and +(c) rolls back BYTE-IDENTICAL to the original. nc_table (add/delete/replace/create), +nc_add_route, nc_insert_protocol (end + after-anchor), nc_create_thread (tcpip/file, +±connect-from), nc_make_jump (gen + e2e insert), nc_tclgen (all 7 templates) all +verified. Rollback validated across ALL granularities: `--session`, `--entry`, +`--target`, `--last N`, the 2-entry chain unwind (newest-first), and the create→delete +path. The journal rollback foundation reliably restores byte-identical originals. + +- **`nc-create-thread.sh` HOST brace-collision (malformed NetConfig).** The block + template inlined `{ HOST ${HOST:-{}} }`. When `--host` was supplied (the common + case for a tcpip client/outbound), the `}` closing the parameter default collided + with the template's closing brace, emitting `{ HOST 10.9.9.9} }` — one extra `}`, + brace-imbalanced (-1), invalid TCL that Cloverleaf would reject. Now the HOST field + is precomputed into `$HOST_FIELD` (real host, else `{}`) and referenced cleanly: + `{ HOST ${HOST_FIELD} }`. Only triggered with `--host`; the empty-host/file case was + already correct. `nc-make-jump.sh` was NOT affected (it uses `{ HOST ${host} }`). +- **`lessons.sh:142` printf option-injection.** Same class fixed in v0.8.29 (and + flagged there as out-of-scope): `printf '---\n\n'` parsed `---` as printf options + → `printf: --: invalid option`, dropping the markdown rule from `lessons.sh export` + bundles. Now `printf '%s\n\n' '---'`. (The in-loop `printf '\n---\n\n'` on line 151 + is safe — the leading `\n` shields the dashes.) + +KNOWN / TRIAGE (not fixed this pass): the journal records the table `target` path with +the lowercase `tables/` segment from `nc-table.sh`'s `modify_via_csv` even when the file +lives under `Tables/` (capital). Restore works on case-insensitive filesystems (macOS +APFS, Windows) but could miss on a case-sensitive Linux mount. Low-risk for current hosts; +flagged for a path-normalization follow-up (do not patch blind — needs a real +case-sensitive box to verify against). + ## v0.8.29 — 2026-05-28 **★ READ/INSPECT TOOL VALIDATION PASS — 6 real bugs found & fixed.** Ran every diff --git a/MANIFEST b/MANIFEST index 4a6c90f..662b467 100644 --- a/MANIFEST +++ b/MANIFEST @@ -23,16 +23,16 @@ # scripts/make-manifest.sh and bump VERSION. # Top-level scripts -larry.sh 219c0b4f84aabec17baec7ba20c47849364bce9039bbcaa07ed7ba81b7b38a05 +larry.sh 5f7c82ac08e6be85db8acaf314fcbdc394ac6182f5f784aba8540c05cb139172 larry-tunnel.sh 6b050e4eeab15669f4858eaf3b807f168f211ced07815db9521bc40a093f6aaa larry-auth.sh a220cdf7878569dc3028951ee57fc8d5e706a8ca5c6aa45347b58facb386f831 larry-rollback.sh 91b5e9aa6c79266bf306dcfba4ca791c07971bd6924d67a779037531648aa6d0 install-larry.sh fa36e23a39eacbd0d7ecedd3b42131902f816ee7e98241dfc6e28c6e4ba80423 # Metadata -VERSION 14624c56b466c22dbace115e50c329bc4bea74a2c25e1f3aa481766ea49ddff7 +VERSION fe9f7fe00061bf3b44b38df8fcaa8d09d689c6ee8be0fee57e7d3fe528d18e50 MANUAL.md c64bd0251a51ad150508b4e1185355bc4826a64071d4de339f92ed550dbfacde -CHANGELOG.md f3a6ac02750188f6cec37e1d7454424c363706f2f9a8a6b041b449b1d783479c +CHANGELOG.md 75b131794cc273ba1dba430637008c975b2532bfc2bcc99cc9fd65bd12701537 # Agent personas (system-prompt overlays) agents/larry.md 0a1ef737e7fc133ab35be09f79c3a4df33de814e0404b69b950932d0c8a01be1 @@ -62,7 +62,7 @@ lib/ssh-helper.sh 18df1f1f1936c930ba0197c0e0b4bd89c027500de99b56067b620ca9144f6e lib/headers-sync.sh 47b1946f807b213a2e77cec71128a84a35f103e12fea13ae88d24610d8ee817a # Logging / capture -lib/lessons.sh 45ea4fdadb843701cd3e87f6a0011ba4097978661851ebc9098ad22ea219efb1 +lib/lessons.sh 225e899ed72ce20906cc454c5f5db87d605859e5e17431731a2ce481623f4e16 lib/journal.sh 11c62a2d47b6b67a2f423fd8b86c454126df18d2dc3e150233bbd08293e39fe7 # HL7 utilities @@ -95,7 +95,7 @@ lib/nc-status.sh fa08c5e48704d3d17e2206dafc8522ae7668b7a2f9b97f3521e05fd0ba73944 lib/nc-table.sh a6d5c11dd460cfb100ea50c74d57c1a46ef49112632037534a32cd28600abe7f lib/nc-xlate.sh 8621e6f0ef55524dd6ecba91fee055cf9cdc168791e75ba7c15d9bf501fe09bf lib/nc-smat-diff.sh 9c04d9e2f35f22c78d5f3c40a884ed23a3b6aaabc53ee27dfbfb66ab3166a567 -lib/nc-create-thread.sh 5a9d5407c117183cad831d6b95f0e785b1b806f5ccc67f803c12b3695882b5b7 +lib/nc-create-thread.sh e35b0ee27f2c0327928adc21467f2b9d5a29f7436e5b89773f65420281739df7 lib/nc-tclgen.sh 5b8e73d7f6950a2b84f563132562ea82f62f4acac907257e233c7e68d85506c9 lib/nc-parse.sh 52fef42d7a4b361534ab0d921deef74586dfeb6c199c941cebb55abcc2c39d4f lib/nc-paths.sh 388d2f4560736587a01218cadc1de612cd59e392819d16db2f56f19174c1111b diff --git a/VERSION b/VERSION index b5f1919..663a808 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.29 +0.8.30 diff --git a/larry.sh b/larry.sh index 14d2f73..59b6b10 100755 --- a/larry.sh +++ b/larry.sh @@ -78,7 +78,7 @@ set -o pipefail # ───────────────────────────────────────────────────────────────────────────── # Config # ───────────────────────────────────────────────────────────────────────────── -LARRY_VERSION="0.8.29" +LARRY_VERSION="0.8.30" LARRY_HOME="${LARRY_HOME:-$HOME/.larry}" # ───────────────────────────────────────────────────────────────────────────── diff --git a/lib/lessons.sh b/lib/lessons.sh index 85a27e7..91b4772 100755 --- a/lib/lessons.sh +++ b/lib/lessons.sh @@ -139,7 +139,7 @@ cmd_export() { printf 'Source: `%s` (host `%s`)\n\n' "$LESSONS_DIR" "$(hostname 2>/dev/null || echo unknown)" printf 'Send this back to home-Larry (paste into chat) so it can be committed\n' printf 'to the canonical agents/ persona files in cloverleaf-larry.\n\n' - printf '---\n\n' + printf '%s\n\n' '---' # Walk files newest-first, optionally filtered by --since find "$LESSONS_DIR" -maxdepth 1 -name '*.md' -type f 2>/dev/null \ diff --git a/lib/nc-create-thread.sh b/lib/nc-create-thread.sh index c31c6e8..04821c6 100755 --- a/lib/nc-create-thread.sh +++ b/lib/nc-create-thread.sh @@ -69,6 +69,12 @@ case "$DIRECTION" in *) die "bad --direction" ;; esac +# HOST field value: a real host when --host given, else the empty Tcl list {}. +# NB: do NOT inline this as ${HOST:-{}} inside the heredoc — the trailing `}` +# of the parameter default collides with the template's closing brace and +# emits `{ HOST 10.9.9.9} }` (one extra `}`, malformed TCL). v0.8.30. +if [ -n "$HOST" ]; then HOST_FIELD="$HOST"; else HOST_FIELD="{}"; fi + # Build the protocol block build_block() { cat <