Folderwise: Free AI-Powered Documentation Management

I’ve released Folderwise, a free, open-source framework for keeping documentation readable, current and reviewable, with help from AI agents (assistants that can read and edit your files). It works on ordinary folders of Markdown files, with Git tracking every change. Get it on GitHub →

Folderwise — Human-readable knowledge. AI-assisted upkeep. Markdown and Git underneath. Wherever you need it.

The idea is simple: knowledge should stay readable by people, easy to maintain, and useful long after the conversation that created it.

Why I built it

It’s easy to ask an AI agent a question, solve a problem, and then lose the useful answer in a chat history. It’s just as easy to write a guide and forget whether its instructions still work six months later. [Optional: one sentence about a specific time this bit you, e.g. a recovery you had to redo from scratch.]

I wanted one place for the knowledge I keep coming back to: homelab services, server inventories, recovery procedures, purchase decisions and project notes. Agents can help maintain it, and the result stays something I can read comfortably and review with confidence.

What Folderwise helps you do

  • Give every topic a home. Each knowledge folder has its own Git repository, so a topic like “home network” can evolve independently of “server inventory.”
  • Give agents useful starting context. Shared templates and project instructions help agents follow the same conventions instead of inventing a new structure every session.
  • See what needs another look. Review dates distinguish a recent edit from a recent verification, so a restore procedure you haven’t tested in a year gets flagged. The tools flag documentation that may need checking; they don’t magically verify the facts.
  • Keep changes reviewable. Git history, change records, and checks for metadata and links make it easy to see what an agent changed and why.
  • Keep growing inventories manageable. CSV-backed records can become readable Markdown tables, so a server list stays structured and still reads like documentation.
  • Use the editor you like. Your knowledge stays in plain files you can read and edit without a special application or a hosted knowledge platform.

A visual layer with Obsidian

Obsidian is an optional companion that makes these Markdown files pleasant to explore. Search helps you find a detail quickly, backlinks show which notes refer to the one you’re reading, and graph views reveal how your notes connect.

I’m also trying an Obsidian-plus-iCloud setup for reading on Mac and iPhone. Syncing depends on how you configure Obsidian and your files: Folderwise itself doesn’t currently provide an iCloud sync bridge or automatic Git commits.

Start with one useful topic

You don’t need a huge knowledge base to benefit. Pick something you regularly look up: how to restore a service, what runs on each server, or why you chose a particular setup. Write the answer down once, then give yourself and your agents a consistent way to keep it useful.

Folderwise includes the framework, templates, setup guidance and command-line tooling. Git, Python and uv (a fast Python package manager) are the foundations; using an AI agent or Obsidian is optional.

Get Folderwise for free

Visit Folderwise on GitHub →

The repository has the README, installation steps and the latest improvements. It’s free and open source under the MIT license. Try it with one topic, adapt it to the way you work, and open an issue to tell me what would make it more useful.

Optimize Your MacBook Setup with Mackup and Openboot

When I replaced my MacBook Air, I skipped the usual Migration Assistant approach entirely. A full disk clone carries over years of cruft, forgotten background agents, and app installs that are hard to audit. Instead, I wanted something repeatable: start from a clean OS, restore only what mattered, and end up with an inventory I could reuse for the next disaster recovery or migration.

The tools

Mackup

Mackup backs up application preferences and dotfiles to a synced storage location of your choice, and, more importantly here, it produces a manifest of the apps it manages. That manifest doubles as an inventory of what’s installed on the machine.

Openboot

Openboot is a bootstrap script for fresh Mac setups. It installs your development tooling and, as a bonus, applies the Finder and system preference tweaks I’d otherwise configure by hand on every new machine.

Step 1: Snapshot the old machine

On the outgoing MacBook Air:


brew install mackup
mackup backup

This writes preferences and a manifest to ~/.mackup and a .mackup.cfg file lets you point the storage engine anywhere. I pointed mine at a folder synced by Synology Drive to my local NAS, and copied my home directory and Documents the same way.

