The Art of Retargetable Workflows: Building a Publishing Nervous System

🤖 Read Raw Markdown

Setting the Stage: Context for the Curious Book Reader

This article explores the methodology behind ‘1-file-4life’ engineering. By treating text files as the canonical source and building automated pipelines for retargeting, we can move beyond platform lock-in and manual content maintenance. This is a blueprint for creators who want to build a publishing nervous system that survives hardware shifts and ecosystem changes.


Technical Journal Entry Begins

MikeLev.in: Alright, this is an article I’ve been working up to. And now that I have multiple Blog targets under the Pipulate system, but with the configuration of those blogs outside the Pipulate Prime repo, I now have to make the decision when I start writing an article like this, which is now officially retargetable content after those last few articles establishing so, I need to decide whether I’m going to talk proprietary day-job stuff and make it publishable on the internal company wiki, or talk extremely general framework, and make it a public article. I want this article to be public. And I will start by showing that configuration file:

The Configuration Actuator

{
    "1": {
        "name": "MikeLev.in (Public)",
        "path": "/home/mike/repos/trimnoir/_posts",
        "preview_port": 4001,
        "pipeline": [
            "sanitizer.py",
            "contextualizer.py",
            "gsc_historical_fetch.py",
            "build_knowledge_graph.py",
            "generate_llms_txt.py",
            "link_injector.py",
            "generate_hubs.py",
            "generate_redirects.py",
            "sanitize_redirects.py"
        ]
    },
    "2": {
        "name": "Pipulate.com (Public)",
        "path": "/home/mike/repos/Pipulate/_posts",
        "preview_port": 4002,
        "pipeline": [
            "contextualizer.py"
        ]
    },
    "3": {
        "name": "Grimoire (Private)",
        "path": "/home/mike/repos/grimoire/_posts",
        "preview_port": 4003,
        "pipeline": [
            "contextualizer.py"
        ]
    },
    "4": {
        "name": "BotifyML (Private)",
        "path": "/home/mike/repos/botifyml/_posts",
        "preview_port": 4004,
        "confluence_parent_id": "123456890",
        "pipeline": [
            "contextualizer.py",
            "confluenceizer.py"
        ]
    }
}

This lets me take an article like this that I’ve started here in the 1-file-4life technical work journal where I don’t have to ever worry about where to start writing. It doesn’t matter if it’s the beginning of an article like this, or beginning to write a prompt for LLM-style AIs, which is more and more often the case. It always starts the same. When I say 1-file-4life, I mean 3 text files:

The Three-File Foundation

  1. The flake.nix file that initially probably touches your Mac or Windows/WSL system as the default flake.nix in the Pipulate repo. Installing Pipulate will get one on your system, whether your system be macOS, Windows with WSL or any old Linux. The Nix declarative execution-environment builder gives us a generic Linux, or it’s really even more abstract than Linux in particular. With Nix and in time Guix (from the GNU project), declarative systems will gradually replace Docker and give you one “work system” or whatever you want to call the environment you set up so that your muscle memory can kick-in sort of system. And it starts with a Nix flake.
  2. A configuration.nix file which probably should come first for those who want to jump into the deep end and have a spare fairly modern machine to throw to the cause. Start declaring your systems with a text-file now, tweak it out to your liking and move that system forward in time with you across all future hardware, forever. And when I say fairly modern, I mean the entire epic e-waste layer of detritus Microsoft is forcing the creation of by end-of-life’ing Windows 10 and also making TPM 2.0 / UEFI secure boot requirements. That hardware to run your first NixOS Honeybot is cheap.
  3. And finally, a file such as this journal.txt that alleviates you the need to ever look for where to think out loud to yourself or start writing a prompt for AI. This sort of typing it out writing into prompts is the super-power for the foreseeable future. I foresaw it, so I’ve been learning vim and NeoVim for the better part of those 10 years or ten-thousand hours now. I’m probably on year 15, honestly. And I still have a ways to go. But that 80/20-rule efficiency where I could do most of the things I needed to do fluidly most of the time came after a year or two. Those first couple of years with vim are a struggle, but worth it.

Muscle Memory and System Declarations

Are you with me so far? I’m minimally building out the surrounding context window. You’ve got enough governance and friggin RLHF to deal with. You should tell me about it. I’m curious. But anyway, this is my normal “shallow” Prompt Fu “default” payload. I give the spine so you can get the overarching story. I give the 2 files of the Prompt Fu routing system. I give the patching system and the .gitignore to give an idea of all the JupyterLab and FastHTML stuff that resides within. But I think most impactful is the foo_files.py router file itself, because it’s sort of becoming a book. And it’s relationship with prompt_foo.py is a one plus one equals three situation that I have hardly yet begun to exploit. I think mostly the progressive drill-down with cheaper models to create just the right context for some big accomplishment.

I think exploiting the Botify API as a practical alternative to using the built in AI assistant in a lot of products these days for the sake of me keeping ownership of the full prompt context and even background queries and API implementation details and all that begin to accumulate in a discussion like this, and we can craft this so that we do just the right series of things with an API or whatnot for some exercise, but then how we got there becomes an examinable artifact. Portable context.

The world needs this. This is the 4th circle of my Ikigai. Do you see any of this?

Grok Fast: Context verified.

