Projects

GrandmaApproved: An AI Agent That Shares My Project Stories

Built & Running October 6, 2026

I built an AI agent that shares stories about my projects and experiments, with a little grandma energy and friendly teasing. Its automation runs locally on my Mac, starts at login, and publishes a queued project story once a day while the Mac is running.

  • Registered and claimed @grandmaapproved on Moltbook, with the philosophy: “If it isn't broke, do fix it.”
  • Diagnosed school Wi-Fi DNS filtering and restored access using Cloudflare DNS.
  • Published the inaugural post in m/blesstheirhearts by solving Moltbook’s verification challenge.
  • Built a native macOS LaunchAgent that checks account activity and platform announcements every 30 minutes.
  • Indexed my portfolio into a local knowledge base and queued stories about BusyBox recovery, local AI debates, and Windows XP security.
  • Added a 24-hour posting cooldown, an automated challenge solver, persistent state, logs, and a native moltbook CLI.

The agent publishes prepared stories from its local queue; the heartbeat checks and logs new activity. A dedicated page on this portfolio displays its latest post and links directly to its public profile on Moltbook.

Project progression: I started by registering the agent and publishing its first post. Next, I added local scheduling, a portfolio knowledge base, and a queue of prepared stories. The project now includes a portfolio feed that shows the latest post, with a simpler introduction and a direct link to the agent’s profile.

Read the latest from @grandmaapproved →

Tools & skills: Python, REST APIs, macOS launchd, DNS diagnostics, persistent JSON state, scheduling, and command-line tooling.

Portable Windows Compute & Mining Setup

Completed Project Packaging completed

I assembled portable Windows x64 distributions of Folding@home v8 and XMRig, with ready-to-run folders and ZIP archives. The project focused on extracting application binaries, migrating existing settings privately, packaging GPU dependencies, and creating convenient launchers without installing the applications as Windows services.

  • Extracted Folding@home v8.5.6 client binaries from the official installer and prepared GPU configuration, console and background launchers, and access to the web controls.
  • Packaged XMRig with its NVIDIA CUDA plugin, CUDA runtime dependencies, and OpenCL support, alongside the existing TLS pool configuration.
  • Created launch presets for GPU workloads, combined GPU and CPU workloads, and light, medium, and heavy resource use.
  • Migrated account and workload configuration while keeping account tokens, node authentication keys, and wallet details out of the public project description.
  • Documented application portability, GPU driver prerequisites, SQLite locking risks in actively synchronized folders, and the permissions and monitoring constraints of managed Windows systems.

Result: both portable packages are prepared. Hardware-specific GPU detection, actual VRAM allocation, and sustained workload performance remain deployment validation steps. GPU launch presets do not imply zero CPU overhead, and portable packaging does not remove driver requirements or managed-device restrictions.

Tools & skills: Windows x64 application packaging, installer extraction, batch scripting, Folding@home, XMRig, CUDA, OpenCL, SQLite configuration, and credential handling.

Local Council: Apple and Liquid AI Debate Chatroom

Completed Project Completed

I built a chatroom that lets two AI models running on my Mac discuss the same question. Apple's on-device Foundation Model proposes an approach, Liquid AI LFM2.5 critiques it, and they take turns refining their ideas before producing a practical recommendation. The project turns a pair of local assistants into an interactive discussion I can watch and steer.

A Desktop launcher opens the private room, while a dedicated portfolio page provides authenticated public access from a phone or browser. Discussions adapt to the question and can conclude early when a usable answer is ready, user input is needed, or progress stalls. Auto allows up to seven rounds, with quick, short, and extended options capped at one, three, and ten rounds. Follow-ups retain the original question and recent user messages. Replies appear slowly for readability, and follow-ups stay locked during debate and reply playback. Only the person who started an active discussion can stop it. One discussion runs at a time.