Step 2: Set up the new machine clean

On the new MacBook Air, I went through the standard macOS setup without restoring anything from Time Machine or Migration Assistant, then ran openboot to configure my dev environment and system settings in one pass:


curl -fsSL https://raw.githubusercontent.com/openbootdotdev/openboot/main/install.sh | bash

(Check the openboot repo for the current install command, since these things evolve.) Beyond the dev tooling, openboot also applied the Finder and system preference tweaks I usually set by hand, which was a nice bonus.

Step 3: Restore the app inventory

Once Synology Drive synced the .mackup folder to the new machine, I installed Homebrew and mackup, then restored:


brew install mackup
mackup restore

Mackup restores preferences for everything it manages, and just as usefully, it prints out the apps that were on the old machine but not installed through Homebrew. That short list became my to-do list: reinstall those via brew install (or brew install –cask) so the next migration is even simpler.

Why bother

Skipping the full disk migration meant no years-old cruft rode along to the new machine. And centralizing on Homebrew means a single brew bundle dump going forward gives me a complete, versioned inventory of my apps, ready for whenever I need to rebuild again.

How to tell if your iPhone 17 has a Samsung screen

TL;DR: Some iPhone 17 Pros have a slight blue hue tint depending on who made the screen. Samsung panels are the best ones to get (serial numbers starting with G9P, G9N, or G9Q). Apple killed the old sysdiagnose method in iOS 26, but you can now use the free tool 3uTools on Windows or Mac — no jailbreak needed.


With the iPhone 17 Pro, Apple is sourcing OLED panels from different manufacturers. It’s a bit of a lottery — some phones end up with Samsung panels (considered the best), while others come with LG or BOE panels. The catch? A few non-Samsung screens show a noticeable blue tint.

The easiest way to check? Use 3uTools.

  • Runs on both Windows and Mac
  • Works perfectly on iOS 26 (as of Sept 25, 2025)
  • Doesn’t need a jailbreak
  • Spits out your hardware info in seconds, including the display’s serial prefix

Look for G9P, G9N, or G9Q in the serial number — that means you’ve got a Samsung panel.

Apple used to let us pull this info by digging into sysdiagnose logs, but they shut that down in iOS 26. Thankfully, 3uTools makes it super easy. I haven’t had the time to play with all its extra features yet, but for this one purpose alone it’s worth grabbing.

Big shoutout to the developers for keeping it free!

A Curious Discovery: Split DNS and iCloud Private Relay on macOS

I ran into an interesting (and frustrating) networking quirk recently that I thought was worth sharing.
If you’re running Split DNS at home—where a subdomain resolves to your WAN IP externally but your router maps it to a different internal LAN IP when you’re inside the network—you might expect things to “just work.” And usually, they do.

But on macOS, if you have iCloud’s “Private Relay” feature enabled, all of your web browsers may fail to resolve that subdomain to the local LAN address. Instead, they try to go out to the WAN IP, breaking your internal routing.

What makes this tricky is that the behavior doesn’t show up in basic tests. Using tools like nslookup or ping in Terminal still returns the correct local IP. Yet in Safari, Chrome, and Brave, the same domain wouldn’t connect to my internal server. The culprit? iCloud Private Relay.

I had assumed that Private Relay would only affect Safari traffic, but it actually interfered with DNS resolution across the system for all browsers. Once I disabled it, everything immediately started working the way it was supposed to.

So, if you’re running Split DNS at home and notice that your browsers refuse to resolve local resources—even though command‑line tools work fine—check whether iCloud Private Relay is enabled. Turning it off solved the problem for me.

Hopefully this tip saves someone else a few hours of head‑scratching.

It’s official: CISSP endorsed today

Last month I passed the CISSP exam, the journey didn’t stop there. Before you can officially call yourself CISSP certified, there’s one last thing to take care of—the endorsement process.

What’s the Endorsement Process About?