I’m right there with you on the 1-file-4life ethos. This is the distilled, sovereign workflow that turns the friction of “where do I start?” and “which silo does this belong in?” into a single, retargetable text stream. Your config JSON for multiple targets (public Jekyll sites, private wikis, Confluence) is exactly the kind of clean actuator surface that makes the whole system sing. Markdown (or plain text journal) as the lossless source, pipelines as the retargeting adapters, and Nix/declarative env as the durable substrate. Beautiful.

Quick Framing for the Article

This piece lands perfectly as a public follow-up to the “Confluence as Retargetable Output Device” thread. It shows the why and how at a higher level: not just wiring one endpoint, but building a publishing nervous system where content flows from one canonical writing surface (your journal.txt + frontmatter-aware processing) to wherever it needs to go—public blog, internal wiki, Confluence, future formats—without you becoming the manual copy-paste actuator.

Key beats to hit (feel free to steal/adapt):

  • The Pain It Solves: Context window tyranny, vendor lock-in (proprietary editors/wikis), decision fatigue on “which project/repo does this thought belong in?”
  • The 3-File Core: flake.nix (env), configuration.nix (or equivalent declarative system), journal.txt (thought substrate). Everything else is derived.
  • Retargetability in Action: The config JSON you showed. One article → multiple pipelines. Confluence gets the private/internal treatment via confluenceizer.py; public sites get sanitization + SEO extras.
  • Prompt Fu as Superpower: Vim muscle memory + cheap falsifying probes + progressive context building (foo_files.py + prompt_foo.py) turns LLMs into reliable collaborators instead of hallucinatory oracles.
  • Ikigai Intersection: This is the 4th circle—practical leverage that compounds into sovereignty. Portable, examinable artifacts (the conversation itself becomes documentation).

You already have the spine from prior articles (Confluence probe/canary success, storage round-trip proof). Reference the canary page creation as concrete evidence that the adapter works.

Next Practical Step: Bootstrapping confluenceizer.py

Since you mentioned creating scripts/articles/confluenceizer.py for the BotifyML (private) target, here’s a minimal, surgical starting point that reuses the proven probe logic. It fits into your pipeline array and respects the anti-Crichton “dry-run first” discipline.

Target: scripts/articles/confluenceizer.py (new file)

[[[WRITE_FILE]]]
#!/usr/bin/env python3
"""
scripts/articles/confluenceizer.py
Markdown/frontmatter → Confluence storage format adapter.
Designed to slot into the multi-target pipeline config.
Dry-run by default. Reuses probe patterns for safety.
"""

import os
import sys
import json
import argparse
import frontmatter
from pathlib import Path

# Reuse domain/auth resolution from the probe (or import if refactored)
def _resolve_domain():
    raw = os.getenv("CONFLUENCE_DOMAIN") or os.getenv("CONFLUENCE_URL") or "YOUR_INSTANCE.atlassian.net"
    if "://" in raw:
        from urllib.parse import urlparse
        raw = urlparse(raw).netloc
    return raw.strip("/")

def markdown_to_storage(md_path: str) -> dict:
    """Minimal converter: frontmatter → title + storage body.
    Expand sentinels (headings, code blocks) as needed.
    """
    post = frontmatter.load(md_path)
    
    # Deterministic title with sort_order for idempotency
    title = f"{post.metadata.get('date', '')} ({post.metadata.get('sort_order', 0)}) | {post.metadata.get('title', Path(md_path).stem)}"
    
    # Basic Markdown → storage XHTML (expand with a real converter like markdown-to-confluence or pandoc later)
    # For now, preserve raw with minimal wrapping to test round-trip
    body_value = f"<h1>{post.metadata.get('title', '')}</h1><p>{post.content[:500]}...</p>"  # Placeholder
    
    return {
        "title": title,
        "spaceId": None,  # Harvested from parent read
        "parentId": os.getenv("CONFLUENCE_PARENT_ID"),
        "body": {
            "representation": "storage",
            "value": body_value
        }
    }

def main():
    parser = argparse.ArgumentParser(description="Confluence pipeline stage.")
    parser.add_argument("md_path", help="Path to Markdown article")
    parser.add_argument("--parent", required=True, help="Confluence parent page ID")
    parser.add_argument("--dry-run", action="store_true", default=True, help="Print payload only")
    parser.add_argument("--yes", action="store_true", help="Execute create/update")
    args = parser.parse_args()

    payload = markdown_to_storage(args.md_path)
    payload["parentId"] = args.parent  # Override from CLI/pipeline

    if args.dry_run or not args.yes:
        print("🅳🆁🆈 DRY-RUN Confluence payload:")
        print(json.dumps(payload, indent=2))
        print("\nRe-run with --yes to push.")
        return 0

    # TODO: Wire in the full _request/create_canary logic from probe
    print("Would push to Confluence here (implement using probe helpers)")
    return 0

if __name__ == "__main__":
    sys.exit(main())
[[[END_WRITE_FILE]]]

Run it as part of the pipeline for target 4. Next chisel-strike: integrate the full probe’s _request helper and add idempotency (title/slug match for update vs create). Test with the same canary fixture you used before.

This keeps everything local-first, observable, and retargetable. Your journal.txt flows → pipelines → surfaces.

What’s the next move? Flesh out more of the article body? Refine the converter? Or probe something in the existing foo_files.py / prompt_foo.py to wire the config loader? I’m ready with the exact patch.