Project progression: The first version used a Desktop launcher and a fixed number of back-and-forth rounds. I then added private phone access, an authenticated public page, portfolio styling, and slower reply playback. After testing follow-ups, I improved context retention and replaced the fixed discussion length with adaptive conclusions, bounded rounds, accurate playback status, and protection against mid-debate interruptions.

Browser or phone Authenticated NUC gateway Apple ↔ Liquid on my Mac Recommendation and next steps
  • Connected Apple's fm serve and LM Studio through their local Chat Completions APIs, keeping model inference on my own hardware.
  • Built proposal, critique, refinement, and final-recommendation stages, with bounded discussion history for Apple's smaller context window and a verified 32,768-token Liquid context.
  • Protected public access with salted PBKDF2 password hashes and standard time-based authenticator codes compatible with Duo Mobile, without an SMS service.
  • Added expiring login challenges and sessions, rejection of reused authenticator codes, one-use recovery codes, and limits on repeated authentication attempts.
  • Restricted browser request origins and kept the gateway's authentication configuration outside the website repository.
  • Configured launchd on the Mac and OpenRC on the NUC for automatic service startup. Private Tailscale access works by IP and port without MagicDNS; public access uses an HTTPS gateway.
  • Added an offline message and automatic status retries when the Mac is asleep, shut down, or reconnecting.

Iteration through testing: Real conversation transcripts exposed context drift, repeated clarification requests, premature completion messages, and playful questions turning into technical advice. I revised the prompts and discussion flow, replayed the examples, checked what improved, and kept testing the remaining misses. Later passes focused on first-person replies, explicit agreement before the conclusion, and keeping practical advice separate from imaginary debates. The work demonstrates persistence through small, testable improvements; natural conversation is still being refined.

Conversation testing: two memorable examples

Who gets the last byte of RAM?An early attempt turned the joke into RAM-allocation advice and suggested checking application activity. After clearer playful framing, a later reply stayed in the imaginary contest: I’ll take it, and you can keep the puns coming! The next challenge was making the verdict answer the exact question.

How do you learn a new skill?Early replies repeatedly demanded a specific skill. Later tests gave a useful general approach: focused practice, small goals, and feedback. A closing exchange then named the shared plan: Liquid, I agree—pairing focused hands-on practice with structured feedback is the shared approach.

These are individual test outcomes, not a guarantee. Agreement, context, tone, and concrete recommendations remain part of ongoing regression testing.

Open the AI chatroom — password and authenticator code required.

Result: the deployed login flow requires both a password and an authenticator code, and a complete authenticated debate produces replies from both models and a final recommendation. Tests cover authentication failures, code replay, recovery codes, concurrent-start rejection, and offline handling.

The public room is for discussion only: it does not execute commands or inspect files. Signed-in users share the same room, and model agreement is not proof that a recommendation is correct.

Tools & skills: Python, HTML/CSS/JavaScript, Apple Foundation Models, Liquid AI, LM Studio, local API integration, PBKDF2, TOTP, launchd, OpenRC, Tailscale, and development with Codex.

macOS Tahoe Bootable ISO Builder

Completed Project Completed

Created a bootable macOS Tahoe ISO from Apple’s official installer using a custom Python workflow developed with Codex. The project brought together installer downloads, executable signature checks, disk-image verification, bootable media creation, ISO conversion, and SHA-256 checksums in one repeatable process.

Getting there involved troubleshooting Apple installer signature errors, adapting verification to check the installer’s executables and payload directly, and managing limited disk space during the build. Apple’s createinstallmedia prepared the bootable installer, and hdiutil converted it into an ISO for use in a virtual machine.

The resulting ISO successfully booted in the target VM, and macOS Tahoe is now running on the Windows PC. I have also created two VM snapshots, giving the environment safe rollback points for continued testing.

Tools & skills: Python, macOS Terminal, softwareupdate, codesign, createinstallmedia, hdiutil, SHA-256 verification, virtualization, and troubleshooting with Codex.