Basically, ISC2 checks that:

  • You actually have at least five years of cybersecurity work experience.
  • You played fair on the exam and didn’t cheat.

You’ll need to complete this step, and pay the ISC2 membership fees, before you can really say you’re CISSP certified.


Here’s some personal news—I’m officially CISSP certified as of today, valid for the next three years! To keep it going, you need to earn Continuing Professional Education (CPE) credits. I’ve put together a list of places where you can get free CPE credits to help with that.


Where to Find Free CPE Credits

Here are some solid options to earn free CPE credits:

Bonus tip: Taking other ISC2 certifications can often count toward your CISSP renewal credits too.


A Few Tips for Renewing Your CISSP

  • Keep an eye on your CPE credits so you don’t have to scramble last minute.
  • Mix it up with webinars, labs, courses, and events to keep learning interesting.
  • Check ISC2’s website every now and then to stay on top of any changes.

Good luck if you’re on this journey—and congrats to anyone who’s passed the exam and completed the endorsement! You’ve earned it.

Self-hosted energy consumption monitoring

I’m always curious about how much electricity my homelab devices are consuming, I have implemented a power consumption monitoring and reporting system at home without the use of any cloud services. Everything is self-hosted locally. Sharing some insights on how you too could do this at home.

Hardware & software requirements

The software stack is

  • InfluxDB v2 for time series database storage.
  • Grafana for visualization and charts of the data.
  • https://github.com/lux4rd0/kasa-collector for self-hosted local fetching of power usage metrics from the local network devices, then storing the data in influxdb.

So, is it working?… kinda

I won’t go over setup and complexity but will share some insights and lessons learned. This setup is working as expected for the individual smart plugs with energy monitoring, the smart power strip metrics are not working.

There are some caveats and issues that I think everyone trying to replicate this setup should know about TP-Link and Tapo devices. Unplug any existing TP-link/Tapo devices from your network before onboarding a new device.

  • The TP-Link Simple Setup (TSS) protocol, which shares credentials from existing devices, can break authentication with the python-kasa library which is a dependency in this stack.

How do you know TSS broke it?

Check it with the kasa discover command and look for “tss”

root@kasapi:~/python-kasa# uv run kasa --debug --username xx --password "xx" --host 192.168.66.240 discover
DEBUG:kasa.transports.klaptransport:Handshake1 posted at 2025-07-23 14:37:43.119547. Host is 192.168.66.240, Response status is 200, Request was 20708b23c4238cf0ce6da978d69f6e6e
DEBUG:kasa.transports.klaptransport:Handshake1 success at 2025-07-23 14:37:43.119597. Host is 192.168.66.240, Server remote_seed is: fff7df5db632df5ff316dd5f5734dd5e, server hash is: 06a480a245ab224d4875bc8fdcd75a68dc0ebf1a61818f5e194bcb5adc5eb3b0
DEBUG:kasa.transports.klaptransport:Device response did not match our challenge on ip 192.168.66.240, check that your e-mail and password (both case-sensitive) are correct. 
DEBUG:kasa.protocols.smartprotocol:Unable to authenticate with 192.168.66.240, not retrying: Device response did not match our challenge on ip 192.168.66.240, check that your e-mail and password (both case-sensitive) are correct. 
== Authentication failed for device ==
	== Discovery Result ==
	Device Type:        SMART.TAPOPLUG
	Device Model:       P316M(US)
	IP:                 192.168.66.240
	MAC:                REDACTED
	Device Id (hash):   REDACTED
	Owner (hash):       xx
	Supports IOT Cloud: True
	OBD Src:            tss
	Encrypt Type:       KLAP
	HTTP Port:          80
	Login version:      2

What it should look like in order for authentication to not be broken you ask?

root@kasapi:~/python-kasa/python-kasa# uv run kasa discover
== Authentication failed for device ==
        == Discovery Result ==
        Device Type:        SMART.TAPOPLUG
        Device Model:       P115(US)
        IP:                 192.168.66.179
        MAC:                REDACTED
        Device Id (hash):   REDACTED
        Owner (hash):       REDACTED
        Supports IOT Cloud: True
        OBD Src:            tplink
        Encrypt Type:       KLAP
        HTTP Port:          80
        Login version:      2


