Daveswo 3c4947ee65 Fix CRLF corruption in fx.sh, add .gitattributes to prevent recurrence
The previous commit's fx.sh was silently checked out with CRLF line
endings because this clone's core.autocrlf was true -- git converted
LF to CRLF on checkout, and every subsequent edit/copy carried that
corruption forward. Undetected by `sh` on the dev host (tolerant of
CRLF), but busybox ash on the actual AdaptiveOS target is not: booting
the resulting apkovl produced real syntax errors and ": not found" on
every corrupted line, confirmed by testing the rebuilt ISO in QEMU.

Fix: stripped all CR bytes, set core.autocrlf=false locally, and added
.gitattributes (* text=auto eol=lf) so this can't recur for any future
clone regardless of the cloning user's global git config.
2026-08-22 02:16:47 -04:00

title, emoji, colorFrom, colorTo, sdk, pinned, license, license_name, license_link
title emoji colorFrom colorTo sdk pinned license license_name license_link
Self-Healing Autopoietic Shell 🔁 indigo purple static false other use-only-no-modify-no-sell LICENSE

Self-Healing Autopoietic Shell

A shell function that learns from its own failures and doesn't fail the same way twice.

What it does

run command → fails → ask for a fix → persist the fix → retry → succeed

The next time that exact command is run, the learned fix is applied automatically before the command itself — no failure, no prompt. The knowledge lives in a plain text file (p) that you can copy to any other machine to transfer what this shell has learned.

  • Zero infrastructure. Pure POSIX shell. No database, no ML model, no network calls.
  • Transferable cognition. p is just command=fix lines. scp p otherhost:~/p and the other machine inherits every fix you've ever taught this one.
  • Self-modifying, not self-executing. It never guesses a fix on its own — a human (or another process) supplies it once, and the loop remembers it forever after.

The pattern (41 bytes)

f(){ $@||{read x&&bash -nc$x&&echo$x>>p&&eval$x&&f"$@";};}

This is the minimal, unapologetically golfed core: run $@; if it fails, read a replacement command, sanity-check it parses, log it to p, eval it, and recurse. It's the idea in its smallest possible form — fragile on purpose, to show the mechanism with nothing hidden.

The hardened version (src/f.sh)

The golfed version above breaks on quoting, doesn't distinguish between different failing commands, and recurses instead of looping. src/f.sh is a POSIX-portable version used in production (it's what boots inside AdaptiveOS):

f() {
    FIX=""
    while IFS= read -r line; do
        case "$line" in
            "$*="*) FIX="${line#"$*="}" ;;
        esac
    done < p
    until { eval "$FIX" 2>/dev/null; "$@"; }; do
        printf '\n[LEARN] "%s" failed. Enter a fix: ' "$*"
        read -r n
        [ -n "$n" ] || return 1
        echo "$*=$n" >> p
        FIX="$n"
    done
}

Differences from the 41-byte original:

  • Looks up the fix keyed by the exact command, so p can hold fixes for many different failing commands, not just the last one.
  • Uses until/loop instead of self-recursion.
  • Applies the learned fix proactively on every subsequent call, not just after a fresh failure.

Usage

. src/f.sh
f cat /etc/myapp.conf
# [LEARN] "cat /etc/myapp.conf" failed. Enter a fix (blank to give up):
# > echo "port=8080" > /etc/myapp.conf

Note the fix isn't a replacement for the command — it's a precondition that runs immediately before the original command is retried. f always re-runs the exact command you asked for; the fix's job is to make the environment one where that command now succeeds (create a missing file, export a variable, start a service, etc.).

Run it again later — even in a new shell, as long as p is in the working directory — and it applies the fix silently.

Why "autopoietic"

Autopoiesis (Maturana & Varela) describes systems that produce and maintain themselves through their own operation — a cell doesn't have external code telling it how to be a cell; the process of living is the process of continuously rebuilding itself. f() is a toy version of that idea applied to a shell: the artifact that results from running it (p, the accumulated fixes) changes how the function itself behaves on the next call. The shell is, in a small way, writing its own patches.

See docs/DESIGN.md for more on the mechanism and its limits.

Try it

Open index.html (or this Space) for an interactive in-browser simulation of the learn/fix/retry loop — no shell required.

Files

  • src/f.sh — the hardened, sourceable implementation
  • index.html — interactive browser demo
  • docs/DESIGN.md — design notes, the autopoiesis framing, known limitations
  • test/test_f.sh — automated test of the learn → persist → auto-apply cycle
S
Description
A 41-byte self-modifying shell function that learns from its own failures, plus an automated fix-source layer (fx)
Readme 86 KiB
Languages
Shell 73%
HTML 27%