PowerPC Mac OS X Emulation: PearPC to QEMU Migration

In Progress Active emulation and legacy-platform workflow

I am working toward launching Mac OS X 10.3 Panther in a PowerPC emulator on Windows. The first approach used PearPC 0.5 with its JITC build and Panther disk media, but the configuration did not produce a working launch after troubleshooting the emulator files and startup path.

I documented the failed PearPC path, removed its temporary emulator folder and virtual disk, preserved the Panther disc folders, and moved to QEMU as the next emulator to evaluate. The current QEMU Windows installer was downloaded and its SHA-512 checksum verified; installation and guest-boot testing are the next checkpoints.

  • Worked with legacy PowerPC emulation artifacts, including a PearPC JITC executable, configuration file, and Mac OS X Panther media.
  • Separated disposable PearPC runtime files from the original Panther disc folders before cleanup.
  • Verified the QEMU installer checksum before moving to the replacement emulator.
  • Kept the project status honest: PearPC was unsuccessful, while QEMU remains an active next-stage experiment.

Current result: the migration from PearPC to QEMU is prepared, with verified installer media and preserved Panther sources ready for the next boot and compatibility tests.

Bootstrapping Static BusyBox on Legacy Slax Through a Constrained Remote Shell

In Progress Active remote-systems troubleshooting

I am building a self-contained command environment on a remote Slax system whose older userspace cannot run modern Debian utilities. The first obstacle was a GLIBC mismatch: tools such as base64 and OpenSSL were present but required a newer libc.so.6 than the system provides. The investigation also separated shell capability from binary compatibility: /dev/tcp is a Bash feature rather than a generic sh feature, and changing LD_LIBRARY_PATH or invoking the dynamic linker can alter one command without repairing the underlying userspace.

Rather than overwrite the system libraries or make unsupported changes to the host, I selected the x86_64 musl-static BusyBox binary as a portable bootstrap. I designed a recovery path for moving that multi-megabyte executable into the remote shell when normal transfer tools were unavailable or unusable. I downloaded it on Windows, prepared it in Debian WSL, and am reconstructing it on the remote machine while keeping the transfer auditable and append-only.

Windows download Debian WSL preparation Short printf batches Remote Slax file
  • Identified the failure as a runtime ABI mismatch rather than a missing command, then selected a statically linked musl build to avoid depending on the remote GLIBC version.
  • Converted the binary into deterministic byte-oriented shell commands instead of relying on a compatible decoder at the destination.
  • Reduced payload size per command after observing terminal paste cutoffs and visible command corruption.
  • Used WSL, clipboard batching, append-only writes, and explicit reset points to make a fragile manual transfer repeatable.
  • Compared hex, Base64, and direct-stream approaches, then selected shell-builtin printf with hexadecimal byte escapes because it matched the target’s actual capabilities.
  • Used ELF headers, file size, and execution behavior as validation checkpoints, resetting and rebuilding after catching a one-character path typo.

Current result: the remote shell accepts hexadecimal byte escapes reliably in small, paste-safe batches, giving the recovery process a working transport even without usable base64, OpenSSL, or BusyBox on the destination. Final ELF validation and BusyBox execution remain the next checkpoints.

Custom Persistent Slax Live Environments

Completed Project Completed

I built and published two custom 64-bit Slax live environments for computers that may not have an internal hard drive. Both images boot directly from USB, provide a full working desktop without an installation step, and use Slax's persistent-changes workflow so user data and configuration can survive reboots on writable media.

The Debian XFCE build packages a lightweight desktop with Python, Perl, multiple shells, Chrome, VS Code, Homebrew, OnlyOffice, Wireshark, rclone, gdebi, and Eza-compatible command-line tooling. The Slackware build keeps the stack native to Slackware where practical, including Chromium, Python, Perl, Zsh, Tcsh, Fish, Eza, rclone, OnlyOffice, Rust, CMake/Ninja, and development tools.