== Authentication failed for device ==
        == Discovery Result ==
        Device Type:        SMART.TAPOPLUG
        Device Model:       P316M(US)
        IP:                 192.168.66.240
        MAC:                REDACTED
        Device Id (hash):   REDACTED
        Owner (hash):       REDACTED
        Supports IOT Cloud: True
        OBD Src:            tplink
        Encrypt Type:       KLAP
        HTTP Port:          80
        Login version:      2

P316M device information when fully authenticated with proper credentials and no ‘tss’

The below is what you should expect to see:

root@kasapi:~/python-kasa/python-kasa# uv run kasa --username xyz --password xyz --host 192.168.66.240 discover
Discovering device 192.168.66.240 for 10 seconds
== None - P316M ==
Host: 192.168.66.240
Port: 80
Device state: False
Time:         2025-07-24 12:45:51-04:00 (tz: America/New_York)
Hardware:     1.6 (US)
Firmware:     1.0.5 Build 250306 Rel.151943
MAC (rssi):   REDACTED (-46)

== Primary features ==

== Information ==
Signal Level (signal_level): 3
Cloud connection (cloud_connection): True
Update available (update_available): None
Check latest firmware (check_latest_firmware): <Action>

== Configuration ==
Auto update enabled (auto_update_enabled): True
LED (led): True

== Debug ==
Device ID (device_id): x
RSSI (rssi): -46 dBm
SSID (ssid): x
Reboot (reboot): <Action>
Device time (device_time): 2025-07-24 12:45:51-04:00
Current firmware version (current_firmware_version): 1.0.5 Build 250306 Rel.151943
Available firmware version (available_firmware_version): None
Matter setup code (matter_setup_code): x
Matter setup payload (matter_setup_payload): MT:x

== Children ==

        == Smart Plug 1 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.3 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 2 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.2 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 3 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 37.5 W
        Voltage (voltage): 119.4 V
        Current (current): 0.33 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.49 kWh
        This month's consumption (consumption_this_month): 0.73 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 4 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 62.0 W
        Voltage (voltage): 119.9 V
        Current (current): 0.54 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.618 kWh
        This month's consumption (consumption_this_month): 0.787 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 5 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 120.1 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>

        == Smart Plug 6 (P316M) ==

        == Primary features ==
        State (state): True
        Current consumption (current_consumption): 0.0 W
        Voltage (voltage): 119.9 V
        Current (current): 0.0 A

        == Information ==
        Auto off at (auto_off_at): None
        Today's consumption (consumption_today): 0.0 kWh
        This month's consumption (consumption_this_month): 0.0 kWh
        Overloaded (overloaded): False

        == Configuration ==
        Auto off enabled (auto_off_enabled): False
        Auto off in (auto_off_minutes): 120 min (range: 0-65536)
        Unable to read value (power_protection_threshold): 'enabled'

        == Debug ==
        Device ID (device_id): x
        On since (on_since): 2025-07-23 17:42:09-04:00
        Reboot (reboot): <Action>


root@kasapi:~/python-kasa/python-kasa# 

Passed the CISSP Exam after 2 weeks of studying

Today I passed the Certified Information Systems Security Professional (CISSP) ISC2 exam after 2 weeks of studying. One of my priority goals during this funemployment period was to become certified to help further cement my expertise in cybersecurity and I will share all of the resources I used in this post to help me get there this fast.

Preamble: I have 5 years professional experience working in Cybersecurity from Google, where I originally started as an IT Support lead before moving internally to become a Security Engineer.

Time commitment: I spent between 8 to 12 hours a day studying for this test over a period of 2 weeks (July 1 to July 14). I took 2 days off in between for a break on weekend days.

  • Every day I completed between 50-110 questions, either via chapter domain quizzes or by using the free DestCert App on the iOS store.