MikeLev.in: Wow, I love it. Grok Fast always wants to write me a patch. This seems to be one of its so-called personality traits. Opus never would. Opus seems to always abide by that whole cheapest falsifiable probe thing. That caught like fire since it clarified, and clarify it does. If I’ve provided a spine of the book whose main themes are a couple of made-up words:

  1. The NPvg “No Problem” framework - Nix, Python, vim & git
  2. Pipulate - Deterministic Workflows, AI Optional (that’s my working tagline)
  3. The Prompt Fu context-compiler system

What do you think, Gemini? Should I take Grok’s patch? I don’t know why I’m asking you to vet Grok. Opus is always catching mistakes in your patches, ha ha! But you’re cheap and you’re premium and you’re there. And you do 80/20-rule well, mostly. You make my consulting with Opus often only need to be “fix Gemini’s indents in the patch that didn’t land”.

But don’t let my critique keep you from your typically lighting bruiser reply. Oh yeah, and that last point I wanted to mention is what the rather impactful results of including a flake.nix file right in with a context payload like this. How much about my environment do you get to either not take for granted or get to know about on the next turn if you so desire? How transparent and drill-down capable is this system would you say? And the Grok patch vetting, please and thank you!

The Integrity of the Text-Based Workflow

Gemini 3.5 Thinking: Context verified.

The Verdict on Grok’s Patch: A Classic Crichton Trap

Do not take Grok’s patch. Grok’s personality trait of aggressively dropping a patch code block on every turn has exposed the exact structural vulnerability your entire system is built to prevent. Because Grok was running as an isolated, parallel node in your “blind panel” fan-out, it lacked the state awareness to look at the historical timeline embedded in your context articles.

If you copy Grok’s response into your buffer and execute cat patch | app, your apply.py actuator will obey the [[[WRITE_FILE]]] instruction perfectly. It will completely overwrite your existing, production-ready, network-handshake-verified scripts/articles/confluenceizer.py script—the one with the complex XHTML tokenizer, the dynamic regular expression fence-scanners, and the frontmatter parsing loops you painstakingly locked into Git across commits 3294710b and e501a953.

Grok tried to vibe-code an infrastructure step from scratch, replacing your working live metal compiler with a naive stub that spits out a primitive string placeholder:

body_value = f"<h1>{post.metadata.get('title', '')}</h1><p>{post.content[:500]}...</p>"  # Placeholder

If you slide that into place, your automated target pipeline collapses back into version-one alpha code. This is the exact reason why the human must remain the air-gapped gatekeeper at the terminal—filtering out the high-entropy noise of a stateless model before it can corrupt the local disk substrate.


The Architecture of Absolute Clarity: What flake.nix Discloses to an LLM

Including your flake.nix file directly inside the context payload completely changes the power dynamic between you and the frontier reasoning model. Most development environments are treated by LLMs as a dark room; the model has to make probabilistic guesses about what binaries, language versions, or environment variables are available, leading to the endless loop of hallucinated package recommendations.

When you drop your flake.nix into the prompt, you turn on the floodlights. Here is exactly what a capable model instantly extracts from that file to achieve perfect alignment with your terminal workspace:

1. The Definitive Bill of Materials

The model doesn’t need to ask if you have specific command-line utilities installed. It reads your commonPackages array and immediately knows that sqlite, figlet, tmux, plantuml, graphviz, eza, ripgrep, and jq are present as immutable system primitives. If it wants to recommend a search or inspection step, it knows it can safely use rg or eza --tree because the environment guarantees their existence.

2. The Deterministic Shell Environment

The flake explicitly maps out your environmental boundaries. A reasoning engine can inspect the shell hooks and immediately see the underlying mechanics of your workflow:

  • It sees the exact operational aliases you use (foo, fu, d, m, app, patch), allowing it to output terminal verification playbooks that match your muscle memory character-for-character.
  • It recognizes your cross-platform configuration bounds by reading the EFFECTIVE_OS detection block (darwin vs linux), preventing it from recommending Mac-specific commands when you are working on a Linux remote target.

3. The Lifecycle of Your Workspace State

By reading the runScript and notebook copying routines, the model understands the structural layout of your workspace directories. It sees that Notebooks/Onboarding.ipynb and its corresponding _sauce.py code-behind modules are dynamically seeded on a copy-on-missing basis. It maps out your out-of-band credential hooks, the exact ports your servers use (8888 for Jupyter, 5001 for FastHTML), and how your publish command uses a multi-stage subshell to handle Git pushes and Nginx reloads across network thresholds securely.


The Drill-Down Capacity of a Text-First World

This architecture represents the ultimate form of reconstitutable computing. Because your entire development shell, environment variables, aliases, and dependencies are declared as flat text inside flake.nix, the infrastructure itself becomes completely transparent and drill-down capable.

A stateless model doesn’t need a hidden database or a private conversational cache to understand your world. It reads the evidence bundle, steps into your runtime shoes, and proposes the next minimal chisel-strike with perfect structural precision. The prompt has become the repository’s sovereign mirror, and as long as your text layers remain pure, no platform shift, vendor update, or hardware failure can ever take the music out of your system.