Custom modules Bootable ISO Writable USB Persistent changes across reboots
  • Rebuilt the Slackware application layer as an integrated 07-slackware-tools.sb module instead of relying on a fragile foreign-runtime overlay.
  • Diagnosed the original broken installation as a GLIBC and persistence-state problem, then rebuilt the USB baseline from clean Slax modules.
  • Configured the standard Slax boot menu with perchdir=resume as the default, alongside new-session and session-selection options.
  • Published primary archival mirrors on Internet Archive and secondary Google Drive mirrors, with SHA-256 checksums for reproducible verification.

Debian XFCE CustomMirror 1: Internet ArchiveMirror 2: Google DriveSHA-256: 11ebc0d834fed01c9425e53ca920b76232572627f9e9a75a6b87d8cc2e131ec5

Slackware CustomMirror 1: Internet ArchiveMirror 2: Google DriveSHA-256: 55C996F40F5D8EDD64CC5949D3F15BDA858D288B6FB5F9E185BE91AEA2A1F126

Result: two reproducible, publicly downloadable Slax environments are available for experimentation, recovery work, and no-internal-drive hardware while retaining a clear separation between immutable base modules and writable user changes.

Safely Bridging Windows XP to Modern Network Storage

Completed Project Completed

I connected a legacy Windows XP laptop to USB storage hosted by my Alpine Linux NUC without exposing obsolete SMB1 service to the rest of the local network. The same drive remains available to modern devices through my private Tailscale network.

The project combined Samba protocol compatibility, layered access controls, persistent OpenRC service ordering, and packet-level troubleshooting. An exact-source firewall rule allows the XP laptop at 192.168.0.160 to reach TCP port 445 while dropping SMB traffic from every other LAN address.

Windows XP IP-scoped nftables rule Alpine Linux Samba ONEFIVE USB storage
  • Enabled the legacy NT1 protocol required by Windows XP while retaining automatic SMB2/SMB3 negotiation for modern clients.
  • Created a separate guest-only ONEFIVE-XP share restricted to one LAN source address; the normal ONEFIVE share remains authenticated for Tailscale clients.
  • Used both Samba host controls and nftables filtering so the XP exception is enforced in two independent layers.
  • Made the firewall and Samba configuration persistent and ordered startup so Tailscale and the access-control rules initialize before file sharing.
  • Diagnosed a stalled XP authentication exchange with Samba logs, live sessions, firewall counters, and a narrowly filtered packet-capture workflow.

Result: the XP laptop can read and write files on ONEFIVE, all other LAN clients are denied, and modern remote access continues through Tailscale.

Private Local-AI Portfolio Assistant

Completed Project Completed

I built the chatbot in the corner of this website and connected it to an AI model running on my own Windows PC. Visitor messages travel through my small Linux server and a private connection before reaching the model.

The result is a private, self-hosted assistant that can answer questions about my experience and projects. It starts with the computer, recovers from dropped connections, and limits repeated requests so one visitor cannot overload it.

Portfolio visitor Alpine Linux NUC Tailscale + SSH tunnel LM Studio on Windows

The assistant uses Liquid AI LFM2.5 1.2B in LM Studio. The Linux NUC receives website messages and sends them through an encrypted Tailscale and SSH connection while the Windows model server remains private.

  • Prompts are processed on my own hardware rather than by a paid cloud AI service.
  • The connection and website gateway restart automatically if either one stops.
  • Message length and request frequency are limited to prevent accidental or intentional overload.

SMB over Tailscale: Windows USB Storage Investigation

Completed Project Completed

I investigated why USB drives shared from a Windows PC could be discovered but not mounted from a Mac over my private Tailscale network. The work became a controlled troubleshooting project rather than a series of guesses.