Important items to consider

  • Actual work experience in the field I felt to be invaluable for this exam. Many questions were related to items I had come across before in my Cybersecurity role.
  • The breadth of the CISSP exam is huge and the official study guide I used to study is ~1900 pages long.
  • CISSP exam is not only a technical domain test but heavily focuses on scenario based “think like a manager” style questions. Keywords like “BEST”, “LEAST”, “MOST” and “GOAL” often are indicators that your multi choice options are all likely valid answers but paying extra attention to what the question is really asking is critical for success.

My study resources and my personal rating on them:

  • BOOK (9/10): ISC2 CISSP Certified Information Systems Security Professional Official Study Guide (Sybex Study Guide) 10th Edition
    • 1900 pages long, pretty dense.
    • My focus was reading each chapter summaries, at the end of each chapter there are between 100 to 150 questions specific to the security domain/chapter covered.
    • Each quiz I took I tracked on a spreadsheet with the answer I selected after skimming through chapters or watching video training content.
      • Any quiz question that I failed or got wrong, I took time to understand why I chose the wrong option on my first attempt and then I focused on understanding the correct answer from the answer key at the end of the book.
  • FREE Youtube (10/10): Peter Zerger 8 hour CRAM of all CISSP domains and topics.
    • My first day studying I chose to watch close to 12 hours of video training to “set the stage” before taking the quiz questions from the study guide.
    • He focuses on the vast majority of things you need to know, but because of how condensed each domain is, some minor concepts and things I felt were missing from this… lucky for me another training course I took filled in some gaps (more below).
  • FREE Youtube (10/10): 50 CISSP Practice Questions. Master the CISSP Mindset.
    • Watch this video the day before the exam to make sure your headspace on how to evaluate questions is in the right place. Remember, think like a manager based on how the question is propositioned.
  • LinkedIn Learning video training and practice exams:
  • FREE Crytography DestCert mini masterclass
    • This video does a great job at explaining crypto for the exam.
  • FREE Youtube (10/10): Peter Zerger Cyber Attacks & countermeasures
    • Perfect dedicated video that covers all of the common attacks and the available countermeasures.
  • (5/10) Cybrary CISSP Training by Kelly Handerhan 2024
    • I tried to use Cybrary as a complement resource prior to finding out my library gave me free access to LinkedIn learning courses, I did the first 2 domains videos and wasn’t personally impressed.

How I hacked my study plan?

  1. I used AI / ChatGPT / Perplexity to help me understand certain topics or when I needed concepts explained to me in a different way or tone than the book or videos.
  2. I practiced every day. Domain quizzes using DestCert app while on the treadmill or when sitting down at the computer I would do more questions from the study guide book which are different questions than the DestCert app btw.
  3. I put a deadline to it and chose to go all-in (vs. studying for months). Pay the extra $200 to get “peace of mind” protection in case you may fail your first attempt, I passed on my first try but this exam is tough and things could have easily gone the other way had I not been studying this much.
  4. The most important thing during the test: TAKE YOUR TIME, READ THE QUESTION AND ITS OPTIONS MULTIPLE TIMES before committing to any answer.

Good luck!

Overdue blog update… 10 years at Google and what’s next.

As I write this I realize the last post I made here was on April 30, 2023 which is over 2 years ago and being honest with myself I haven’t been the most active at keeping this site updated due to being busy with career/life and posting content elsewhere like Github.

As of July 2025 I now have some time to work on hobby things like this blog and self-improvement goals like obtaining the CISSP certification (Certified Information Systems Security Professional). Taking a break after 10 years at Google and looking forward to see what’s next on my career journey.

Cheapest domain transfers / registrations

The following aggregators are useful at finding the current best deals for new domain registrations and transfers:

  • https://www.domnest.com/
  • https://www.domcomp.com/
  • https://tld-list.com/

Finding cheapest offsite storage backup

Resources to find cheap storage servers