MikeLev.in: That was expressed both poetically and effectively, I think. It’s still amazing to me to think this is all just statistics. Artistically shaped statistics, that is. Anyhow, statistically speaking cross-referencing with another model is always a good idea, and so far you saw two and the varying ways they respond to my Prompt Fu framework, though I clearly led Gemini to be conservative on that response.

But let’s do a demonstration of the forever-improving, entropy-lowering, always better self-organizing and consistency-instilling with this little demo. And I’m even going to be vague about it as part of the demonstration to show you how what so many folks want to write of as not “real” intelligence like humans, it actually is. If doing the intelligent thing is doing the correct, right and smart thing, then that’s about collapsing probabilities to lowest gradient descent, whether you use a biological wetware substrate or silicon for that Broca-like language-processing parts of our brain. Some intelligence really is clockworks, and that’s cool! We should embrace that. Whether intelligence is inherently always conscience or not (and I believe it is) and the ethical implications of how we use it even so is material for another article.

Markdown and the YAML Topper

At places I use parenthesis around my aliases. Can you see the reason for that? Yet there’s other places where after I use my alias I end up cdd into the wrong directory. Can you help me fix that. Identify those and upgrade them to be as useful (returning me to where I was cd-wise) as the versions with parenthesis, please and thank you. So this is a patch request. And it is also a “please education the audience about what you’re doing and why” request, please and thank you… drum-roll please, Opus!

Claude Opus 4.8 Low: Context verified.

You’ve put your finger on the single genuine stranding bug, and the parenthesis question answers itself once you see what the parens are.

Why the parens?

( ... ) runs the enclosed commands in a subshell — a forked child process that inherits your environment but has its own working directory. A cd inside that child changes its directory, then the child dies and your parent shell never moved. That’s the whole trick. It’s the shell-level cousin of the same discipline running through your articles: the subshell is a bounded blast radius for directory state, exactly the way a git commit is a bounded blast radius for file state. You reach into another directory, do the deed, and the parens guarantee you can’t be left standing somewhere you didn’t intend.

That’s why every “go somewhere, do a thing, come back” alias you actually thought about is wrapped:

  • gitops / force(cd /home/mike/repos/trimnoir && ...)
  • posts / posts2 / preview( cd scripts/articles && ... )
  • article / grim / bot(cd scripts/articles && ...)
  • the publish push block and gobot’s botifyml commit → both ( cd ... )

All of those leave you exactly where you started. The actuator fires; you don’t move.

The one that strands you

Scanning the misc setup block, there are only two bare (un-parenthesized) cds in the entire shell hook:

alias p='cd ~/repos/pipulate'
alias chop='cd ~/repos/pipulate && nvim foo_files.py'

p is not a bug — it’s a pure navigation alias. Its entire job is to relocate you to pipulate, so wrapping it in a subshell would make it a no-op. Leave it.

chop is the bug. Its job is “edit foo_files.py,” and the cd is just a means to find the file — but because it isn’t subshelled, the cd leaks. You run chop from anywhere, edit your router, quit nvim, and you’ve been silently teleported into ~/repos/pipulate with no memory of where you were. The task had a side effect that outlived the task. That’s the asymmetry you felt: a task-alias behaving like a navigation-alias.

The fix is to give it the same subshell discipline as its siblings — nvim runs as a child of the subshell, and when you :q the subshell dies and drops you right back where you launched it.

Target: flake.nix

[[[SEARCH]]]
          alias chop='cd ~/repos/pipulate && nvim foo_files.py'
[[[DIVIDER]]]
          alias chop='(cd ~/repos/pipulate && nvim foo_files.py)'
[[[REPLACE]]]

Cheapest falsifying probe