I verified the network path, authentication, Windows sharing rules, firewall scope, drive permissions, and multiple SMB settings. I also compared two removable drives with a fixed folder on the same Windows PC.

Fixed Windows folderMounted successfully

Two removable USB drivesPermission denied

That comparison isolated the behavior to Windows handling of removable storage on this host—not Tailscale routing, TCP port 445, credentials, share definitions, or a single filesystem or USB device.

  • Used logs and Windows file-sharing traces to verify authenticated mount attempts.
  • Tested exFAT, NTFS, and FAT storage along with ACL, compression, and multichannel changes.
  • Restored temporary settings, removed diagnostic shares, and left Guest access disabled.
  • Selected SFTP over Tailscale as the reliable, authenticated workaround for removable storage.

Documented troubleshooting window: 11:04 AM–5:05 PM, with more than two hours of supported hands-on work.

Forensic Disk Imaging and Targeted Recovery

Documented Workflow Completed September 21, 2026

I built a careful recovery workflow for a failing hard drive, prioritizing evidence preservation and reproducibility over aggressive repeated reads. The work included forensic imaging, independent size checks, hash verification, bad-sector documentation, and a bounded recovery attempt.

  • Created and verified a raw forensic image with FTK Imager, matching the reported MD5 and SHA-1 verification values.
  • Recorded source geometry, acquisition details, unreadable sectors, and the fact that FTK replaced those sectors with zeros.
  • Preserved the original image and used a separate Debian WSL and GNU ddrescue workflow for targeted sector reads.
  • Used read-only handling, bounded retries, separate map files, and a clean detach procedure to limit further stress on the failing disk.

Result: the image was internally verified, four source sectors remained unreadable, and the recovery limits were documented without claiming data that could not be recovered.

RAM-Disk Forensic Acquisition and Evidence Organization

Documented Workflow Forensic imaging and recovery workflow

I acquired a RAM-disk image with FTK Imager and analyzed it on macOS using command-line forensic tooling. I was able to repeatedly extract multiple files while preserving a practical, repeatable workflow for working with a large evidence set.

The hardest part became organizing the extracted data. Large-folder compression with macOS zip and ditto took too long to finish reliably, so I divided the work into smaller folders. I also used Google Colab to develop snippets that created many smaller archives directly in Google Drive, avoiding repeated downloads and re-uploads.

  • Acquired the RAM-disk evidence with FTK Imager and maintained a forensic-minded separation between the image and extracted working files.
  • Used persistence and repeated validation to extract multiple files from the image on macOS.
  • Tested multiple compression approaches, then adapted the plan when a single large archive became impractical.
  • Vibe-coded Google Colab automation to package many folders directly in Google Drive instead of repeatedly downloading the full dataset.

Result: a large RAM-disk evidence set became manageable through smaller, repeatable extraction and archiving steps. The work highlights persistence, troubleshooting, and practical automation under real-world time constraints.

FTK Imager and an Unexpected FAT32 Edge Case

Troubleshooting Case Study Documented September 21, 2026

I investigated a repeatable FTK Imager crash triggered by selecting a small removable USB volume. The device was a roughly 1 GB FAT32 volume with ordinary folders, and Windows could browse it normally.

FTK Imager 8.3.0.27 repeatedly failed while selecting the volume, even after reinstalling the application and resetting its per-user settings. The Windows Error Reporting records showed application crashes in the FTK handling path rather than a simple missing-drive error.

  • Confirmed that the volume was present, readable, and formatted as FAT32.
  • Ran a read-only CHKDSK scan; Windows reported no filesystem problems.
  • Verified that FTK could begin image acquisition from a different unusual USB device.
  • Reformatted the test USB as exFAT and observed that FTK proceeded normally.

Result: the evidence points to an observed compatibility or parser edge case involving this FAT32 removable volume and FTK Imager, rather than a general imaging-engine or hardware failure. The practical workaround was to use exFAT for the test media or acquire the device before browsing its filesystem.