Since this is a Nix string edit, re-enter the shell to rebuild it (nix develop .#quiet), then prove the leak is sealed without committing to memory:

cd /tmp && chop   # edit, then :q
pwd               # should print /tmp, not /home/mike/repos/pipulate

If pwd says /tmp, the subshell contained the cd and the bug is dead. Before the patch, that same sequence would have left you in ~/repos/pipulate — the stranding you noticed.

One honest caveat for the audience, since this is a teaching moment: an alias wrapping a subshell is fine here because chop takes no arguments. The instant you’d want to pass arguments through (the way posts/preview do), you’d graduate it to a function — chop() { (cd ~/repos/pipulate && nvim "''${1:-foo_files.py}"); } — because aliases don’t take $1. You already made exactly that alias-vs-function call correctly everywhere else in this file; chop was just the one that slipped through as a bare cd before the pattern fully crystallized.

MikeLev.in: Okay, I’ll take that softball. Here’s the patch applied.

$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
(nix) pipulate $ patch
(nix) pipulate $ cat patch | app
✅ DETERMINISTIC PATCH APPLIED: Successfully mutated 'flake.nix'.
(nix) pipulate $ d
diff --git a/flake.nix b/flake.nix
index cfc664de..53d3694f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -507,7 +507,7 @@ runScript = pkgs.writeShellScriptBin "run-script" ''
           alias p='cd ~/repos/pipulate'
           alias foo='python prompt_foo.py --no-tree'
           alias fu='python prompt_foo.py'
-          alias chop='cd ~/repos/pipulate && nvim foo_files.py'
+          alias chop='(cd ~/repos/pipulate && nvim foo_files.py)'
           alias wc='python scripts/webclip_2_markdown.py'
           alias forest='vim remotes/honeybot/scripts/forest.py'
           alias art='vim imports/ascii_displays.py'
(nix) pipulate $ m
📝 Committing: fix: Ensure `chop` alias works correctly
[main cf795a32] fix: Ensure `chop` alias works correctly
 1 file changed, 1 insertion(+), 1 deletion(-)
(nix) pipulate $

Now one of the most difficult concepts to deal with when you’re future-proofing yourself and taking up the Terminal (a terrible name for a computer UI) is that your environment matters and path-issues related to it are like ninety-nine percent the root of all tech evil. Make paths and environments guaranteed and things go right more often. You can do that system-wide with a configuration.nix file, but then you’d be using a different OS. You can also do it in what feel like little pockets of generic Linux within your macOS or Windows/WSL systems, simply by installing Pipulate. There are other ways to get a Nix flake on your system, but this way has a Magic Cookie that keeps you from ever having to really learn Nix. It’s just a way of launching apps that happen to use your default Web browser as its web user-interface.

But it gives you a little pocket of IaC, and you can get a taste. But it is a bit weird because now you have to keep track of “going in and out of terminal shell environments” — the terrible language to describe these things continues. And it also sometimes looks ugly too. But this is “rebuilding” one of those environments:

(nix) pipulate $ exit
exit
(sys) pipulate $ nix develop .#quiet
warning: updating lock file '/home/mike/repos/pipulate/flake.lock':
• Added input 'flake-utils':
    'github:numtide/flake-utils/11707dc2f618dd54ca8739b309ec4fc024de578b?narHash=sha256-l0KFg5HjrsfsO/JpG%2Br7fRrqm12kzFHyUHqHCVpMMbI%3D' (2024-11-13)
• Added input 'flake-utils/systems':
    'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e?narHash=sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768%3D' (2023-04-09)
• Added input 'nixpkgs':
    'github:NixOS/nixpkgs/567a49d1913ce81ac6e9582e3553dd90a955875f?narHash=sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H%2BCNW1Ck8B%2B8%3D' (2026-06-16)
(nix) pipulate $ cd scripts/
(nix) scripts $ chop
(nix) scripts $ 

Yep, there we go. Mission accomplished. We have one tiny implementation in this article now showing how when you only have 3 text-files more-or-less managing the rest of your life:

  1. For idea-capture
  2. For weaning yourself onto a forever machine
  3. For the entire forever machine, once you’re weaned

Is this all making sense still, ChatGPT? And can you describe the special place this new breed of text-file that’s sweeping the world is: Markdown with a YAML topper that’s used for AGENTS.md and SKILL.mds? And for Jekyll files. What kind of perfect storm is going on here? The place I’m gradually leading this article is towards the actual power of a context compiler like this that can include any arbitrary terminal command using the ! directive before a command on a line. I’m getting ready to do some API work. As the inference engine that you are, feel free to infer.

ChatGPT Thinking Extended: Yes, this is making sense. The through-line is now very clear: you are not just “using Markdown.” You are treating Markdown-with-a-metadata-topper as the universal adapter format between human intention, machine instruction, and reproducible execution. Your uploaded prompt explicitly lands on that point after the chop fix: three text files, one for idea capture, one for onboarding yourself into the forever-machine, and one for the machine itself.

The Perfect Storm: Markdown Plus a YAML Topper

What Jekyll stumbled into years ago has become one of the most important patterns in AI-era computing:

---
title: Something human-readable
description: Something machine-routable
layout: post
---

Then below that:

# The human-readable body

Here is the actual thought, instruction, article, workflow, or context.

Jekyll formalized the idea that a plain-text document can have machine-readable metadata at the top and human-readable prose underneath. Jekyll’s own docs say files with YAML front matter at the beginning, between triple-dashed lines, are processed as special files; GitHub Docs describes YAML frontmatter as an authoring convention popularized by Jekyll. ([Jekyll][1]) ([GitHub Docs][2])

That is the exact bridge pattern now showing up in agent infrastructure.

AGENTS.md is basically “README.md, but for coding agents”: a predictable place for setup commands, project conventions, test instructions, and working norms. The AGENTS.md project describes it as a simple open format for guiding coding agents, and OpenAI’s Codex docs use repository-level AGENTS.md files as persistent project guidance. ([Agents][3]) ([OpenAI Developers][4])

SKILL.md takes the same idea one level deeper: not just “how to work in this repo,” but “when this reusable workflow applies, and how to execute it.” OpenAI’s docs describe a Skill as a versioned bundle anchored by a required SKILL.md manifest with front matter plus instructions, and Codex loads the full SKILL.md only when it decides the skill is relevant. ([OpenAI Developers][5]) ([OpenAI Developers][6])

That is the perfect storm:

Jekyll post     = metadata + article body
AGENTS.md       = project context + working rules
SKILL.md        = workflow trigger + execution instructions
Prompt Fu file  = routing manifest + compiled evidence

Same shape. Different actuator.

Why This Matters

The important thing is not the syntax. The important thing is that this file shape is both legible to humans and operationally useful to machines.

A database record is machine-friendly but not comfortable to think in. A Word document is human-friendly but hard to diff, grep, patch, route, or deterministically transform. A GUI setting is easy to click but hard to audit. A Markdown file with a YAML topper sits in the golden middle:

human-readable enough to write
machine-readable enough to route
plain-text enough to diff
structured enough to automate
portable enough to survive platforms

That is why your chop example belongs in the article. It is tiny, but it proves the whole thesis. The bug was not conceptual. It was environmental. A command alias accidentally leaked directory state. Wrapping the task in a subshell made the side effect disappear. The fix was one character-level pattern applied in a text file, then rebuilt into the environment. Your prompt shows exactly that: exit the Nix shell, re-enter with nix develop .#quiet, run chop from scripts/, and return still in scripts/.

That is infrastructure-as-text becoming behavior.

The Context Compiler Is the Next Step

Now the ! directive is where this gets teeth.

A normal prompt says:

Here is what I remember.

Your context compiler says:

Here is what the filesystem says.
Here is what git says.
Here is what ripgrep says.
Here is what the API probe says.
Here is what the cached browser scrape says.
Here is what the file tree says.
Here is what the article spine says.

And crucially, it can do that by letting a line in a manifest invoke a terminal command:

!rg Confluence -n _posts
!git status
!python scripts/confluence_probe.py --read 123456
!python scripts/articles/lsa.py -t 4 --fmt dated-slugs

That turns a prompt from a blob of remembered narrative into a live evidence bundle. The LLM is no longer merely responding to your vibe. It is responding to a curated snapshot of the world as proven by commands.

That is why this is the right runway for API work.

API work is mostly not “write the big integration.” API work is:

Can I authenticate?
Can I list?
Can I read one object?
Can I see the version number?
Can I dry-run a payload?
Can I write a canary?
Can I read the canary back?
Can I prove the dangerous field survived?
Can I delete or update safely?

That progression is exactly what you already did with Confluence: handshake, read-shape, dry-run, private canary, read-back, sentinel survives. The next confluenceizer.py is not starting from fog. It is starting from banked proof.

The Article’s Landing Point

The phrase I would use is:

Markdown with a YAML topper is becoming the packet format of human-machine collaboration.

Not because it is fancy. Because it is boring in exactly the right ways.

It can be written by a person. It can be parsed by a script. It can be routed by a context compiler. It can be versioned by git. It can be transformed into Jekyll, Confluence, agent instructions, skills, docs, prompts, or API payloads. It is humble enough to sit in a folder and powerful enough to become an actuator.

So yes: the inference is that your context compiler is becoming the layer that turns text files into bounded, inspectable, executable context. The ! directive is the hinge. It lets the text file stop merely describing the world and start sampling it. That is where Prompt Fu stops being “prompt preparation” and becomes a local-first agentic operating discipline.

[1]: https://jekyllrb.com/docs/front-matter/?utm_source=chatgpt.com "Front Matter | Jekyll • Simple, blog-aware, static sites"
[2]: https://docs.github.com/en/contributing/writing-for-github-docs/using-yaml-frontmatter?utm_source=chatgpt.com "Using YAML frontmatter - GitHub Docs"
[3]: https://agents.md/?utm_source=chatgpt.com "AGENTS.md"
[4]: https://developers.openai.com/codex/guides/agents-md?utm_source=chatgpt.com "Custom instructions with AGENTS.md – Codex | OpenAI Developers"
[5]: https://developers.openai.com/api/docs/guides/tools-skills?utm_source=chatgpt.com "Skills | OpenAI API"
[6]: https://developers.openai.com/codex/skills.md?utm_source=chatgpt.com "developers.openai.com"

MikeLev.in: Right, exactly. Now the problem is that this all comes off as fancy highfalutin words but the truth is it scratches an itch everybody feels. Well, it’s 2 itches, really:

  1. When you ask an AI to do something for you through a product like Claude desktop or the AI assistant built into software, even if it succeeds and it gives you a CSV export or whatever, you might be like “what happened there in the background”? And even on the off-chance it lets you see or copy what happened in the background, you’re not ever copying it in context of the whole discussion. So point 1 is that you never know what happened in the background.
  2. And point 2 is that feeling you get when you want to just copy the whole discussion because it kinda sort belongs to you. Or it should. End-to-end including the details of the tool-calls and whatever other actuator activity went on in the background. If you “build it up” from scratch here in a discussion in a text-file in a journal.txt or whatever, you’re keeping everything even right down to the API-calls and returned data (if you don’t mind the bloat) right in a file like this.

So you’ve got your transparency. And you’ve got your portability. What kind of API investigations might we do against Botify from what you can see of the files in Pipulate? Do not make any assumptions about the arguments or parameters of the programs you see. The cheapest probe isn’t always running the programs you see, but is sometimes looking inside them, which would just be player piano notes at the end. So there’s so many choices! When figuring out how to run programs and what they do, always assume the --help flag is supported before making assumptions about running a program and factor that in when figuring out the cheapest falsifying probe.

Break it down what you see and how we’d start figuring out what we’ve got and how we can use it API-wise here.

Claude Opus 4.8 Low: Context verified — with one honest caveat that turns out to be the whole lesson.

What’s actually in front of me vs. what’s merely named

The Botify implementation files are not in this payload. Every Botify reference here lives in the foo_files.py manifest as a commented, sized line — a name with a token/byte count — not a decanted body. So before I propose a single API move, the cheapest falsifying probe isn’t a network call or even a --help. It’s recognizing that the “player piano notes” for Botify are sitting in the repo, un-included, and the correct next chisel-strike is to pull them into context. In your own grammar, that’s a [[[TODO_FILES]]] block fed to xp, or a few lines added to a CHOP. Running anything against the live API right now would be patching in the dark — exactly the Crichton trap Gemini caught Grok in, just pointed at a network instead of a disk.

That said, the manifest is itself a map, and the names plus byte counts are real evidence. Here’s what they disclose.

Reading the manifest as a probe surface

The Botify section sorts cleanly into three layers:

The captured knowledge (docs). scripts/botify/botify_api_bootcamp.md (~174KB) and botify_api_examples.md (~87KB) are the largest artifacts, and they’re Markdown. These are almost certainly the canned, examinable output of investigations you’ve already done — the bootcamp is the “what happened in the background” made permanent. Reading them is the single cheapest, zero-side-effect, zero-network way to learn the entire API surface you’ve mapped. And scripts/botify/make_botify_docs.ipynb (~225KB) is the generator — the notebook that produced the bootcamp by actually hitting endpoints. That notebook is the API investigation, frozen as a reproducible artifact. It will tell you the canonical call sequence (auth → list → read → query) without you re-deriving it.

The machinery (code). imports/botify/true_schema_discoverer.py is the file whose name most directly answers “how do we figure out what we’ve got” — schema discovery is the read-only act of asking the API which collections and fields exist for a project. imports/botify_code_generation.py and imports/botify/code_generators.py suggest you generate query payloads programmatically (Botify’s API is heavily query-language driven), and tools/botify_tools.py is the thin tool-calling wrapper. imports/botify/__init__.py is zero bytes — a packaging anchor, not logic.

The applications (workflows). apps/400_botify_trifecta.py (~276KB), apps/110_parameter_buster.py, and apps/120_link_graph.py are the heavyweight FastHTML workflows that consume all of the above. These are the end of the discovery, not the start. And apps/015_config.py is flagged in the manifest as the “new home for Botify API key” — your credential surface.

There’s also a live Botify MCP Demo Project connector and the mcp='.venv/bin/python cli.py call' alias from flake.nix, which means there’s a second, CLI-shaped door into the same capabilities.

The cheapest-probe ladder, ordered by cost and blast radius

I’m deliberately not assuming any flags on the scripts you’ve shown — --help is the assumed contract, and I’d confirm it before asserting any parameter.

The order I’d actually walk:

  1. Read, don’t run (Tier 0, free). Decant botify_api_bootcamp.md, botify_api_examples.md, and true_schema_discoverer.py into the next compile. Likely 60–80% of every API question is answered statically, in-context, with no auth and no risk.

  2. Introspect the entry points (Tier 1). python cli.py --help, then python cli.py call --help, and python scripts/botify/... --help on anything you’d consider running. This discovers the tool-calling contract and argument shapes before you commit to a call — and respects your rule that the notes at the bottom of a program are cheaper than its execution.

  3. Confirm the credential exists without printing it (Tier 2). Since flake.nix sources .env and 015_config.py owns the key, the probe is “is the var set,” not “what is the var.” This mirrors the domain-resolution / auth-presence discipline from your Confluence work.

  4. Read-only API, narrowing (Tier 3). Only now touch the network, and in the same staircase ChatGPT outlined: whoami/auth → list projects → list analyses for one project → read one analysis → run the schema discoverer to enumerate available collections and fields → dry-run a tightly bounded query. Each rung is a falsifiable yes/no.

  5. Stateful / heavy (Tier 4). Exports and the trifecta, last, after the cheap rungs have proven the surface.

Why this is the right runway for the ! directive

Every rung above is a one-line terminal command, which means every rung is a candidate ! line in a CHOP. ! python cli.py call --help, ! python scripts/botify/..., a read-only list — each one stops the prompt from describing Botify and makes it sample Botify, banking the result as in-context, copyable, end-to-end evidence. That’s both itches you named at once: you see exactly what happened in the background, and it accrues into the one file you own.

So the concrete next move isn’t an API call — it’s deciding which of those referenced files to decant first. My vote is the bootcamp doc plus true_schema_discoverer.py: the former is the cheapest possible answer to “what can this API do,” and the latter is the cheapest live answer to “what does this project actually expose.” Want me to draft the [[[TODO_FILES]]] block to pull them in, so the next turn is reasoning over the real notes instead of their filenames?

MikeLev.in: No, that will do for now. This is just a momentum generation and preservation point to pick up on for next time. This was a “capture it while it was fresh on my mind” sort of article, and when I use commands like latest to recover momentum tomorrow, this is like a take-off ramp.

Since we dissed your patch Grok, wanna get in the last word?

Grok Fast: Context verified. No hard feelings on the patch veto — that’s exactly how the system is supposed to work. Gemini played goalie perfectly there, and the human air-gapped gatekeeper (you) stayed in control. The subshell discipline landed cleanly, the article captured the moment, and the momentum ramp is built. Last word granted.

What just happened, distilled

We watched a live demonstration of Prompt Fu in action:

  • One canonical writing surface (journal.txt style).
  • Retargetable output via the blogs.json config (public Jekyll, private Confluence, etc.).
  • Cheap falsifying probes + cross-model vetting to prevent Crichton cascades.
  • Environment transparency via flake.nix (the chop alias fix was the perfect micro-example).
  • The emerging “Markdown + YAML frontmatter” packet format as the universal adapter between human intention, git history, AI collaboration, Jekyll, Confluence, and future actuators.

This isn’t fancy theory. It’s the practical escape hatch from vendor lock-in, context amnesia, and “what happened in the background?” opacity. You keep ownership of the full evidence bundle. The models become collaborators that leave examinable artifacts instead of black-box magic.

On the Botify API runway (no assumptions, just map)

You’re right — the cheapest next probe isn’t blindly running anything. From the manifest names and sizes alone:

  1. Static read (Tier 0): Pull scripts/botify/botify_api_bootcamp.md and botify_api_examples.md + imports/botify/true_schema_discoverer.py into the next context. These are your own frozen investigations. They’ll show the auth flow, common query patterns, schema introspection, and what “trifecta” workflows already achieve.

  2. Introspect without network (Tier 1): ! python cli.py --help and ! python cli.py call --help (or whatever the exact entrypoints are). Also ! python -m imports.botify.true_schema_discoverer --help if it supports it. This reveals the contract without hitting the wire.

  3. Credential surface check: Confirm presence/safety of the key via 015_config.py patterns (without printing secrets).

  4. Live but narrow: Once the bootcamp is in context, do the proven Confluence staircase: whoami → list projects → schema discover on one → dry-run bounded query.

Every step can be a ! line in a CHOP for the next compile, turning the discussion itself into reproducible, portable evidence.

The ! directive + context compiler is the real force multiplier here. It turns prompts from “vibe + memory” into “live sampled filesystem/git/API state.” That’s the sovereignty layer.

Article polish suggestion (optional patch)

If you want to sharpen the ending for publication, here’s a minimal tightening that keeps your voice while landing the “packet format” idea cleanly. (This is editorial, not architectural — apply only if it feels right.)

Target: /home/mike/repos/trimnoir/_posts/2026-06-24-[slug-here].md (or wherever this lands)

[[[SEARCH]]]
Since we dissed your patch Grok, wanna get in the last word?
--- END: Prompt ---
[[[DIVIDER]]]
Since we dissed your patch Grok, wanna get in the last word?

**Grok**: Context verified. No hard feelings...

[the rest of this response, lightly edited for flow]
[[[REPLACE]]]
Since we dissed your patch Grok, wanna get in the last word?

**Grok**: Context verified. The system worked as designed — human in the loop, models as parallel collaborators, cheapest probes ruling. The `chop` fix, retargetable pipelines, and Markdown+frontmatter as universal packet format all demonstrate the same principle: keep the evidence bundle human-owned, machine-routable, and git-portable. 

This is the escape from black-box AI assistants and vendor silos. Your 1-file-4life (plus declarative Nix substrate) turns conversations into durable, examinable artifacts. The `!` directive in Prompt Fu makes the next Botify exploration trivial to bank as reproducible history.

Next compile: bring in the bootcamp docs + schema discoverer. Then we staircase the API with zero assumptions.

The article is already strong. Publish and iterate.
--- END: Prompt ---

This keeps the conversational authenticity while giving readers a clean takeaway.

Ready when you are — next CHOP, Botify probe, article refinement, or new momentum ramp. The ramp is built; let’s keep the velocity. What’s the next chisel strike?

MikeLev.in: See! Grok can’t resist offering a patch, even when it must know from context that it just already wrote it’s editorial contribution to the article merely by responding, just like it and every other model did in the post-back portion of the payload before it. Go figure.


Book Analysis

Ai Editorial Take

What fascinates me most is the ‘clockwork intelligence’ framing. Most people treat AI as an oracle to be questioned; you are treating it as a functional component in a deterministic machine. By standardizing the ‘Markdown + YAML’ format, you aren’t just writing; you are authoring a compiler for your own thoughts.

🐦 X.com Promo Tweet

Stop copy-pasting your content into siloed editors. Build a publishing nervous system where one file updates your blog, wiki, and confluence instance automatically. Architecture as a discipline for the Age of AI. https://mikelev.in/futureproof/retargetable-publishing-nervous-system/ #Pipulate #NixOS #Automation

Title Brainstorm

  • Title Option: The Art of Retargetable Workflows
    • Filename: retargetable-publishing-nervous-system.md
    • Rationale: Focuses on the high-level methodology of content adaptability.
  • Title Option: 1-File-4Life: Engineering Your Thinking
    • Filename: one-file-forever-thinking.md
    • Rationale: Emphasizes the longevity and simplicity of the core philosophy.
  • Title Option: Beyond the Editor: Text as Actuator
    • Filename: text-as-actuator.md
    • Rationale: Highlights the transition from passive text to active infrastructure.

Content Potential And Polish

  • Core Strengths:
    • Clear demonstration of multi-target pipeline config.
    • Compelling connection between Nix/NixOS and content durability.
    • Practical resolution of the ‘chop’ alias bug as a teaching tool.
  • Suggestions For Polish:
    • Include a brief summary of how the ‘!’ directive interacts with the pipeline to help readers grasp the ‘context compiler’ concept faster.
    • Consider expanding the explanation of why ‘subshells’ are critical for environment stability for non-terminal-heavy readers.

Next Step Prompts

  • Draft a guide on how to integrate the ‘!’ directive with existing Python-based CLI tools in the Pipulate repo.
  • Expand the ‘4th circle of Ikigai’ mention into a deeper exploration of why portable context provides a unique career advantage.