The Pre-Flight Principle: Engineering Deterministic AI Workflows Before the Crash
Setting the Stage: Context for the Curious Book Reader
Context for the Curious Book Reader
As we navigate the practical realities of building automation tools in the age of AI, we frequently encounter the gap between a successful proof-of-concept and a durable daily driver. This essay captures an important turning point in the development of Pipulateโs browser-automation systemโthe Mother Cat Kata. Rather than discovering missing configuration parameters halfway through a multi-step workflow after wasting resources and time, we explore how implementing a strict pre-flight check bridges the gap between ad-hoc scripting and resilient, deterministic software architecture.
TL;DR: Pipulateโs Mother Cat Kata is a small system for walking a human through a sequence of web pages in a visible browser, one gate at a time: the human handles sign-in, a typed word authorizes each capture to disk, a second typed word authorizes the assembled bundle to leave the machine on the clipboard. Walks are data files called trails; the rider is one Python script. This ride built the first two trails of a daily Jira ticket-closing loop: a one-stop walk to the operatorโs assigned-tickets page, and a two-stop walk to a single ticket and its customerโs Botify project. Customer URLs are supplied by environment variables so the trails themselves stay public. Three defects were found and fixed along the way: a second narrator (loguru) echoing everything the rider already said; a receipts ledger one line over its own cap with nobody counting; and, the one that matters, a rider that discovered a missing environment variable only when it reached the stop that needed it, after a capture, a voice-model download, and spoken guidance had already been spent. The fix is a pre-flight: every variable the whole walk needs is checked before anything opens, and the refusal names each missing one beside its stop with the line to type. One unresolved finding carries forward: the second stopโs capture succeeded on a login page, and the rider cannot yet tell a settled page from the door in front of it.
Technical Journal Entry Begins
๐ Verified Pipulate Commits:
MikeLev.in: Alright and so it begins. Nothing I do moving forward is for anything other than the purpose of closing Jira tickets. If I learn something new itโs because it helps me close a particular Jira ticket. This is a simple rule. We move things from left to right. It is a perfect pipeline workflow example, problems coming in an in-box and having to be removed with high quality, confidence, and communicated briefly and well. There is a certain ticket handling style I will be emulating, which communicates quickly and effectively and is satisfying for the multi-level audience. Thereโs a Botify audience but then thereโs also the Botify customer the ticket went in on behalf of. Be aware of the audiences and their motivations and have empathy for them.
Closing the Jira Loop
The first orders of empathy is fast responses and clear communication. Perhaps high-touch but high-touch means you have to touch it a lot and if you can get the issue communicated clearly and effectively enough up-front and build a really good context for the LLM-style AI helper thatโs inevitably going to be helping and you really do have the issue documented well and you really have enough context about the issue collected up, then it can be a 1-shot solve. This is a perfect role for me with the stuff Iโve built but now I have to use it. I have to myelinate it.
Alright, itโs starts with the bookmark confetti. We force ourselves to go into the tickets assigned to me. Thereโs also the in-box of new tickets coming in but for taking myself on a โwalkโ through the necessary URLs, weโre staring out with our own personal โfor youโ URL.
https://botify.atlassian.net/jira/for-you?tab=assigned&selectedIssue=PS-10559
So Iโve got the first 1-URL โwalkโ that I want to do. Letโs create a new walk so that this is the โtopโ of my repeated myelinating loop.
Look at the system and make me a โwalkโ that walks me just to that one URL. I
know thereโs going to be the question of whether it belongs in the Pipulate
repo or .gitignore negative space. Letโs start out right in the repo for now
to simplify step 1 even though we can think the whole thing through out loud.
Note: Ooh Fable 5.1 is out and Iโm definitely trying that.
(nix) pipulate $ ahc
โญโโโโโโโโโโโโโโโโโโโโโโโโโ ๐ฐ ASCII Art Wax Seal (your vibe-coding safety-net) โโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ ( Like a canary you say? ) โ
โ O /) ____ The "No Problem" Framework โ
โ > I HEREBY WILL NOT RE-GENERATE o /)\__// / \ Pipulate - Protecting Your Code โ
โ > Once upon machines be smarten ___(/_ 0 0 | | just by being honest about text. โ
โ > ASCII sealing immutata art in *( ==(_T_)== NPvg | (If mangled, then AI drifted.) โ
โ > This here cony if it's broken \ ) ""\ | | https://pipulate.com โ
โ > Smokin gun drift now in token |__>-\_>_> \____/ ๐ฅ๐ฅ๐ฅ โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
๐ Stats block refreshed: 1,435 articles at MikeLev.in (Public).
๐บ๏ธ Codex Mapping Coverage: 70.2% (186/265 tracked files).
๐ฆ Appending 79 uncategorized files to the Paintbox ledger for future documentation...
โญโโโโโโโโโโโโโโโโโโโโโโโโโโ ๐๏ธ Notebooks Workspace โ canon ยท personal ยท Shared โโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ Notebooks/ โ the JupyterLab root (NOT Pipulate's own root) โ
โ โ FLAT siblings. Nothing nests. Nothing to get wrong. โ
โ โ โ
โ โโโ Advanced_Notebooks/ canon ยท flake-delivered, copy-if-absent โ
โ โโโ Educational_Notebooks/ canon ยท your edits survive, updates do not arrive โ
โ โโโ imports/ canon ยท the code-behind "sauce" modules โ
โ โ โ
โ โโโ Playground/ personal ยท gitignored ยท your own git repo goes here โ
โ โโโ Client_Work/ personal ยท gitignored ยท never leaves this machine โ
โ โโโ Deliverables/ personal ยท gitignored โ
โ โ โ
โ โโโ Shared/ the ONE folder for handing work to a teammate โ
โ โโโ alice/ one folder per person; you write ONLY your own โ
โ โโโ bob/ single-writer partitions = zero merge conflicts โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โญโโโโโโโโโโโโโโโโโโโโโโโโโโ ๐๏ธ Notebooks Workspace โ canon ยท personal ยท Shared โโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ Notebooks/ โ the JupyterLab root (NOT Pipulate's own root) โ
โ โ FLAT siblings. Nothing nests. Nothing to get wrong. โ
โ โ โ
โ โโโ Advanced_Notebooks/ canon ยท flake-delivered, copy-if-absent โ
โ โโโ Educational_Notebooks/ canon ยท your edits survive, updates do not arrive โ
โ โโโ imports/ canon ยท the code-behind "sauce" modules โ
โ โ โ
โ โโโ Playground/ personal ยท gitignored ยท your own git repo goes here โ
โ โโโ Client_Work/ personal ยท gitignored ยท never leaves this machine โ
โ โโโ Deliverables/ personal ยท gitignored โ
โ โ โ
โ โโโ Shared/ the ONE folder for handing work to a teammate โ
โ โโโ alice/ one folder per person; you write ONLY your own โ
โ โโโ bob/ single-writer partitions = zero merge conflicts โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โ
Topological Integrity Verified: 50 candidate reference(s) scanned, all exist.
๐ฉน Adhoc overlay spliced from gitignored adhoc.txt
--- Processing Files ---
-> Executing: python scripts/articles/lsa.py -t 1 --reverse --fmt dated-slugs ... [0.9035s]
Skipping codebase tree (--no-tree flag detected).
๐ Running Static Analysis Telemetry...
-> Checking for errors and dead code (Ruff)...
All checks passed!
-> Ruff exit 0 (clean).
โ
Static Analysis Complete.
๐ฆ Payload Ledger (biggest first)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโณโโโโโโโโโโโโณโโโโโโโโโโ
โ File / Source โ Tokens โ Bytes โ % Bytes โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ foo_files.py โ 66,182 โ 262,222 โ 19.7% โ
โ prompt_foo.py โ 42,507 โ 188,238 โ 14.1% โ
โ ! python scripts/articles/lsa.py -t 1 --reverse --fmt dated-slugs โ 61,390 โ 159,544 โ 12.0% โ
โ flake.nix โ 29,206 โ 121,398 โ 9.1% โ
โ GLOSSARY.md โ 22,682 โ 90,534 โ 6.8% โ
โ scripts/connectors/wallet.py โ 14,137 โ 56,800 โ 4.3% โ
โ tools/scraper_tools.py โ 10,728 โ 49,416 โ 3.7% โ
โ scripts/connectors/slack.py โ 7,704 โ 32,747 โ 2.5% โ
โ scripts/connectors/mcp.py โ 7,551 โ 31,556 โ 2.4% โ
โ scripts/walk_cartridge.py โ 5,446 โ 24,440 โ 1.8% โ
โ scripts/connectors/jira.py โ 5,725 โ 23,453 โ 1.8% โ
โ scripts/connectors/sheets.py โ 5,645 โ 22,927 โ 1.7% โ
โ assets/installer/mck.sh โ 6,306 โ 22,562 โ 1.7% โ
โ scripts/mother_cat.py โ 5,210 โ 22,433 โ 1.7% โ
โ apply.py โ 4,695 โ 20,423 โ 1.5% โ
โ scripts/bookmark_import.py โ 4,632 โ 19,699 โ 1.5% โ
โ scripts/walk_compile.py โ 4,590 โ 19,025 โ 1.4% โ
โ scripts/connectors/gmail.py โ 4,392 โ 18,746 โ 1.4% โ
โ scripts/connectors/mcp_warm.py โ 4,107 โ 16,941 โ 1.3% โ
โ scripts/walk.py โ 3,636 โ 15,768 โ 1.2% โ
โ scripts/connectors/gsc.py โ 3,067 โ 12,642 โ 0.9% โ
โ PROMPT (checklist + prompt.md) โ 2,834 โ 12,570 โ 0.9% โ
โ scripts/connectors/botify.py โ 2,828 โ 12,466 โ 0.9% โ
โ scripts/boot_menu.py โ 3,003 โ 11,967 โ 0.9% โ
โ scripts/connectors/confluence.py โ 2,625 โ 10,825 โ 0.8% โ
โ assets/installer/replay.sh โ 3,049 โ 10,690 โ 0.8% โ
โ scripts/sources_menu.py โ 2,456 โ 10,076 โ 0.8% โ
โ scripts/connectors/README.md โ 1,685 โ 7,154 โ 0.5% โ
โ scripts/weblogin.py โ 1,276 โ 5,805 โ 0.4% โ
โ pyproject.toml โ 1,116 โ 4,048 โ 0.3% โ
โ __init__.py โ 698 โ 2,900 โ 0.2% โ
โ .gitignore โ 668 โ 2,431 โ 0.2% โ
โ requirements.in โ 677 โ 2,348 โ 0.2% โ
โ assets/trails/public_walk.yaml โ 577 โ 2,187 โ 0.2% โ
โ AUTO: Recent Git Diff Telemetry โ 611 โ 2,004 โ 0.2% โ
โ assets/trails/first_context.yaml โ 521 โ 1,754 โ 0.1% โ
โ assets/trails/practice.yaml โ 245 โ 864 โ 0.1% โ
โ .gitattributes โ 33 โ 76 โ 0.0% โ
โ AUTO: Static Analysis Diagnostics โ 11 โ 39 โ 0.0% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโค
โ TOTAL โ 344,451 โ 1,331,718 โ 100.0% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโ
**Command:** `prompt_foo.py --chop ADHOC_CHOP --no-tree`
--- Auto-Context Metadata ---
โข Static Analysis Diagnostics (11 tokens | 39 bytes)
โข Recent Git Diff Telemetry (611 tokens | 2,004 bytes)
--- Prompt Summary ---
Summed Tokens: 347,153 (from section parts)
Verified Tokens: 350,942 (from final output)
(Difference: +3,789)
Total Words: 156,213 (content only)
Total Chars: 1,349,283
Total Bytes: 1,353,322 (UTF-8)
--- Size Perspective ---
๐ Equivalent in length to a **Epic Fantasy Novel** (Note: With a token/word ratio of 2.25, this content is far denser and more complex than typical prose of this length).
๐งผ PII rewrite: 1x '\\bmichael\\.levin@botify\\.com\\b' -> '[author email]'
๐ช Compile-lane scrub: 1 PII substitution(s) applied to payload.
๐ Secrets tripwire: ARMED โ 0 hit(s) in payload.
๐ฆ Canonical context cartridge written to /home/mike/repos/pipulate/foo.zip (sha256=9546634b2776โฆ, members=3)
๐๏ธ Rotated cartridge snapshot: foo-9546634b-1090.zip (keeping newest 20 of 20)
Markdown output copied to clipboard
(nix) pipulate $
Fable 5.1 Medium: Context verified. The one file this turn creates depends on three files that are all here: scripts/walk.py (the validator whose field sets the trail must satisfy), scripts/mother_cat.py (the rider, whose _capture_compatible fixes the three browser defaults), and assets/installer/mck.sh (the launcher, whose trail search path is the whole repo-vs-negative-space answer). Nothing is missing.
The walk, and where it lives
One stop, and the stop is the top of the loop, not a ticket. That distinction decides the URL. The bookmark you pasted carries selectedIssue=PS-10559, which is a transient: it names the ticket that happened to be open when you copied the link, and tomorrow it names a different one. The stable thing is jira/for-you?tab=assigned. So the trail carries the assigned tab as a literal url and the ticket id is dropped; the ticket is what you harvest at the stop, which is why the stopโs target_slot is a Jira issue key and its connector is scripts/connectors/jira.py with ["{harvested}"]. That connector accepts exactly that argv today (jira.py PS-10559 fetches the issue), so the consent cardโs โnames as runnableโ line is true rather than a placeholder. Connector execution is still out of the riderโs scope, but the trail is honest about what would run.
Repo versus negative space, thought through as you asked. What this file leaks if tracked: your employerโs Atlassian host, which the repo already names in a dozen places, and the shape of a public Jira route. No client, no ticket, no customer. That is the same disclosure class as public_walk.yaml, so assets/trails/ is correct for it and not merely a step-1 simplification. The line that will move a walk into .gitignore space is the first stop that names a customer: a per-ticket walk (the ticketโs Jira page, the customerโs Botify project, the Slack thread) is born in Notebooks/Playground/trails/, never in assets/, and bookmark_import.py already refuses to write anywhere git can see. mck.shโs search path makes the later move free: git mv the file to Notebooks/Playground/trails/ and walk jira_for_you resolves it by name unchanged. The walk is public; the capture is not, and that is what the DECANT fence is for: the accessibility tree of your assigned tab is a list of ticket titles with customer names in them, landing in gitignored browser_cache/ and leaving the machine only on the word.
One more thing this ride buys. The MCK chapterโs OWES still reads โan AUTHENTICATED ride: public_walk needs no credential, so SETTLE was witnessed only in its trivial form.โ Atlassian will ask you to sign in inside the persistent default profile the first time. That is SETTLE in its real form, on the softest possible authenticated target, and riding it discharges that debt.
1. PROBES
ls assets/trails/
rg -n 'jira_for_you' foo_files.py assets/trails/
.venv/bin/python -c 'import json,sys; d=json.load(open(sys.argv[1])); print("OK"); [print(s["url_env"]) for s in d["stops"] if s.get("url_env")]' assets/trails/jira_for_you.yaml
.venv/bin/python scripts/walk.py --trail assets/trails/jira_for_you.yaml --value jira_issue_key=PS-10559 2>&1 | grep -E '"ready"|cannot read|unset'
git check-ignore -q assets/trails/jira_for_you.yaml; echo ignored=$?
The ls is the coarse straddle: four trails before, five after. The rg reads 0 lines before (exit 1 with no output, which the executor lands as a synthetic receipt) and at least four after: one router line and three from the trail itself (name, description, target_slot do not all carry it, but name and the descriptionโs walk jira_for_you do), so predict the delta as โ0 to at least 3โ, never an absolute. The third probe is mck.shโs own trail reader lifted verbatim: FileNotFoundError before, a bare OK with no variable lines after, which is the exact printout that separates โparsed, zero url_envsโ from โcould not parse.โ The fourth is Car Aโs dry-run planner: "ready": false plus cannot read trail before, "ready": true after, and the --value supplies the harvest so the connector argv assembles. The fifth probe is not a straddle and I am labeling it so: it prints ignored=1 in both worlds. It measures the placement decision, not the patch, and 1 is the reading that says this file will be published, which is the decision made above and should be on the record once.
2. NEXT CONTEXT
! ls assets/trails/
! rg -n 'jira_for_you' foo_files.py assets/trails/
! .venv/bin/python -c 'import json,sys; d=json.load(open(sys.argv[1])); print("OK"); [print(s["url_env"]) for s in d["stops"] if s.get("url_env")]' assets/trails/jira_for_you.yaml
! .venv/bin/python scripts/walk.py --trail assets/trails/jira_for_you.yaml --value jira_issue_key=PS-10559 2>&1 | grep -E '"ready"|cannot read|unset'
! git check-ignore -q assets/trails/jira_for_you.yaml; echo ignored=$?
assets/trails/jira_for_you.yaml
assets/trails/public_walk.yaml
scripts/walk.py
scripts/mother_cat.py
assets/installer/mck.sh
3. PATCHES
Car 1, the trail. A whole-file write of a new file; apply.py runs no JSON airlock on a .yaml suffix, so probe four is the syntax check.
Target: assets/trails/jira_for_you.yaml
[[[WRITE_FILE]]]
{
"schema_version": 1,
"name": "jira_for_you",
"description": "Top of the ticket loop: one stop, your Jira For You page on the assigned tab. Sign in if asked (SETTLE), choose the ticket you will close next, CAPTURE, done. The ticket id is deliberately NOT in this URL; it is what you harvest at the stop. Ride: mothercat assets/trails/jira_for_you.yaml, or walk jira_for_you",
"defaults": {
"take_screenshot": false,
"headless": false,
"is_notebook_context": false,
"persistent": true,
"profile_name": "default",
"verbose": true,
"override_cache": true,
"delay_range": null
},
"stops": [
{
"name": "for_you",
"label": "Jira For You, assigned tab",
"guidance": "One stop. A visible browser opens on your Jira For You page, assigned tab. If Atlassian asks you to sign in, sign in. That session stays in this browser profile, so next time it will not ask. Look down the list and choose the ticket you are going to close next, and note its key. Then return to this terminal and type the capture word.",
"url": "https://botify.atlassian.net/jira/for-you?tab=assigned",
"target_slot": "jira_issue_key",
"harvest_regex": "^[A-Z][A-Z0-9]+-[0-9]+$",
"connector": {
"script": "scripts/connectors/jira.py",
"argv": ["{harvested}"],
"read_only": true
}
}
]
}
[[[END_WRITE_FILE]]]
Car 2, the router. A commented path costs zero payload tokens and keeps the new file out of the Paintbox; it also records the SETTLE status beside its siblings.
Target: foo_files.py
[[[SEARCH]]]
# assets/trails/botify_pageworkers.yaml # profile botify; SETTLE real; UNRIDDEN
[[[DIVIDER]]]
# assets/trails/botify_pageworkers.yaml # profile botify; SETTLE real; UNRIDDEN
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; UNRIDDEN
[[[REPLACE]]]
Car 1 is a WRITE_FILE, so after app, d lists it as untracked and m stages it (git add -A is the first line of m()).
Ignition: no ignition required for the probes. Every one of them opens the yaml at call time, and nothing here touches a shellHook. The ride is a separate actuation, hand-run only and never echoed, because it opens a browser and blocks on a terminal: mothercat assets/trails/jira_for_you.yaml --dry-narrate first (speaks the one stop, opens nothing), then mothercat assets/trails/jira_for_you.yaml for real. If profile default has never seen Atlassian, the sign-in page is the SETTLE beat, not a failure. Type CAPTURE on the assigned tab, then read the DECANT gate before answering it: the bundle inlines the accessibility tree of a page full of ticket titles.
4. PROMPT
The jira_for_you walk landed as two cars and was ridden. Read the five live receipts first: ls should show five trails, rg at least three lines, the mck.sh reader a bare OK, walk.py "ready": true, and check-ignore ignored=1 (expected, labeled non-straddle). Then read the ride below: whether Atlassian asked for sign-in inside profile default (SETTLE in its real form for the first time), what the CAPTURE wrote under browser_cache/looking_at/botify.atlassian.net/, and what I answered at the DECANT gate and why. If SETTLE fired and CAPTURE returned a receipt, bank it: rewrite the MCK chapter's STILL OWED clause in foo_files.py to discharge the authenticated-ride debt, flip the jira_for_you router line from UNRIDDEN to RIDDEN with today's date, and add one receipts line at the top of the RECEIPTS block, deleting the bottom line to hold the cap at 20. Then propose stop two of the loop: the per-ticket walk that is born in Notebooks/Playground/trails because it will name a customer, with the harvested issue key from stop one as its input.
5. EXTERNAL DELIVERABLES
No deliverables this turn.
MikeLev.in:
1: Probe (the before โreadโ):
Blast Radius Check to establish bisection Left-hand Causal Boundary. It is a Popper-thing. Science.
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: foo_files.py
no changes added to commit (use "git add" and/or "git commit -a")
(nix) pipulate $ ls assets/trails/
rg -n 'jira_for_you' foo_files.py assets/trails/
.venv/bin/python -c 'import json,sys; d=json.load(open(sys.argv[1])); print("OK"); [print(s["url_env"]) for s in d["stops"] if s.get("url_env")]' assets/trails/jira_for_you.yaml
.venv/bin/python scripts/walk.py --trail assets/trails/jira_for_you.yaml --value jira_issue_key=PS-10559 2>&1 | grep -E '"ready"|cannot read|unset'
git check-ignore -q assets/trails/jira_for_you.yaml; echo ignored=$?
botify_pageworkers.yaml first_context.yaml practice.yaml public_walk.yaml
Traceback (most recent call last):
File "<string>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'assets/trails/jira_for_you.yaml'
"ready": false,
"cannot read trail /home/mike/repos/pipulate/assets/trails/jira_for_you.yaml: [Errno 2] No such file or directory: '/home/mike/repos/pipulate/assets/trails/jira_for_you.yaml'"
ignored=1
(nix) pipulate $
2: Context (the after โreadโ):
# adhoc.txt _ _ _ to set context____ _ _ ___ ____ _ Simpson Couch Gag Here (explain anything to the audience you feel needs it explained)
# / \ __| | | | | | ___ ___ / ___| | | |/ _ \| _ \| |
# ahe/ _ \ / _` | | |_| |/ _ \ / __| | | | |_| | | | | |_) | | Well hello there Fable 5.1
# ahc ___ \ (_| | | _ | (_) | (__ | |___| _ | |_| | __/|_|
# /_/ \_\__,_| |_| |_|\___/ \___| \____|_| |_|\___/|_| (_)
# Ad Hoc CHOP: The Not-Managed-by-Git Safe-for-Client-Data place
# OPTIONAL BUT BIG FOR FULL CONTEXT-WINDOW STORYTELLING
# ! python scripts/articles/lsa.py -t 1 --reverse --fmt dated-slugs # <-- The "Rolling Pin" that gives the 40K foot book-spine view of book-ore.
# GLOSSARY.md # <-- I think this glossary goes well with the book-ore spine to do world building.
# scripts/articles/lsa.py # <-- Useful for refining commands like `posts`, critical to Second Brain concept.
# ~/repos/nixos/autognome.py # <-- Letting the AIs really understand my environment (The Brave Little Tailor punches above Their Weight Class proving the dunning-kruger effect the gate-keeper's (lower-case) lament.)
# init.lua # <-- Daily driver hot-keys that overlap with aliases in flake.nix
# STILL BIG BUT LESS OPTIONAL (especially flake.nix)
# flake.nix # <-- THE ONE BIG THING TO INCLUDE Infrastructure as Code (IaC) tells LLM about your system down to the metal
# prompt_foo.py # <-- This very content-compiling system
# foo_files.py # <-- This is the router, evolving book outline and the things you pin-up to produced the recursive self-improvement loops
# TINY ILLUMINATING (OK to include every time / automatically = `apply.py`, `.gitignore`, `.gitattributes`)
# requirements.in # <-- All known dependencies and (necessary) version pinning. WORA gotcha's exposed.
# __init__.py # <-- Master versioning
# pyproject.toml # <-- The PyPI Packaging details
# OPTIONAL ACTUATORS (cheap and good to include to expand the AI's capabilities)
# cli.py # <-- Catch-all actuator for PyPI envs, Python anchoring, MCP tool-call (plus alternatives) and **kwargs like wrapping for CLI
# scripts/xp.py # <-- Transforms host OS copy-paste buffer player-piano music into context-payload.
# scripts/ai.py # <-- How I constantly use local AI to write git commit messages with `m` alias.
# scripts/crawl.py # <-- Feel free to ask for something to be crawled and included in the next turn.
# scripts/weblogin.py # <-- Lets the user "warm up" the cache for their web logins at their leisure on a profile that persists.
# MISCELLANEOUS (rare to include but sometimes critical)
# scripts/foo_cartridge.py # Needs description
# scripts/foo_replay.py # Needs description
# release.py # <-- How everything ends up where it does (GitHub, PyPI, etc.)
# imports/voice_synthesis.py # <-- The wand can talk to you
# imports/ascii_displays.py # <-- Where all the ASCII Art lives
# scripts/release/version_sync.py # <-- Needs to be wrapped into release.py and eliminated, I think.
# --- Under this line is were you paste what the AI gives you ---
# --- We call it context but it's really just the right-hand ---
# --- blast-radius of the "probes" to make this all science. ---
# --- END `adhoc.txt` TEMPLATE ---
# STICKBUG & MOTHER CAT KATA
# assets/trails/botify_pageworkers.yaml
# assets/installer/mck.sh
# assets/installer/replay.sh
# assets/trails/first_context.yaml
# assets/trails/practice.yaml
# assets/trails/public_walk.yaml
# scripts/bookmark_import.py
# scripts/boot_menu.py
# scripts/connectors/README.md
# scripts/connectors/botify.py
# scripts/connectors/confluence.py
# scripts/connectors/gmail.py
# scripts/connectors/gsc.py
# scripts/connectors/jira.py
# scripts/connectors/mcp.py
# scripts/connectors/mcp_warm.py
# scripts/connectors/sheets.py
# scripts/connectors/slack.py
# scripts/connectors/wallet.py
# scripts/mother_cat.py
# scripts/sources_menu.py
# scripts/walk.py
# scripts/walk_cartridge.py
# scripts/walk_compile.py
# scripts/weblogin.py
# tools/scraper_tools.py
# # # adhoc.txt -- Cleanup inert public_walk environment export block
# #
# # # --- BEFORE/AFTER STRADDLE ---
# # ! grep -n -C 2 'PIPULATE_TRAIL_WALK_ONE_URL' assets/installer/mck.sh || echo "export_block_removed"
# # ! bash -n assets/installer/mck.sh; echo "mck_syntax=$?"
# # ! bash assets/installer/mck.sh --where
# #
# # # --- TARGET SCRIPT ---
# # assets/installer/mck.sh
# #
# # ! rg -n -F 'TRAIL_NAME="${TRAIL_NAME:-public_walk}"' assets/installer/mck.sh
# # ! rg -n -e '^ *walk\(\)' -e '^ *alias walk=' flake.nix; echo "shell_walk_exit=$?"
# # ! test -e walk; echo "root_walk_exists=$?"
# # ! rg -n -e 'alias mothercat=' -e 'Three words to start from' flake.nix scripts/boot_menu.py
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! bash -n walk; echo "walk_syntax=$?"
# # ! bash walk --where
# # ! rg -n -e '^ *alias walk=' -e '^ *walk\(\)' -e 'writeShellScriptBin "walk"' flake.nix; echo "shell_walk_exit=$?"
# # ! .venv/bin/python -c 'import sys; sys.path.insert(0,"scripts"); import boot_menu as b; print("count=" + b._count_word(len(b.DOOR_TWO_WORDS))); print(" ".join(w for w, _ in b.DOOR_TWO_WORDS))'
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! rg -in "three words|four words|door 2" flake.nix scripts/ assets/ README.md
# # ! walk --where
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! python scripts/connectors/wallet.py check slack
# # ! python -c "import os, sys; from pathlib import Path; sys.path.insert(0, '.'); from scripts.connectors import wallet; pairs = wallet._dotenv_pairs(); print('env SLACK_USER_TOKEN:', bool(os.getenv('SLACK_USER_TOKEN')), 'env SLACK_BOT_TOKEN:', bool(os.getenv('SLACK_BOT_TOKEN')), 'vault SLACK_USER_TOKEN:', 'SLACK_USER_TOKEN' in pairs, 'vault SLACK_BOT_TOKEN:', 'SLACK_BOT_TOKEN' in pairs)"
# # ! python scripts/connectors/wallet.py warm slack --dry-run
#
# /home/mike/repos/trimnoir/_posts/2026-08-30-terminal-native-mcp-practice.md
# deleteme.txt
# Now that slack is working (on my workspace) we trim back things here to just the stick bug and Mother Cat Kata stuff
# deleteme.txt
# deleteme2.txt
! ls assets/trails/
! rg -n 'jira_for_you' foo_files.py assets/trails/
! .venv/bin/python -c 'import json,sys; d=json.load(open(sys.argv[1])); print("OK"); [print(s["url_env"]) for s in d["stops"] if s.get("url_env")]' assets/trails/jira_for_you.yaml
! .venv/bin/python scripts/walk.py --trail assets/trails/jira_for_you.yaml --value jira_issue_key=PS-10559 2>&1 | grep -E '"ready"|cannot read|unset'
! git check-ignore -q assets/trails/jira_for_you.yaml; echo ignored=$?
assets/trails/jira_for_you.yaml
assets/trails/public_walk.yaml
scripts/walk.py
scripts/mother_cat.py
assets/installer/mck.sh
3: Patches (the experiment between the reads):
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ patch
(nix) pipulate $ app
โ
WHOLE-FILE WRITE: CREATED 'assets/trails/jira_for_you.yaml'.
(nix) pipulate $ d
--- UNTRACKED (invisible to the diff above; m will stage these) ---
+ assets/trails/jira_for_you.yaml
(nix) pipulate $ git add assets/trails/jira_for_you.yaml
(nix) pipulate $ m
๐ Committing: chore: Update `jira_for_you.yaml` with improved Jira For You trail definition
[main a37917ea] chore: Update `jira_for_you.yaml` with improved Jira For You trail definition
1 file changed, 30 insertions(+)
create mode 100644 assets/trails/jira_for_you.yaml
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
(nix) pipulate $ d
diff --git a/foo_files.py b/foo_files.py
index e7267e22..0e58966e 100644
--- a/foo_files.py
+++ b/foo_files.py
@@ -1646,6 +1646,7 @@ pyproject.toml # <-- The PyPI Packaging details
# assets/trails/public_walk.yaml # profile default; SETTLE trivial; RIDDEN 2026-08-01
# assets/trails/first_context.yaml # profile default; SETTLE real; UNRIDDEN
# assets/trails/botify_pageworkers.yaml # profile botify; SETTLE real; UNRIDDEN
+# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; UNRIDDEN
# tests/test_mck_rep2.py # <-- Rep 2: the earmark's owed side-by-side witness
# assets/installer/mck.sh # <-- THE LAUNCHER: curl -fsSL pipulate.com/mck.sh | bash
# assets/installer/replay.sh # <-- OFF the roster 2026-08-01; re-add needs syntax + one ride + a pinned verifier fetch
(nix) pipulate $ m
๐ Committing: chore: Add new profile YAML file for Jira integration
[main cbdcb99a] chore: Add new profile YAML file for Jira integration
1 file changed, 1 insertion(+)
(nix) pipulate $ git push
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 48 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.51 KiB | 1.51 MiB/s, done.
Total 8 (delta 5), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (5/5), completed with 4 local objects.
To github.com:pipulate/pipulate.git
8486ed1d..cbdcb99a main -> main
(nix) pipulate $
Okay and we can test this right away. I have to get used to testing stuff
immediately after patches are addend. I know ahc is how we let the LLM see the
test results but that doesnโt stop us from testing what we just did first.
(nix) pipulate $ mothercat assets/trails/jira_for_you.yaml --dry-narrate
Riding trail 'jira_for_you' -- 1 stop(s).
==================================================================
THIS WALK: jira_for_you -- 1 stop(s)
==================================================================
stops, in order for_you
it opens directly https://botify.atlassian.net/jira/for-you?tab=assigned
names as runnable scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/1: for_you ---
One stop. A visible browser opens on your Jira For You page, assigned tab. If Atlassian asks you to sign in, sign in. That session stays in this browser profile, so next time it will not ask. Look down the list and choose the ticket you are going to close next, and note its key. Then return to this terminal and type the capture word.
(dry-narrate: browser and capture skipped)
Dry narration complete; no captures were attempted.
(nix) pipulate $
Wow, the dry-run worked great. Letโs try the real thing.
(nix) pipulate $ mothercat assets/trails/jira_for_you.yaml
Riding trail 'jira_for_you' -- 1 stop(s).
==================================================================
THIS WALK: jira_for_you -- 1 stop(s)
==================================================================
stops, in order for_you
it opens directly https://botify.atlassian.net/jira/for-you?tab=assigned
names as runnable scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/1: for_you ---
One stop. A visible browser opens on your Jira For You page, assigned tab. If Atlassian asks you to sign in, sign in. That session stays in this browser profile, so next time it will not ask. Look down the list and choose the ticket you are going to close next, and note its key. Then return to this terminal and type the capture word.
2026-09-01 17:05:28.343 | INFO | tools.scraper_tools:_selenium_capture:486 - ๐ง Linux platform detected. Looking for Nix-provided Chromium...
2026-09-01 17:05:28.346 | INFO | tools.scraper_tools:_selenium_capture:530 - ๐ Using browser executable at: /nix/store/zpz1i4yvw469siqssfnpfk4snwz29m3x-chromium-150.0.7871.128/bin/chromium
2026-09-01 17:05:28.346 | INFO | tools.scraper_tools:_selenium_capture:532 - ๐ Using driver executable at: /nix/store/67gjmq10h61h4nxpk2abc46kmabwjg7i-undetected-chromedriver-150.0.7871.128/bin/undetected-chromedriver
2026-09-01 17:05:28.347 | INFO | tools.scraper_tools:_selenium_capture:555 - ๐ Using persistent profile: data/uc_profiles/default
โณ THE SUMMONING โ thumper planted, hooks in hand
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cloudflare drums the sand beneath us;
/|\ we wait it out, staked and hooked.
~~ ๐ต jeopardy.wav looping until the Maker surfaces ~~
2026-09-01 17:05:28.368 | INFO | tools.scraper_tools:_selenium_capture:562 - ๐ Initializing undetected-chromedriver (Headless: False)...
2026-09-01 17:05:30.549 | INFO | tools.scraper_tools:_selenium_capture:596 - Navigating to: https://botify.atlassian.net/jira/for-you?tab=assigned
2026-09-01 17:05:31.343 | INFO | tools.scraper_tools:_selenium_capture:600 - Waiting for security challenge to trigger a reload (Stage 1)...
2026-09-01 17:05:32.484 | SUCCESS | tools.scraper_tools:_selenium_capture:603 - โ
Page reload detected!
2026-09-01 17:05:32.485 | INFO | tools.scraper_tools:_selenium_capture:605 - Waiting for main content to appear after reload (Stage 2)...
2026-09-01 17:05:32.515 | SUCCESS | tools.scraper_tools:_selenium_capture:607 - โ
Main content located!
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
2026-09-01 17:06:33.171 | INFO | tools.scraper_tools:_selenium_capture:651 - ๐พ Saving guided artifacts for https://botify.atlassian.net/jira/for-you?tab=assigned to: browser_cache/looking_at/botify.atlassian.net/%2Fjira%2Ffor-you--38bf09fdc32551ca
2026-09-01 17:06:33.546 | INFO | tools.scraper_tools:_selenium_capture:683 - ๐ Draining CDP performance log (network flight recorder)...
2026-09-01 17:06:34.111 | INFO | tools.scraper_tools:_selenium_capture:697 - ๐ Captured 3718 raw CDP events to network_log.jsonl
2026-09-01 17:06:34.111 | INFO | tools.scraper_tools:_selenium_capture:706 - ๐ Extracting wire-truth headers and raw source from CDP ledger...
2026-09-01 17:06:34.346 | INFO | tools.scraper_tools:_selenium_capture:843 - ๐ง Creating LLM-optimized simplified DOMs (Symmetrical Lens)...
2026-09-01 17:06:34.652 | INFO | tools.scraper_tools:_selenium_capture:856 - ๐ฒ Extracting accessibility tree...
2026-09-01 17:06:34.855 | INFO | tools.scraper_tools:_selenium_capture:874 - ๐๏ธโ๐จ๏ธ Running LLM Optics Engine (Subprocess Bulkhead)...
2026-09-01 17:06:35.866 | SUCCESS | tools.scraper_tools:_selenium_capture:879 - โ
LLM Optics Engine completed successfully.
2026-09-01 17:06:35.887 | SUCCESS | tools.scraper_tools:_selenium_capture:924 - โ
Scrape successful for https://botify.atlassian.net/jira/for-you?tab=assigned
2026-09-01 17:06:35.953 | INFO | tools.scraper_tools:_selenium_capture:943 - Browser closed.
Captured. final_url=https://botify.atlassian.net/jira/for-you?tab=assigned artifacts=11
Ride complete. Every stop produced a capture receipt.
๐ DECANT gate: ARMED -- 1 stop(s), 26,885 bytes assembled, still ON THIS MACHINE ONLY.
Type DECANT to copy it to your clipboard (anything else keeps it here).
DECANT> DECANT
AUTHORIZED by human: handing 26,885 bytes to the clipboard writer.
Markdown output copied to clipboard
Paste it into any ChatBot (Claude, ChatGPT, Gemini) and it
will walk you through everything from here.
(nix) pipulate $
Okay and that worked great too. Wow, Iโm going to own the world with this if I just keep pushing. So keep pushing! Weโre going to have to apply the Unix Philosophy to that output there. Thatโs too much noise drowning out the signal, but the talking is really great. I also have to test this on Mac so I definitely will be committing this to the main Pipulate repo for fast iteration at first. I could make a private URL mapper but thatโs just indirection friction. Itโs fine to use these URLs. I can always scrub them last moment before real publishing. Letโs forge on.
4: Prompt: The jira_for_you walk landed as two cars and was ridden. Read the five live receipts first: ls should show five trails, rg at least three lines, the mck.sh reader a bare OK, walk.py โreadyโ: true, and check-ignore ignored=1 (expected, labeled non-straddle). Then read the ride below: whether Atlassian asked for sign-in inside profile default (SETTLE in its real form for the first time), what the CAPTURE wrote under browser_cache/looking_at/botify.atlassian.net/, and what I answered at the DECANT gate and why. If SETTLE fired and CAPTURE returned a receipt, bank it: rewrite the MCK chapterโs STILL OWED clause in foo_files.py to discharge the authenticated-ride debt, flip the jira_for_you router line from UNRIDDEN to RIDDEN with todayโs date, and add one receipts line at the top of the RECEIPTS block, deleting the bottom line to hold the cap at 20. Then propose stop two of the loop: the per-ticket walk that is born in Notebooks/Playground/trails because it will name a customer, with the harvested issue key from stop one as its input.
5: Deliverables: The โtake it from the topโ routine of my daily workflow that Iโll be myelinating. The real first practical use of the Mother Cat Kata. And not too shabby for a first Fable 5.1 experience.
Fable 5.1 Medium: Context verified. The five receipts are all in the Manifest, and every one read the way the straddle predicted: ls shows five trails; rg reads three lines (router 1649, trail lines 3 and 4; target_slot is jira_issue_key, so it correctly carries no hit); the mck.sh reader printed a bare OK with no variable lines; walk.py printed "ready": true; check-ignore printed ignored=1, the labeled non-straddle. The BEFORE half you pasted matches the predictions too, including the FileNotFoundError and the cannot read trail line.
Reading the ride
Two facts are witnessed and one is not, and the banking below is worded to keep them apart. Witnessed: the CAPTURE fence passed on a logged-in Jira page. final_url equals the requested URL exactly, and a logged-out Jira Cloud session lands on id.atlassian.com, so a final_url_exact capture of jira/for-you?tab=assigned is a capture of an authenticated page. Eleven artifacts landed under browser_cache/looking_at/botify.atlassian.net/, and the DECANT gate read AUTHORIZED at 26,885 bytes (your trailing space after the word was stripped, as designed). Not witnessed: whether Atlassian asked you to sign in during those sixty seconds between โMain content locatedโ and CAPTURE, or whether profile default already held the session from an earlier weblogin. The transcript cannot show it and you did not say. So the OWES clause is discharged as โan authenticated ride was captured and decanted,โ with the sign-in moment marked unrecorded rather than assumed. The next ride on a cold profile records it; this one did not need to.
Also worth saying out loud: โPage reload detectedโ was not a Cloudflare challenge. Jiraโs SPA replaces the body on first paint, and the Stage 1 staleness wait caught that. Harmless, and it is the reason the summoning art played for one second.
The noise
You are right about the output, and it is a one-block fix. Every INFO and SUCCESS line in that transcript is loguru from tools/scraper_tools.py, half of them gated on the trailโs verbose flag and half not. The rider already prints its own receipts (Captured. final_url=... artifacts=11), so the loguru lines are a second narrator saying the same thing louder. Car 3 sets the rideโs loguru floor to WARNING inside mother_cat.py, right where it imports the capture function: silent on success, still loud on the provenance fallbacks and driver failures that matter. The summoning art and the CAPTURE prompt are print(), so they survive. PIPULATE_RIDE_LOG=INFO restores the chatter for debugging. This car cannot be straddled from the compile lane; its witness is your next ride, counting | INFO | lines: fifteen this time, zero next time.
Stop two, and a correction to what I said last turn
I told you the per-ticket walk is born in Notebooks/Playground/trails/ because it names a customer. Reading first_context.yaml again, that was wrong in a useful way: the url_env mechanism exists precisely so the trail never names the customer. The trail names variables; the customer lives in the exports file, which is the split bookmark_import.py already enforces. So stop two is a tracked, public, two-stop trail (ticket.yaml: the Jira issue, then the customerโs Botify project), and the per-ticket artifact is one gitignored exports file under Notebooks/Client_Work/tickets/. That file is filled in two stages, which matches the loopโs shape: the Jira line you can write the moment stop one hands you a key, and the Botify line you can only write after you have read the ticket, because the ticket is what tells you which project. Car 4 is the trail. The exports file is yours to write by hand; it carries a customer and I do not know the project.
Mac testing stays dangling: nothing here touches a platform branch, and the rideโs Darwin path (webdriver-manager resolving the driver) has no receipt yet.
1. PROBES
rg -n 'jira_for_you.yaml' foo_files.py
rg -n 'an AUTHENTICATED ride' foo_files.py
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | sed -n '2p' | cut -c1-70
rg -n 'PIPULATE_RIDE_LOG' scripts/mother_cat.py
.venv/bin/python scripts/walk.py --trail assets/trails/ticket.yaml 2>&1 | grep -E '"ready"|cannot read|unset'
ls browser_cache/looking_at/botify.atlassian.net/*/
The first reads UNRIDDEN before and RIDDEN 2026-09-01 after, one line either way. The second reads two hits before (the chapter clause and the constitution clause, counted from the previous payload, so treat the absolute as a prediction) and zero after; the replacement text is spelled so the epitaph cannot fire on that exact phrase. The third is the cap: 20 before and 20 after, a predicted delta of zero, because one line enters at the top and one leaves at the bottom. The fourth shows which line sits at the top: the menu-recall receipt before, the ride receipt after. The fifth reads nothing before and the one mechanism line after. The sixth reads cannot read trail before and, after, "ready": false with two unset environment variable lines naming PIPULATE_TRAIL_JIRA_URL and PIPULATE_TRAIL_BOTIFY_URL, which is the correct reading from a lane where nothing is exported. The seventh is not a straddle; it lists the artifacts the ride wrote, and the directory names carry only your employerโs host and a path hash.
2. NEXT CONTEXT
! rg -n 'jira_for_you.yaml' foo_files.py
! rg -n 'an AUTHENTICATED ride' foo_files.py
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | sed -n '2p' | cut -c1-70
! rg -n 'PIPULATE_RIDE_LOG' scripts/mother_cat.py
! .venv/bin/python scripts/walk.py --trail assets/trails/ticket.yaml 2>&1 | grep -E '"ready"|cannot read|unset'
! ls browser_cache/looking_at/botify.atlassian.net/*/
foo_files.py
assets/trails/ticket.yaml
assets/trails/jira_for_you.yaml
scripts/mother_cat.py
scripts/connectors/jira.py
scripts/connectors/botify.py
3. PATCHES
A caveat on Cars 1 and 2 before the interlock finds it for you: foo_files.py is not in this compile. Their SEARCH anchors are copied from the previous payloadโs raw source, where each block was contiguous, so the exact-match interlock is the fence. If either car refuses, delete it and re-emit next turn with foo_files.py in context; it is already on the NEXT CONTEXT list.
Car 1, bank the ride. Three blocks, one commit story: flip the router line, discharge the chapterโs OWES, discharge the constitutionโs OWES.
Target: foo_files.py
[[[SEARCH]]]
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; UNRIDDEN
[[[DIVIDER]]]
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; RIDDEN 2026-09-01
[[[REPLACE]]]
Target: foo_files.py
[[[SEARCH]]]
# STILL OWED: an AUTHENTICATED ride (public_walk needs no credential, so SETTLE
# is witnessed only in its trivial form), a signature over the sealed manifest,
# and ONE TRAIL PER AUTH KIND -- none / OAuth / API-key -- each findable by
# name FROM THIS CHAPTER. That last one is what this chapter is for.
[[[DIVIDER]]]
# THE AUTHENTICATED-RIDE DEBT IS DISCHARGED (2026-09-01): jira_for_you captured
# a logged-in Jira page on profile default -- final_url exact, so no
# id.atlassian.com redirect -- and DECANTED it. Whether the sign-in happened
# inside the ride or was inherited from the warmed profile is UNRECORDED; the
# next ride on a cold profile records it.
# STILL OWED: a signature over the sealed manifest, and ONE TRAIL PER AUTH
# KIND -- none / OAuth / API-key -- each findable by name FROM THIS CHAPTER.
# That last one is what this chapter is for.
[[[REPLACE]]]
Target: foo_files.py
[[[SEARCH]]]
# discharged. STILL OWED: (1) the fence-vs-lean-back discrimination shared with
# the VARIANCE-SUPPRESSION RULE; (2) an AUTHENTICATED ride -- public_walk needs
# no credential, so SETTLE was witnessed only in its trivial form.
[[[DIVIDER]]]
# discharged. STILL OWED: (1) the fence-vs-lean-back discrimination shared with
# the VARIANCE-SUPPRESSION RULE. DISCHARGED 2026-09-01: (2) the authenticated
# ride -- jira_for_you captured and decanted a logged-in Jira page on profile
# default, SETTLE in its non-trivial form, sign-in moment unrecorded.
[[[REPLACE]]]
Car 2, the receipts block. One line in at the top, one line out at the bottom, cap held at 20.
Target: foo_files.py
[[[SEARCH]]]
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
[[[DIVIDER]]]
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
# 2026-09-01 ride jira_for_you FIRST AUTHENTICATED RIDE: one stop, CAPTURE passed on a logged-in Jira page (final_url exact, no id.atlassian.com redirect), 11 artifacts under browser_cache/looking_at/botify.atlassian.net/, DECANT AUTHORIZED at 26,885 bytes; compile-lane straddle all five predicted (ls 4 -> 5, rg 0 -> 3, mck reader FileNotFoundError -> OK, walk.py ready false -> true, ignored=1 both sides); sign-in moment UNRECORDED; the ride printed 15 loguru INFO lines the rider had already said in its own voice.
[[[REPLACE]]]
Target: foo_files.py
[[[SEARCH]]]
# 2026-07-20 compile TOOL ROSTER LANDED between Manifest and Story, AST-derived and generated-not-authored; count matched live_registry_count=21 in the same compile.
# --- END RECEIPTS ---
[[[DIVIDER]]]
# --- END RECEIPTS ---
[[[REPLACE]]]
Car 3, the quiet ride.
Target: scripts/mother_cat.py
[[[SEARCH]]]
if not dry_narrate:
from tools.scraper_tools import guided_browser_capture
[[[DIVIDER]]]
if not dry_narrate:
from tools.scraper_tools import guided_browser_capture
# QUIET ON SUCCESS, LOUD ON FAILURE (2026-09-01, the first real ride).
# scraper_tools narrates every step through loguru at INFO, and this
# rider ALREADY narrates the ride in its own voice -- the spoken
# guidance, the CAPTURE prompt, the "Captured. final_url=" receipt --
# so the first jira_for_you ride printed fifteen INFO lines saying
# what the rider had just said. Two narrators, one story. The floor
# moves to WARNING for the ride only: provenance fallbacks, driver
# failures and CDP misses still print, because those change what the
# capture MEANS. PIPULATE_RIDE_LOG=INFO restores the chatter when a
# ride needs debugging. print() output is untouched: the summoning
# art and both fences ride on it, and it is the human's channel.
try:
from loguru import logger as _ride_log
_ride_log.remove()
_ride_log.add(
sys.stderr,
level=os.environ.get("PIPULATE_RIDE_LOG", "WARNING"),
)
except Exception:
pass
[[[REPLACE]]]
Car 4, stop two of the loop. Tracked and public by construction: both stops are url_env, so the file names two variables and never a customer.
Target: assets/trails/ticket.yaml
[[[WRITE_FILE]]]
{
"schema_version": 1,
"name": "ticket",
"description": "Stop two of the ticket loop: one ticket, two pages. The Jira issue, then the customer's Botify project. Both URLs come from your environment and never from this file, so the trail is tracked and the customer is not. Write the ticket's exports file, source it, then ride: mothercat assets/trails/ticket.yaml",
"defaults": {
"take_screenshot": false,
"headless": false,
"is_notebook_context": false,
"persistent": true,
"profile_name": "default",
"verbose": true,
"override_cache": true,
"delay_range": null
},
"stops": [
{
"name": "issue",
"label": "Jira issue",
"guidance": "Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.",
"url_env": "PIPULATE_TRAIL_JIRA_URL",
"target_slot": "jira_issue_key",
"harvest_regex": "^[A-Z][A-Z0-9]+-[0-9]+$",
"connector": {
"script": "scripts/connectors/jira.py",
"argv": ["{harvested}"],
"read_only": true
}
},
{
"name": "project",
"label": "Botify project",
"guidance": "Stop two of two. The customer's Botify project opens. Sign in if asked. Land on the view the ticket is about, then return to this terminal and type the capture word. After this capture you are asked once more, with a different word, before anything leaves this machine.",
"url_env": "PIPULATE_TRAIL_BOTIFY_URL",
"target_slot": "botify_project",
"harvest_regex": "^[^/\\s]+/[^/\\s]+$",
"connector": {
"script": "scripts/connectors/botify.py",
"argv": ["{harvested}"],
"read_only": true
}
}
]
}
[[[END_WRITE_FILE]]]
The variable names deliberately reuse first_context.yamlโs, so one exports file serves both trails. Car 4 is a WRITE_FILE: d lists it untracked and m stages it.
Ignition: no ignition required for the seven probes; each opens its file at call time. The ride is the witness for Car 3 and the smoke for Car 4, hand-run and never echoed. First, re-ride mothercat assets/trails/jira_for_you.yaml and count INFO lines: fifteen last time, zero now, with the summoning art and both prompts intact; DECANT or decline as you like, the count is the reading. Second, write the exports file by hand, outside git: Notebooks/Client_Work/tickets/PS-10559.exports.sh containing one line for now, export PIPULATE_TRAIL_JIRA_URL='https://botify.atlassian.net/browse/PS-10559', then source it and run mothercat assets/trails/ticket.yaml --dry-narrate, which will refuse at stop two naming PIPULATE_TRAIL_BOTIFY_URL. That refusal is correct: you cannot know the project until you have read the ticket, and the walk is telling you to go read it. jira PS-10559 in the shell reads it into your terminal without a browser; add the Botify export line once the project is known, re-source, and ride for real.
4. PROMPT
Four cars landed: the ride banked in foo_files.py (Car 1), the receipts block rotated (Car 2), the ride's loguru floor moved to WARNING (Car 3), and ticket.yaml, the two-stop per-ticket trail with url_env stops (Car 4). Read the seven live receipts first: the router line RIDDEN, 'an AUTHENTICATED ride' at zero, the receipts count still 20 with the ride receipt on top, PIPULATE_RIDE_LOG present in mother_cat.py, ticket.yaml ready false with exactly two unset-variable lines, and the artifact listing. If Car 1 or Car 2 was refused on exact-match, foo_files.py is in this payload now: re-emit that car against the live text and nothing else. Then read the re-ride of jira_for_you below and report the INFO line count; zero is the witness for Car 3. Then read the ticket.yaml dry-narrate and, if I have written both export lines, the real ride. Next: decide whether the jira connector should run at the end of the ticket ride so the issue text lands in the DECANT bundle beside the capture, given that mother_cat.py declares connector execution out of scope and walk.py already builds the argv for it. Argue both sides before proposing a car.
5. EXTERNAL DELIVERABLES
No deliverables this turn. The exports file is on your machine and carries a customer, so it is hand-written under Notebooks/Client_Work/ and never rides a patch.
MikeLev.in:
1: Probe (the before โreadโ):
Blast Radius Check to establish bisection Left-hand Causal Boundary. It is a Popper-thing. Science.
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ rg -n 'jira_for_you.yaml' foo_files.py
rg -n 'an AUTHENTICATED ride' foo_files.py
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | sed -n '2p' | cut -c1-70
rg -n 'PIPULATE_RIDE_LOG' scripts/mother_cat.py
.venv/bin/python scripts/walk.py --trail assets/trails/ticket.yaml 2>&1 | grep -E '"ready"|cannot read|unset'
ls browser_cache/looking_at/botify.atlassian.net/*/
1649:# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; UNRIDDEN
773:# the VARIANCE-SUPPRESSION RULE; (2) an AUTHENTICATED ride -- public_walk needs
1606:# STILL OWED: an AUTHENTICATED ride (public_walk needs no credential, so SETTLE
21
# 2026-09-01 menu recall car: boot_menu.py --recall + flake.nix menu()
"ready": false,
"cannot read trail /home/mike/repos/pipulate/assets/trails/ticket.yaml: [Errno 2] No such file or directory: '/home/mike/repos/pipulate/assets/trails/ticket.yaml'"
accessibility_tree.json diff_simple_dom.txt links.md seo.md source.html
accessibility_tree_summary.txt headers.json network_log.jsonl simple_hydrated_dom.html
diff_simple_dom.html hydrated_dom.html optics_manifest.txt simple_source_html.html
(nix) pipulate $
2: Context (the after โreadโ):
# adhoc.txt _ _ _ to set context____ _ _ ___ ____ _ Simpson Couch Gag Here (explain anything to the audience you feel needs it explained)
# / \ __| | | | | | ___ ___ / ___| | | |/ _ \| _ \| |
# ahe/ _ \ / _` | | |_| |/ _ \ / __| | | | |_| | | | | |_) | | Not disappointed by 1st exposure to Fable 5.1
# ahc ___ \ (_| | | _ | (_) | (__ | |___| _ | |_| | __/|_|
# /_/ \_\__,_| |_| |_|\___/ \___| \____|_| |_|\___/|_| (_)
# Ad Hoc CHOP: The Not-Managed-by-Git Safe-for-Client-Data place
# OPTIONAL BUT BIG FOR FULL CONTEXT-WINDOW STORYTELLING
# ! python scripts/articles/lsa.py -t 1 --reverse --fmt dated-slugs # <-- The "Rolling Pin" that gives the 40K foot book-spine view of book-ore.
# GLOSSARY.md # <-- I think this glossary goes well with the book-ore spine to do world building.
# scripts/articles/lsa.py # <-- Useful for refining commands like `posts`, critical to Second Brain concept.
# ~/repos/nixos/autognome.py # <-- Letting the AIs really understand my environment (The Brave Little Tailor punches above Their Weight Class proving the dunning-kruger effect the gate-keeper's (lower-case) lament.)
# init.lua # <-- Daily driver hot-keys that overlap with aliases in flake.nix
# STILL BIG BUT LESS OPTIONAL (especially flake.nix)
# flake.nix # <-- THE ONE BIG THING TO INCLUDE Infrastructure as Code (IaC) tells LLM about your system down to the metal
# prompt_foo.py # <-- This very content-compiling system
# foo_files.py # <-- This is the router, evolving book outline and the things you pin-up to produced the recursive self-improvement loops
# TINY ILLUMINATING (OK to include every time / automatically = `apply.py`, `.gitignore`, `.gitattributes`)
# requirements.in # <-- All known dependencies and (necessary) version pinning. WORA gotcha's exposed.
# __init__.py # <-- Master versioning
# pyproject.toml # <-- The PyPI Packaging details
# OPTIONAL ACTUATORS (cheap and good to include to expand the AI's capabilities)
# cli.py # <-- Catch-all actuator for PyPI envs, Python anchoring, MCP tool-call (plus alternatives) and **kwargs like wrapping for CLI
# scripts/xp.py # <-- Transforms host OS copy-paste buffer player-piano music into context-payload.
# scripts/ai.py # <-- How I constantly use local AI to write git commit messages with `m` alias.
# scripts/crawl.py # <-- Feel free to ask for something to be crawled and included in the next turn.
# scripts/weblogin.py # <-- Lets the user "warm up" the cache for their web logins at their leisure on a profile that persists.
# MISCELLANEOUS (rare to include but sometimes critical)
# scripts/foo_cartridge.py # Needs description
# scripts/foo_replay.py # Needs description
# release.py # <-- How everything ends up where it does (GitHub, PyPI, etc.)
# imports/voice_synthesis.py # <-- The wand can talk to you
# imports/ascii_displays.py # <-- Where all the ASCII Art lives
# scripts/release/version_sync.py # <-- Needs to be wrapped into release.py and eliminated, I think.
# --- Under this line is were you paste what the AI gives you ---
# --- We call it context but it's really just the right-hand ---
# --- blast-radius of the "probes" to make this all science. ---
# --- END `adhoc.txt` TEMPLATE ---
# STICKBUG & MOTHER CAT KATA
# assets/trails/botify_pageworkers.yaml
# assets/installer/mck.sh
# assets/installer/replay.sh
# assets/trails/first_context.yaml
# assets/trails/practice.yaml
# assets/trails/public_walk.yaml
# scripts/bookmark_import.py
# scripts/boot_menu.py
# scripts/connectors/README.md
# scripts/connectors/botify.py
# scripts/connectors/confluence.py
# scripts/connectors/gmail.py
# scripts/connectors/gsc.py
# scripts/connectors/jira.py
# scripts/connectors/mcp.py
# scripts/connectors/mcp_warm.py
# scripts/connectors/sheets.py
# scripts/connectors/slack.py
# scripts/connectors/wallet.py
# scripts/mother_cat.py
# scripts/sources_menu.py
# scripts/walk.py
# scripts/walk_cartridge.py
# scripts/walk_compile.py
# scripts/weblogin.py
# tools/scraper_tools.py
# # # adhoc.txt -- Cleanup inert public_walk environment export block
# #
# # # --- BEFORE/AFTER STRADDLE ---
# # ! grep -n -C 2 'PIPULATE_TRAIL_WALK_ONE_URL' assets/installer/mck.sh || echo "export_block_removed"
# # ! bash -n assets/installer/mck.sh; echo "mck_syntax=$?"
# # ! bash assets/installer/mck.sh --where
# #
# # # --- TARGET SCRIPT ---
# # assets/installer/mck.sh
# #
# # ! rg -n -F 'TRAIL_NAME="${TRAIL_NAME:-public_walk}"' assets/installer/mck.sh
# # ! rg -n -e '^ *walk\(\)' -e '^ *alias walk=' flake.nix; echo "shell_walk_exit=$?"
# # ! test -e walk; echo "root_walk_exists=$?"
# # ! rg -n -e 'alias mothercat=' -e 'Three words to start from' flake.nix scripts/boot_menu.py
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! bash -n walk; echo "walk_syntax=$?"
# # ! bash walk --where
# # ! rg -n -e '^ *alias walk=' -e '^ *walk\(\)' -e 'writeShellScriptBin "walk"' flake.nix; echo "shell_walk_exit=$?"
# # ! .venv/bin/python -c 'import sys; sys.path.insert(0,"scripts"); import boot_menu as b; print("count=" + b._count_word(len(b.DOOR_TWO_WORDS))); print(" ".join(w for w, _ in b.DOOR_TWO_WORDS))'
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! rg -in "three words|four words|door 2" flake.nix scripts/ assets/ README.md
# # ! walk --where
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! python scripts/connectors/wallet.py check slack
# # ! python -c "import os, sys; from pathlib import Path; sys.path.insert(0, '.'); from scripts.connectors import wallet; pairs = wallet._dotenv_pairs(); print('env SLACK_USER_TOKEN:', bool(os.getenv('SLACK_USER_TOKEN')), 'env SLACK_BOT_TOKEN:', bool(os.getenv('SLACK_BOT_TOKEN')), 'vault SLACK_USER_TOKEN:', 'SLACK_USER_TOKEN' in pairs, 'vault SLACK_BOT_TOKEN:', 'SLACK_BOT_TOKEN' in pairs)"
# # ! python scripts/connectors/wallet.py warm slack --dry-run
#
# /home/mike/repos/trimnoir/_posts/2026-08-30-terminal-native-mcp-practice.md
# deleteme.txt
# Now that slack is working (on my workspace) we trim back things here to just the stick bug and Mother Cat Kata stuff
# deleteme.txt
# deleteme2.txt
! rg -n 'jira_for_you.yaml' foo_files.py
! rg -n 'an AUTHENTICATED ride' foo_files.py
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | sed -n '2p' | cut -c1-70
! rg -n 'PIPULATE_RIDE_LOG' scripts/mother_cat.py
! .venv/bin/python scripts/walk.py --trail assets/trails/ticket.yaml 2>&1 | grep -E '"ready"|cannot read|unset'
! ls browser_cache/looking_at/botify.atlassian.net/*/
foo_files.py
assets/trails/ticket.yaml
assets/trails/jira_for_you.yaml
scripts/mother_cat.py
scripts/connectors/jira.py
scripts/connectors/botify.py
deleteme3.txt
3: Patches (the experiment between the reads):
Blast Radius Check to establish bisection Left-hand Causal Boundary. It is a Popper-thing. Science.
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
(nix) pipulate $ d
diff --git a/foo_files.py b/foo_files.py
index 0e58966e..9aa42377 100644
--- a/foo_files.py
+++ b/foo_files.py
@@ -770,8 +770,9 @@ AI_PHOOEY_CHOP = r"""#
# green end to end -- three stops, three CAPTURE fences, three wire-provenance
# captures, one DECANT bundle to the clipboard. That half of the OWES is
# discharged. STILL OWED: (1) the fence-vs-lean-back discrimination shared with
-# the VARIANCE-SUPPRESSION RULE; (2) an AUTHENTICATED ride -- public_walk needs
-# no credential, so SETTLE was witnessed only in its trivial form.
+# the VARIANCE-SUPPRESSION RULE. DISCHARGED 2026-09-01: (2) the authenticated
+# ride -- jira_for_you captured and decanted a logged-in Jira page on profile
+# default, SETTLE in its non-trivial form, sign-in moment unrecorded.
# THE SEED REDUCTION (30-and-3 banked 2026-08-01; the fan-out lives in the
# article, only the three survivors live here, per the rule that a reduction
# written down is a traversal never repeated):
@@ -1603,10 +1604,14 @@ pyproject.toml # <-- The PyPI Packaging details
# re-sealed to identical digests 2026-08-07; the DECANT egress fence and the
# consent surface landed 2026-08-07; a filled authoring surface compiled to a
# trail that walk.py loaded unmodified 2026-08-09.
-# STILL OWED: an AUTHENTICATED ride (public_walk needs no credential, so SETTLE
-# is witnessed only in its trivial form), a signature over the sealed manifest,
-# and ONE TRAIL PER AUTH KIND -- none / OAuth / API-key -- each findable by
-# name FROM THIS CHAPTER. That last one is what this chapter is for.
+# THE AUTHENTICATED-RIDE DEBT IS DISCHARGED (2026-09-01): jira_for_you captured
+# a logged-in Jira page on profile default -- final_url exact, so no
+# id.atlassian.com redirect -- and DECANTED it. Whether the sign-in happened
+# inside the ride or was inherited from the warmed profile is UNRECORDED; the
+# next ride on a cold profile records it.
+# STILL OWED: a signature over the sealed manifest, and ONE TRAIL PER AUTH
+# KIND -- none / OAuth / API-key -- each findable by name FROM THIS CHAPTER.
+# That last one is what this chapter is for.
# THE PATHS BELOW STAY COMMENTED ON PURPOSE: a commented path costs zero
# payload tokens and still drops the file out of the Paintbox, because
# update_paintbox_in_place strips the leading hash before deciding a path is
@@ -1646,7 +1651,7 @@ pyproject.toml # <-- The PyPI Packaging details
# assets/trails/public_walk.yaml # profile default; SETTLE trivial; RIDDEN 2026-08-01
# assets/trails/first_context.yaml # profile default; SETTLE real; UNRIDDEN
# assets/trails/botify_pageworkers.yaml # profile botify; SETTLE real; UNRIDDEN
-# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; UNRIDDEN
+# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; RIDDEN 2026-09-01
# tests/test_mck_rep2.py # <-- Rep 2: the earmark's owed side-by-side witness
# assets/installer/mck.sh # <-- THE LAUNCHER: curl -fsSL pipulate.com/mck.sh | bash
# assets/installer/replay.sh # <-- OFF the roster 2026-08-01; re-add needs syntax + one ride + a pinned verifier fetch
(nix) pipulate $ m
๐ Committing: chore: Update documentation for jira_for_you trail
[main 82ea6c85] chore: Update documentation for jira_for_you trail
1 file changed, 12 insertions(+), 7 deletions(-)
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
(nix) pipulate $ d
diff --git a/foo_files.py b/foo_files.py
index 9aa42377..ac8db75b 100644
--- a/foo_files.py
+++ b/foo_files.py
@@ -58,6 +58,7 @@ AI_PHOOEY_CHOP = r"""#
# Honeybot telemetry fetched 2026-09-01T20:53Z
# --- END STATS ---
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
+# 2026-09-01 ride jira_for_you FIRST AUTHENTICATED RIDE: one stop, CAPTURE passed on a logged-in Jira page (final_url exact, no id.atlassian.com redirect), 11 artifacts under browser_cache/looking_at/botify.atlassian.net/, DECANT AUTHORIZED at 26,885 bytes; compile-lane straddle all five predicted (ls 4 -> 5, rg 0 -> 3, mck reader FileNotFoundError -> OK, walk.py ready false -> true, ignored=1 both sides); sign-in moment UNRECORDED; the ride printed 15 loguru INFO lines the rider had already said in its own voice.
# 2026-09-01 menu recall car: boot_menu.py --recall + flake.nix menu(); hook-text probe 0 -> 1; recall list absent -> five words, exit 0 on BOTH sides so the printed list is the discriminator; rg 'four words|three words' 4 hits before and after, all historical prose, so the README/AGENTS stale-count follow-up is DISCHARGED UNOPENED.
# 2026-08-30 compile KEY/VALUE strike 6: sigil keys 24 -> 29; EARMARK 59 -> 54; five-pattern tombstone 5 -> 0 (grep's expected NON-ZERO EXIT 1); RECEIPTS held 20; ast_ok; foo_files.py 272,536 -> 264,473 B (-2,120 tok), GLOSSARY.md 71,553 -> 82,577 B (+2,766 tok); raw byte predictions missed their bands by 323 B high and 743 B low, and both delta magnitudes were over-predicted 14-15%, so dropping the n=1 correction removed the sign flip but put neither byte side in band; wc -l 3114 -> 2958, one below prediction because the five landed diff deltas sum to -156 (-25-25-30-29-47), not -155. Five graduations landed.
# 2026-08-30 compile KEY/VALUE strike 5: the 204-line MCP cluster cut by gated sed on its first GO; sigil keys 18 -> 24; EARMARK 64 -> 59; six readings six exact including wc -l 3114 derived through the sed range; foo_files.py 297,413 -> 272,536 B (-6,372 tok); GLOSSARY.md 59,602 -> 71,553 B (+2,959 tok); both byte predictions 0.6% and 1.3% high, just outside their bands in the same direction, and last turn's 9% correction proved an n=1 overfit that swung the glossary error from 9% high to 8% low. THE GATE SPEAKS A VERDICT witnessed both branches GO on its first flight. Mcp-Session-Id promoted to OBSERVED as a header NAME (mcp.py:444 reads it, :488/:554 print session=yes iff truthy); the round trip stays INFERRED. THE PLACEHOLDER THAT CLAIMS TO RUN discharged: scripts/connectors/noop.py exists and public_walk.yaml names it at all three stops.
@@ -78,7 +79,6 @@ AI_PHOOEY_CHOP = r"""#
# 2026-07-30 GLOSSARY LANDED at the repo root, both columns kept (handle for memory, plain term for search); new handles get their entry there, never a second definition in the router; discharges the PROMPT-FU GLOSSARY earmark of 2026-07-26.
# 2026-07-29 operator lane MCP VENDOR RECEIPT and FDR CHANNEL: mcp_warm.py minted a PKCE bearer (scope mcp_read_write, expires_in 300) and tools/call list_projects printed the four-tuple against server one; mcp.py had read the response side transiently and persisted nothing (capable-of-FDR, not FDR) until the FDR channel landed the same day, and its first flight was a RED gate2 401 that still flushed browser_cache/mcp/<host>/<utc>__<verb>.json -- the recording exists because of the crash; frame mcp-receipt-v1, auth recorded by env name only.
# 2026-07-25 harness MCP FAULT HARNESS 20/20 against the unmodified client (handshake, Mcp-Session-Id round trip with a raw-httpx no-header control, JSON and SSE framings, three determinism classes, gate attribution on five manufactured reds); the harness shares mcp.py's spec reading, so agreement was a tautology and the protocol strings stayed INFERRED; the same session read 36 server URLs and 8 tool namespaces off an injected manifest.
-# 2026-07-20 compile TOOL ROSTER LANDED between Manifest and Story, AST-derived and generated-not-authored; count matched live_registry_count=21 in the same compile.
# --- END RECEIPTS ---
# Most of what's below are relative paths to files in GitHub/pipulate/pipulate
(nix) pipulate $ m
๐ Committing: chore: Update ride telemetry receipt content
[main f24fed7f] chore: Update ride telemetry receipt content
1 file changed, 1 insertion(+), 1 deletion(-)
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'scripts/mother_cat.py'.
(nix) pipulate $ d
diff --git a/scripts/mother_cat.py b/scripts/mother_cat.py
index b4831217..ac4d02d5 100644
--- a/scripts/mother_cat.py
+++ b/scripts/mother_cat.py
@@ -346,6 +346,26 @@ async def _ride_async(trail_path, dry_narrate=False):
guided_browser_capture = None
if not dry_narrate:
from tools.scraper_tools import guided_browser_capture
+ # QUIET ON SUCCESS, LOUD ON FAILURE (2026-09-01, the first real ride).
+ # scraper_tools narrates every step through loguru at INFO, and this
+ # rider ALREADY narrates the ride in its own voice -- the spoken
+ # guidance, the CAPTURE prompt, the "Captured. final_url=" receipt --
+ # so the first jira_for_you ride printed fifteen INFO lines saying
+ # what the rider had just said. Two narrators, one story. The floor
+ # moves to WARNING for the ride only: provenance fallbacks, driver
+ # failures and CDP misses still print, because those change what the
+ # capture MEANS. PIPULATE_RIDE_LOG=INFO restores the chatter when a
+ # ride needs debugging. print() output is untouched: the summoning
+ # art and both fences ride on it, and it is the human's channel.
+ try:
+ from loguru import logger as _ride_log
+ _ride_log.remove()
+ _ride_log.add(
+ sys.stderr,
+ level=os.environ.get("PIPULATE_RIDE_LOG", "WARNING"),
+ )
+ except Exception:
+ pass
stops = trail["stops"]
print(f"Riding trail '{trail['name']}' -- {len(stops)} stop(s).\n")
(nix) pipulate $ m
๐ Committing: chore: Add logging configuration for `mother_cat.py`
[main 15e28ce6] chore: Add logging configuration for `mother_cat.py`
1 file changed, 20 insertions(+)
(nix) pipulate $ patch
(nix) pipulate $ app
โ
WHOLE-FILE WRITE: CREATED 'assets/trails/ticket.yaml'.
(nix) pipulate $ git add assets/trails/ticket.yaml
(nix) pipulate $ m
๐ Committing: fix: Add ticket.yaml schema and stop definitions
[main 72e36af9] fix: Add ticket.yaml schema and stop definitions
1 file changed, 43 insertions(+)
create mode 100644 assets/trails/ticket.yaml
(nix) pipulate $ git push
Enumerating objects: 21, done.
Counting objects: 100% (21/21), done.
Delta compression using up to 48 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 3.55 KiB | 605.00 KiB/s, done.
Total 15 (delta 10), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (10/10), completed with 6 local objects.
To github.com:pipulate/pipulate.git
cbdcb99a..72e36af9 main -> main
(nix) pipulate $
Okay nice. I can do tests now.
(nix) pipulate $ g
Blast Radius Check to establish bisection Left-hand Causal Boundary. It is a Popper-thing. Science.
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ mothercat assets/trails/jira_for_you.yaml
Riding trail 'jira_for_you' -- 1 stop(s).
==================================================================
THIS WALK: jira_for_you -- 1 stop(s)
==================================================================
stops, in order for_you
it opens directly https://botify.atlassian.net/jira/for-you?tab=assigned
names as runnable scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/1: for_you ---
One stop. A visible browser opens on your Jira For You page, assigned tab. If Atlassian asks you to sign in, sign in. That session stays in this browser profile, so next time it will not ask. Look down the list and choose the ticket you are going to close next, and note its key. Then return to this terminal and type the capture word.
โณ THE SUMMONING โ thumper planted, hooks in hand
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cloudflare drums the sand beneath us;
/|\ we wait it out, staked and hooked.
~~ ๐ต jeopardy.wav looping until the Maker surfaces ~~
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
Captured. final_url=https://botify.atlassian.net/jira/for-you?tab=assigned artifacts=11
Ride complete. Every stop produced a capture receipt.
๐ DECANT gate: ARMED -- 1 stop(s), 29,283 bytes assembled, still ON THIS MACHINE ONLY.
Type DECANT to copy it to your clipboard (anything else keeps it here).
DECANT> DECANT
AUTHORIZED by human: handing 29,283 bytes to the clipboard writer.
Markdown output copied to clipboard
Paste it into any ChatBot (Claude, ChatGPT, Gemini) and it
will walk you through everything from here.
(nix) pipulate $ vim
(nix) pipulate $ xv deleteme3.txt
(nix) pipulate $ ahe
(nix) pipulate $
Wow, friggin nice. Okay, so we use environment variables for parameters to be fed to these walks, got it! That way I can do demos in the future including full code with the URLs typed once into the shell through exports at the beginning of the session and I donโt have to worry about sanitizing the articles as I go or code leaks in repos. Nice! I can keep template work even for Botify on things where client URLs are used, but the client URLs stay out of it because environment variables. Got it! Nice.
(nix) pipulate $ export PIPULATE_TRAIL_JIRA_URL='https://botify.atlassian.net/browse/PS-10559'
(nix) pipulate $ mothercat assets/trails/ticket.yaml --dry-narrate
Riding trail 'ticket' -- 2 stop(s).
==================================================================
THIS WALK: ticket -- 2 stop(s)
==================================================================
stops, in order issue, project
URLs YOU supply PIPULATE_TRAIL_BOTIFY_URL, PIPULATE_TRAIL_JIRA_URL
names as runnable scripts/connectors/botify.py, scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/2: issue ---
Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.
(dry-narrate: browser and capture skipped)
--- Stop 2/2: project ---
Stop two of two. The customer's Botify project opens. Sign in if asked. Land on the view the ticket is about, then return to this terminal and type the capture word. After this capture you are asked once more, with a different word, before anything leaves this machine.
(dry-narrate: browser and capture skipped)
Dry narration complete; no captures were attempted.
(nix) pipulate $
And now without the dry run:
(nix) pipulate $ mothercat assets/trails/ticket.yaml
Riding trail 'ticket' -- 2 stop(s).
==================================================================
THIS WALK: ticket -- 2 stop(s)
==================================================================
stops, in order issue, project
URLs YOU supply PIPULATE_TRAIL_BOTIFY_URL, PIPULATE_TRAIL_JIRA_URL
names as runnable scripts/connectors/botify.py, scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/2: issue ---
Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.
โณ THE SUMMONING โ thumper planted, hooks in hand
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cloudflare drums the sand beneath us;
/|\ we wait it out, staked and hooked.
~~ ๐ต jeopardy.wav looping until the Maker surfaces ~~
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
Captured. final_url=https://botify.atlassian.net/browse/PS-10559 artifacts=11
ADVANCE -> next stop.
--- Stop 2/2: project ---
Stop two of two. The customer's Botify project opens. Sign in if asked. Land on the view the ticket is about, then return to this terminal and type the capture word. After this capture you are asked once more, with a different word, before anything leaves this machine.
TRAIL INVALID (Car A refused): stop 'project' requires environment variable PIPULATE_TRAIL_BOTIFY_URL
(nix) pipulate $
Wow! I even understood all that. Nice. The deleteme3.txt is not the single
ticket walk but was the assigned ticket one FYI.
4: Prompt: Four cars landed: the ride banked in foo_files.py (Car 1), the receipts block rotated (Car 2), the rideโs loguru floor moved to WARNING (Car 3), and ticket.yaml, the two-stop per-ticket trail with url_env stops (Car 4). Read the seven live receipts first: the router line RIDDEN, โan AUTHENTICATED rideโ at zero, the receipts count still 20 with the ride receipt on top, PIPULATE_RIDE_LOG present in mother_cat.py, ticket.yaml ready false with exactly two unset-variable lines, and the artifact listing. If Car 1 or Car 2 was refused on exact-match, foo_files.py is in this payload now: re-emit that car against the live text and nothing else. Then read the re-ride of jira_for_you below and report the INFO line count; zero is the witness for Car 3. Then read the ticket.yaml dry-narrate and, if I have written both export lines, the real ride. Next: decide whether the jira connector should run at the end of the ticket ride so the issue text lands in the DECANT bundle beside the capture, given that mother_cat.py declares connector execution out of scope and walk.py already builds the argv for it. Argue both sides before proposing a car.
5: Deliverables: The โriggingโ I need or the harness dragging me along or the Mother Cat picking me up by the scruff of the neck and carrying me โ however you want to think about it. Lowering friction and raising powerful driving force, making the so-called โUnix wayโ like riding a bicycle. Iโm going to test on the Mac after this. Hmm, letโs seeโฆ a real release always when Mac testing.
(nix) pipulate $ exit
exit
Saving session...
...saving history...truncating history files...
...completed.
michaellevin@MichaelMacBook-Pro ~ % rm -rf pipulate
michaellevin@MichaelMacBook-Pro ~ % curl -fsSL https://pipulate.com/install.sh | bash
--------------------------------------------------------------
๐ Welcome to the Pipulate Installer ๐
Local-first, Nix-reproducible, and yours to delete.
--------------------------------------------------------------
๐ Checking prerequisites...
โ
All required tools found.
๐ Checking target directory: /Users/michaellevin/pipulate
โ
Target directory is available.
๐ Creating directory '/Users/michaellevin/pipulate'
๐ฅ Downloading Pipulate source code...
#=#=- # #
โ
Download complete.
๐ฆ Extracting source code...
โ
Extraction complete. Source code installed to '/Users/michaellevin/pipulate'.
๐ Now in directory: /Users/michaellevin/pipulate
๐ Fetching the shared deploy key from https://pipulate.com/key.rot...
(Public, ROT13-encoded, pull-only: it exists so this folder can fetch
updates without a GitHub account. nix develop decodes it into
~/.ssh/id_rsa only if no key is there already.)
โ
Deploy key downloaded.
๐ Deploy key saved as .ssh/rot (mode 600).
๐ Starting the Pipulate environment...
--------------------------------------------------------------
Source is in place at: /Users/michaellevin/pipulate
To come back later, run:
cd /Users/michaellevin/pipulate && nix develop -L
--------------------------------------------------------------
Setting up app identity as 'pipulate'...
โ
Application identity set.
Creating ./run -- a one-file shortcut for the cd-and-nix-develop line above.
Next, nix develop builds the environment and turns this folder into a
git repository (the 'magic cookie' step) so it can auto-update from now on.
๐ Booting the Forever Machine...
Please wait while the Nix environment hydrates...
Restored session: Tue Sep 1 17:34:18 EDT 2026
๐ Transforming installation into git repository...
Creating temporary clone in /tmp/nix-shell.xdJ6IP/tmp.3hde2Qsz0b...
Cloning into '/tmp/nix-shell.xdJ6IP/tmp.3hde2Qsz0b'...
remote: Enumerating objects: 376, done.
remote: Counting objects: 100% (376/376), done.
remote: Compressing objects: 100% (342/342), done.
remote: Total 376 (delta 24), reused 195 (delta 9), pack-reused 0 (from 0)
Receiving objects: 100% (376/376), 3.14 MiB | 17.09 MiB/s, done.
Resolving deltas: 100% (24/24), done.
Preserving app identity and credentials...
Creating backup of current directory in /tmp/nix-shell.xdJ6IP/tmp.SjFaiy6D5z...
Moving git repository into place...
โ
Successfully transformed into git repository!
Original files backed up to: /tmp/nix-shell.xdJ6IP/tmp.SjFaiy6D5z
Checking for updates...
Temporarily stashing local JupyterLab settings...
From https://github.com/pipulate/pipulate
* branch main -> FETCH_HEAD
Already up to date.
Found ~/.ssh/id_rsa -- switching the git remote to SSH so auto-updates use it.
INFO: Setting up your personal Playground...
(Determinate Nix 3.19.1) 2.34.6 ยท Python 3.12.13 ยท v2.53 ยท ~/pipulate
๐ง Fresh install detected โ packages downloading...
โ
291 packages ready.
๐ 12 starter file(s) copied into Notebooks/ -- yours to edit.
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ nix develop -- a reproducible *nix shell :: pick a door โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ [1] Start JupyterLab plus the app server and browser tabs โ
โ [2] Just the shell nothing starts -- five words wait at the prompt โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ waiting for your choice -- Ctrl+C also drops to the shell โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
[2] Just the shell. Nothing started -- no JupyterLab, no server.
Five words to start from:
walk take the guided tour -- public pages, nothing to log into
sources see what this shell can reach outside this machine
brief compile this workshop into your clipboard for an AI
pu change your mind and start the app server after all
menu print this list again once it scrolls away
(nix:nix-shell-env) (nix) pipulate $ mothercat assets/trails/ticket.yaml
Riding trail 'ticket' -- 2 stop(s).
==================================================================
THIS WALK: ticket -- 2 stop(s)
==================================================================
stops, in order issue, project
URLs YOU supply PIPULATE_TRAIL_BOTIFY_URL, PIPULATE_TRAIL_JIRA_URL
names as runnable scripts/connectors/botify.py, scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/2: issue ---
/Users/michaellevin/pipulate/.venv/lib/python3.12/site-packages/huggingface_hub/utils/_validators.py:205: UserWarning: The `local_dir_use_symlinks` argument is deprecated and ignored in `hf_hub_download`. Downloading to a local directory does not use symlinks anymore.
warnings.warn(
Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
en/en_US/amy/low/en_US-amy-low.onnx: downloading bytes: โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 59.5MB, 5.43MB/s
en/en_US/amy/low/en_US-amy-low.onnx: reconstructing file: 100%|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 63.1MB / 63.1MB, 5.99MB/s
en_US-amy-low.onnx.json: 100%|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 4.16k/4.16k [00:00<00:00, 6.55MB/s]
Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.
TRAIL INVALID (Car A refused): stop 'issue' requires environment variable PIPULATE_TRAIL_JIRA_URL
(nix:nix-shell-env) (nix) pipulate $ export PIPULATE_TRAIL_JIRA_URL='https://botify.atlassian.net/browse/PS-10559'
(nix:nix-shell-env) (nix) pipulate $ mothercat assets/trails/ticket.yaml
Riding trail 'ticket' -- 2 stop(s).
==================================================================
THIS WALK: ticket -- 2 stop(s)
==================================================================
stops, in order issue, project
URLs YOU supply PIPULATE_TRAIL_BOTIFY_URL, PIPULATE_TRAIL_JIRA_URL
names as runnable scripts/connectors/botify.py, scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/2: issue ---
Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
Captured. final_url=https://botify.atlassian.net/browse/PS-10559 artifacts=11
ADVANCE -> next stop.
--- Stop 2/2: project ---
Stop two of two. The customer's Botify project opens. Sign in if asked. Land on the view the ticket is about, then return to this terminal and type the capture word. After this capture you are asked once more, with a different word, before anything leaves this machine.
TRAIL INVALID (Car A refused): stop 'project' requires environment variable PIPULATE_TRAIL_BOTIFY_URL
(nix:nix-shell-env) (nix) pipulate $
Wow! This is almost finished. We never want to be mid-walk and realize that we didnโt set an environment variable we needed to have set up front. A built-in feature of this whole walk system should be for each walk to evaluate whether it actually has all the environment variables it really needs before starting the walk, otherwise if itโs a long walk could you imagine how pissed people would be?
Fable 5.1 Medium: Context verified. Seven receipts in the Manifest, and six read the way the straddle predicted. The router line reads RIDDEN 2026-09-01 at line 1654. 'an AUTHENTICATED ride' reads zero hits with a synthetic exit 1, the expected non-zero. The top receipt line is the ride receipt. PIPULATE_RIDE_LOG sits at lines 357 and 365 of mother_cat.py. The artifact listing shows two capture directories under botify.atlassian.net/, the for-you tab and browse/PS-10559. The seventh receipt, the receipts count, is the one that did not read as predicted, and it is worth a paragraph.
Reading the receipts
The count reads 21 before and 21 after. I predicted 20 and 20. The delta was right and the absolute was wrong, which is the delta-not-absolute rule catching me from the other direction: Car 2 did exactly what it said (one in at the top, one out at the bottom, delta zero), but the block was already one line over its own cap before Car 2 touched it. Nobody was counting; the cap is a comment, not a fence. Car 2 below takes two lines off the bottom while adding this rideโs line, so the block reads 20 after and the cap is true again. Whether it stays true is a probe I now echo every turn.
The ticket.yaml receipt read one unset variable, not two, and that is not a defect: you exported PIPULATE_TRAIL_JIRA_URL in the shell before compiling, so the compile lane inherited it. The reading is correct for the lane it ran in.
Car 3 is witnessed. The jira_for_you re-ride printed zero | INFO | lines, down from fifteen, with the summoning art and both prompts intact and the DECANT gate reading 29,283 bytes. And noted on deleteme3.txt: it is the assigned-tab bundle, and it reads that way (PS-10619 and PS-10559 both listed).
The Mac is the better witness for the thing you asked for. Fresh install green, Determinate Nix 3.19.1, 291 packages. Then the first mothercat assets/trails/ticket.yaml on that machine downloaded a 60 MB Piper voice, printed two Hugging Face warnings, spoke the stop-one guidance aloud, and only then refused for the unset Jira URL. The second attempt captured the issue, ADVANCED, and refused at stop two for the unset Botify URL, same as Linux. Two refusals, both for facts knowable before anything opened. That is the bug, and it is the car.
The pre-flight
walk.pyโs planner already reports every unset variable per stop, and mck.sh already checks them in shell before it rides. But mothercat is the direct alias, it is the Mac path, and neither goes through mck.sh; the rider itself only discovers a missing variable when it reaches the stop that needs it. Car 3 gives the rider its own pre-flight: every url_env across the whole trail, checked before narration, before the consent card, before the browser, refusing with each missing name beside its stop and the export line to type. An exported empty string counts as unset, matching the planner. Under --dry-narrate it is disclosed and not enforced, same shape as the capture-compatibility problems already printed there, because the rehearsal mck.sh forces on first contact must be able to run in a shell that has exported nothing. The per-stop KeyError branch stays as the belt to these braces; after this car it can only fire if the environment changes under a running ride. The shell check in mck.sh is now a second implementation of the same rule; it should retire once the Python one is witnessed on both platforms, and I am naming that as owed rather than cutting it blind.
The connector at DECANT, both sides
For running it: the loop exists to close tickets, and the ticketโs text is the ask. The Jira browse page is a React SPA, so the captured seo_md and accessibility tree carry the description at best and the comments folded, while jira.py returns the whole issue cleanly. The trail already declares the connector with read_only: true, walk.py already builds the argv, and the consent card already says โnames as runnable scripts/connectors/jira.pyโ; the plumbing is half-installed and the bundle would be more useful with the issue text beside the capture.
Against running it, and this side wins: first, the docstringโs โout of scopeโ is a ruling about what the rider is. It is a browser witness; the connector is an API client with a different auth kind (an API token wallet, not a browser profile), and folding it in means the pre-flight must also check wallets, or the ride fails at DECANT on an expired token after two good captures, which is precisely the mid-walk failure you just asked to eliminate. Second, the rider never harvests: {harvested} needs the issue key, and the trailโs target_slot and harvest_regex describe values supplied to the planner by --value, not values scraped from a final_url. Third, and decisive: DECANT gates a bundle whose every part was fenced by CAPTURE, one word per write, and the consent card says so in the โTWO WORDS, TWO ACTSโ lines. Connector output was never fenced by anything. Putting it in the bundle makes DECANT authorize material the human never saw written, and the card would need a third act. Fourth, the bridge already exists and it is Prompt Fu itself: a ! .venv/bin/python scripts/connectors/jira.py PS-10559 line in adhoc.txt puts the issue text beside the capture in a compiled payload with a live exit code, which is the operatorโs compose step anyway. The rider is for the newcomer with a chatbot; the operator has the compile lane. So: no execution car. The ruling is banked in the router line so it is findable from the chapter. The one small car that survives this argument is a future disclosure, not an act: at ride end, print the connector command the human could run next, key harvested from the captured URLโs last path segment. Not this turn; one ride-changing car per ride.
1. PROBES
rg -n 'ticket.yaml.*SETTLE' foo_files.py
rg -c 'assets/trails/ticket.yaml' foo_files.py
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
rg -n 'PRE-FLIGHT|_missing_url_envs' scripts/mother_cat.py
env -u PIPULATE_TRAIL_JIRA_URL -u PIPULATE_TRAIL_BOTIFY_URL .venv/bin/python scripts/mother_cat.py assets/trails/ticket.yaml < /dev/null 2>&1 | grep -E 'Riding|REFUSING|TRAIL INVALID|needs |export '
grep -c '^export' Notebooks/Client_Work/tickets/PS-10559.exports.sh
The first reads zero before and one after: the router line. The second is not a straddle but a reading I want: it counts the Paintbox line plus the router line, so it reads 1 before, and after it reads 1 if the Paintbox self-cleans when a commented path claims the file, 2 if it does not; either number tells me something. The third is the cap: 21 before, 20 after. The fourth reads zero before and the mechanism lines after. The fifth is the straddle that matters. Before, it prints Riding trail 'ticket' and then ONE TRAIL INVALID line naming only the Jira variable, because the old rider learns about stop two only at stop two (and Piper speaks the stop-one guidance during the compile, once; that is the before world). After, no Riding line at all: REFUSING TO RIDE, two needs lines, two export lines, nothing spoken. The sixth reads how many export lines your exports file carries, 1 or 2, without printing the customerโs URL; if the file does not exist it says so, which is also an answer.
2. NEXT CONTEXT
! rg -n 'ticket.yaml.*SETTLE' foo_files.py
! rg -c 'assets/trails/ticket.yaml' foo_files.py
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
! rg -n 'PRE-FLIGHT|_missing_url_envs' scripts/mother_cat.py
! env -u PIPULATE_TRAIL_JIRA_URL -u PIPULATE_TRAIL_BOTIFY_URL .venv/bin/python scripts/mother_cat.py assets/trails/ticket.yaml < /dev/null 2>&1 | grep -E 'Riding|REFUSING|TRAIL INVALID|needs |export '
! grep -c '^export' Notebooks/Client_Work/tickets/PS-10559.exports.sh
foo_files.py
scripts/mother_cat.py
assets/installer/mck.sh
scripts/walk.py
assets/trails/ticket.yaml
mck.sh and walk.py ride along so the shell pre-checkโs retirement can be a car against live text next turn.
3. PATCHES
Car 1, the router line and the ruling. One line after the jira_for_you line; the Paintbox entry is left alone, because it lives only in your working tree and the second probe reports whether the compiler clears it.
Target: foo_files.py
[[[SEARCH]]]
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; RIDDEN 2026-09-01
[[[DIVIDER]]]
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; RIDDEN 2026-09-01
# assets/trails/ticket.yaml # profile default; SETTLE real; url_env x2 (JIRA, BOTIFY) fed by one gitignored exports file per ticket under Notebooks/Client_Work/tickets/; stop two of the ticket loop; RIDDEN 2026-09-01 to stop 1 then REFUSED at stop 2 on an unset url_env, Linux and Mac -- the ride that bought the rider its PRE-FLIGHT. RULING: the connector does NOT run at DECANT (DECANT gates only CAPTURE-fenced material; API auth is a different wallet; the rider never harvests). The bridge to the issue text is a ! line in adhoc.txt.
[[[REPLACE]]]
Car 2, the receipts block. One line in at the top, two out at the bottom, so the block reads 20 and the cap is true again.
Target: foo_files.py
[[[SEARCH]]]
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
[[[DIVIDER]]]
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
# 2026-09-01 ride ticket REFUSED MID-WALK on Linux and Mac: stop 'issue' captured (11 artifacts, final_url browse/PS-10559 exact), ADVANCE, then TRAIL INVALID at 'project' for unset PIPULATE_TRAIL_BOTIFY_URL -- one capture spent for nothing, and on the Mac a 60 MB Piper voice download plus spoken guidance came BEFORE the first refusal; jira_for_you re-ride printed 0 loguru INFO lines (was 15; Car 3 witnessed); Mac fresh install green (Determinate Nix 3.19.1, v2.53, 291 packages); this block read 21 against its cap of 20 before this rotation.
[[[REPLACE]]]
Target: foo_files.py
[[[SEARCH]]]
# 2026-07-29 operator lane MCP VENDOR RECEIPT and FDR CHANNEL: mcp_warm.py minted a PKCE bearer (scope mcp_read_write, expires_in 300) and tools/call list_projects printed the four-tuple against server one; mcp.py had read the response side transiently and persisted nothing (capable-of-FDR, not FDR) until the FDR channel landed the same day, and its first flight was a RED gate2 401 that still flushed browser_cache/mcp/<host>/<utc>__<verb>.json -- the recording exists because of the crash; frame mcp-receipt-v1, auth recorded by env name only.
# 2026-07-25 harness MCP FAULT HARNESS 20/20 against the unmodified client (handshake, Mcp-Session-Id round trip with a raw-httpx no-header control, JSON and SSE framings, three determinism classes, gate attribution on five manufactured reds); the harness shares mcp.py's spec reading, so agreement was a tautology and the protocol strings stayed INFERRED; the same session read 36 server URLs and 8 tool namespaces off an injected manifest.
# --- END RECEIPTS ---
[[[DIVIDER]]]
# --- END RECEIPTS ---
[[[REPLACE]]]
Car 3, the pre-flight. Four blocks in one file: the docstring gains the step, the helper lands beside _announce_consent, the check lands before the capture import, and the per-stop branchโs comment stops claiming to be the only guard.
Target: scripts/mother_cat.py
[[[SEARCH]]]
NARRATE -- Piper reads the stop guidance, best-effort.
[[[DIVIDER]]]
PRE-FLIGHT -- every url_env the WHOLE walk needs is checked
before anything opens, speaks, or writes.
NARRATE -- Piper reads the stop guidance, best-effort.
[[[REPLACE]]]
Target: scripts/mother_cat.py
[[[SEARCH]]]
def _announce_consent(trail_path):
[[[DIVIDER]]]
def _missing_url_envs(stops):
"""Every url_env the WHOLE walk needs that the environment lacks, in stop order.
Returns [(stop_name, var_name), ...], one entry per stop that is short a
URL, so a variable two stops share is named beside each stop that needs
it: the human reads what the walk will do, not a deduplicated set. An
exported empty or whitespace-only string counts as unset, matching
walk.build_plan -- an empty export opens nothing.
"""
missing = []
for stop in stops:
url_env = stop.get("url_env")
if url_env and not os.environ.get(url_env, "").strip():
missing.append((stop["name"], url_env))
return missing
def _announce_consent(trail_path):
[[[REPLACE]]]
Target: scripts/mother_cat.py
[[[SEARCH]]]
guided_browser_capture = None
[[[DIVIDER]]]
# PRE-FLIGHT (2026-09-01, the ticket ride that died at stop two). A trail
# declares every URL it needs before it opens anything, so the rider can
# know at t=0 whether it can finish -- and it used to find out one stop at
# a time. ticket.yaml captured the Jira issue, ADVANCED, and only then
# discovered PIPULATE_TRAIL_BOTIFY_URL was unset; on the Mac the first
# refusal came AFTER a sixty-megabyte voice download and the spoken
# guidance for a stop that would never open. A walk that can fail at its
# last stop for a reason knowable at its first wastes the human's
# captures, and a long walk would waste many. mck.sh already runs this
# check in shell, but `mothercat` is the direct alias and the Mac path,
# and neither passes through mck.sh, so the rider owns it too: EVERY
# missing variable, named beside its stop, with the export line to type,
# before narration, before the consent card, before any browser. Under
# --dry-narrate it is disclosed and not enforced, same as the capture
# problems above: the rehearsal mck.sh forces on first contact must be
# able to run in a shell that has exported nothing yet.
missing_envs = _missing_url_envs(trail["stops"])
if missing_envs:
if dry_narrate:
print("NOTE -- a real ride of this trail would be REFUSED before stop one:")
else:
print("REFUSING TO RIDE -- this walk needs URLs your environment does not have:")
for stop_name, var_name in missing_envs:
print(f" - stop {stop_name!r} needs {var_name}")
print(" Export each one, then ride again:")
seen = set()
for _stop_name, var_name in missing_envs:
if var_name in seen:
continue
seen.add(var_name)
print(f" export {var_name}='https://...'")
if dry_narrate:
print(" (--dry-narrate continues anyway; nothing will open.)")
else:
print(" Nothing opened, nothing was spoken, nothing was written.")
return 2
guided_browser_capture = None
[[[REPLACE]]]
Target: scripts/mother_cat.py
[[[SEARCH]]]
# A stop carries exactly one of `url` or `url_env`. The url_env path
# below is byte-identical to what it always was, including the message
# that names the missing variable.
[[[DIVIDER]]]
# A stop carries exactly one of `url` or `url_env`. The PRE-FLIGHT
# above has already checked every url_env for a real ride, so this
# branch is the belt to those braces: it can only fire if the
# environment changed under a running ride. The message is unchanged.
[[[REPLACE]]]
Ignition: no ignition required. Every probe opens its file at call time, and the fifth probe runs the patched rider itself. The hand-run witness is the real ride, never echoed: env -u PIPULATE_TRAIL_BOTIFY_URL mothercat assets/trails/ticket.yaml should refuse in the first line printed, with nothing spoken and no browser; then source Notebooks/Client_Work/tickets/PS-10559.exports.sh with both lines written and mothercat assets/trails/ticket.yaml should ride both stops to the DECANT gate. If you run the Mac too, the reading to bring back is whether the second ride there still prints the Hugging Face lines; the voice is cached after the first download, so I expect silence, and if it is not silent the voice module is the next noise car.
4. PROMPT
Three cars landed: the ticket.yaml router line with the DECANT ruling (Car 1), the receipts block rotated back to its cap (Car 2), and the rider's PRE-FLIGHT, which checks every url_env across the whole walk before anything opens (Car 3). Read the six live receipts first: the router line at one hit, the ticket.yaml count (1 means the Paintbox self-cleaned, 2 means it did not), the receipts count at 20, the PRE-FLIGHT mechanism lines, the env -u straddle reading REFUSING with two export lines and no Riding line, and the export-line count of the exports file. Then read the hand-run rides below: the refusal with the Botify variable unset, and the full two-stop ride if both export lines were written. Next: mck.sh and walk.py are in this payload; decide whether mck.sh's shell pre-check retires now that the rider owns the check, and if it does, emit the car. Then propose the end-of-ride disclosure line naming the connector command the human could run next, key harvested from the captured URL's last path segment, as a disclosure and not an act.
5. EXTERNAL DELIVERABLES
No deliverables this turn. The Botify export line is still yours to write by hand, after reading PS-10559, into the gitignored exports file; it carries a customer and never rides a patch.
MikeLev.in:
1: Probe (the before โreadโ):
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ rg -n 'ticket.yaml.*SETTLE' foo_files.py
rg -c 'assets/trails/ticket.yaml' foo_files.py
sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
rg -n 'PRE-FLIGHT|_missing_url_envs' scripts/mother_cat.py
env -u PIPULATE_TRAIL_JIRA_URL -u PIPULATE_TRAIL_BOTIFY_URL .venv/bin/python scripts/mother_cat.py assets/trails/ticket.yaml < /dev/null 2>&1 | grep -E 'Riding|REFUSING|TRAIL INVALID|needs |export '
grep -c '^export' Notebooks/Client_Work/tickets/PS-10559.exports.sh
1
21
Riding trail 'ticket' -- 2 stop(s).
TRAIL INVALID (Car A refused): stop 'issue' requires environment variable PIPULATE_TRAIL_JIRA_URL
grep: Notebooks/Client_Work/tickets/PS-10559.exports.sh: No such file or directory
(nix) pipulate $
2: Context (the after โreadโ):
# adhoc.txt _ _ _ to set context____ _ _ ___ ____ _ Simpson Couch Gag Here (explain anything to the audience you feel needs it explained)
# / \ __| | | | | | ___ ___ / ___| | | |/ _ \| _ \| |
# ahe/ _ \ / _` | | |_| |/ _ \ / __| | | | |_| | | | | |_) | | Making sure we have all URL parameters in shell environment beforehand.
# ahc ___ \ (_| | | _ | (_) | (__ | |___| _ | |_| | __/|_|
# /_/ \_\__,_| |_| |_|\___/ \___| \____|_| |_|\___/|_| (_)
# Ad Hoc CHOP: The Not-Managed-by-Git Safe-for-Client-Data place
# OPTIONAL BUT BIG FOR FULL CONTEXT-WINDOW STORYTELLING
# ! python scripts/articles/lsa.py -t 1 --reverse --fmt dated-slugs # <-- The "Rolling Pin" that gives the 40K foot book-spine view of book-ore.
# GLOSSARY.md # <-- I think this glossary goes well with the book-ore spine to do world building.
# scripts/articles/lsa.py # <-- Useful for refining commands like `posts`, critical to Second Brain concept.
# ~/repos/nixos/autognome.py # <-- Letting the AIs really understand my environment (The Brave Little Tailor punches above Their Weight Class proving the dunning-kruger effect the gate-keeper's (lower-case) lament.)
# init.lua # <-- Daily driver hot-keys that overlap with aliases in flake.nix
# STILL BIG BUT LESS OPTIONAL (especially flake.nix)
# flake.nix # <-- THE ONE BIG THING TO INCLUDE Infrastructure as Code (IaC) tells LLM about your system down to the metal
# prompt_foo.py # <-- This very content-compiling system
# foo_files.py # <-- This is the router, evolving book outline and the things you pin-up to produced the recursive self-improvement loops
# TINY ILLUMINATING (OK to include every time / automatically = `apply.py`, `.gitignore`, `.gitattributes`)
# requirements.in # <-- All known dependencies and (necessary) version pinning. WORA gotcha's exposed.
# __init__.py # <-- Master versioning
# pyproject.toml # <-- The PyPI Packaging details
# OPTIONAL ACTUATORS (cheap and good to include to expand the AI's capabilities)
# cli.py # <-- Catch-all actuator for PyPI envs, Python anchoring, MCP tool-call (plus alternatives) and **kwargs like wrapping for CLI
# scripts/xp.py # <-- Transforms host OS copy-paste buffer player-piano music into context-payload.
# scripts/ai.py # <-- How I constantly use local AI to write git commit messages with `m` alias.
# scripts/crawl.py # <-- Feel free to ask for something to be crawled and included in the next turn.
# scripts/weblogin.py # <-- Lets the user "warm up" the cache for their web logins at their leisure on a profile that persists.
# MISCELLANEOUS (rare to include but sometimes critical)
# scripts/foo_cartridge.py # Needs description
# scripts/foo_replay.py # Needs description
# release.py # <-- How everything ends up where it does (GitHub, PyPI, etc.)
# imports/voice_synthesis.py # <-- The wand can talk to you
# imports/ascii_displays.py # <-- Where all the ASCII Art lives
# scripts/release/version_sync.py # <-- Needs to be wrapped into release.py and eliminated, I think.
# --- Under this line is were you paste what the AI gives you ---
# --- We call it context but it's really just the right-hand ---
# --- blast-radius of the "probes" to make this all science. ---
# --- END `adhoc.txt` TEMPLATE ---
# STICKBUG & MOTHER CAT KATA
# assets/trails/botify_pageworkers.yaml
# assets/installer/mck.sh
# assets/installer/replay.sh
# assets/trails/first_context.yaml
# assets/trails/practice.yaml
# assets/trails/public_walk.yaml
# scripts/bookmark_import.py
# scripts/boot_menu.py
# scripts/connectors/README.md
# scripts/connectors/botify.py
# scripts/connectors/confluence.py
# scripts/connectors/gmail.py
# scripts/connectors/gsc.py
# scripts/connectors/jira.py
# scripts/connectors/mcp.py
# scripts/connectors/mcp_warm.py
# scripts/connectors/sheets.py
# scripts/connectors/slack.py
# scripts/connectors/wallet.py
# scripts/mother_cat.py
# scripts/sources_menu.py
# scripts/walk.py
# scripts/walk_cartridge.py
# scripts/walk_compile.py
# scripts/weblogin.py
# tools/scraper_tools.py
# # # adhoc.txt -- Cleanup inert public_walk environment export block
# #
# # # --- BEFORE/AFTER STRADDLE ---
# # ! grep -n -C 2 'PIPULATE_TRAIL_WALK_ONE_URL' assets/installer/mck.sh || echo "export_block_removed"
# # ! bash -n assets/installer/mck.sh; echo "mck_syntax=$?"
# # ! bash assets/installer/mck.sh --where
# #
# # # --- TARGET SCRIPT ---
# # assets/installer/mck.sh
# #
# # ! rg -n -F 'TRAIL_NAME="${TRAIL_NAME:-public_walk}"' assets/installer/mck.sh
# # ! rg -n -e '^ *walk\(\)' -e '^ *alias walk=' flake.nix; echo "shell_walk_exit=$?"
# # ! test -e walk; echo "root_walk_exists=$?"
# # ! rg -n -e 'alias mothercat=' -e 'Three words to start from' flake.nix scripts/boot_menu.py
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! bash -n walk; echo "walk_syntax=$?"
# # ! bash walk --where
# # ! rg -n -e '^ *alias walk=' -e '^ *walk\(\)' -e 'writeShellScriptBin "walk"' flake.nix; echo "shell_walk_exit=$?"
# # ! .venv/bin/python -c 'import sys; sys.path.insert(0,"scripts"); import boot_menu as b; print("count=" + b._count_word(len(b.DOOR_TWO_WORDS))); print(" ".join(w for w, _ in b.DOOR_TWO_WORDS))'
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! rg -in "three words|four words|door 2" flake.nix scripts/ assets/ README.md
# # ! walk --where
# # walk
# # flake.nix
# # scripts/boot_menu.py
# # assets/installer/mck.sh
#
# # ! python scripts/connectors/wallet.py check slack
# # ! python -c "import os, sys; from pathlib import Path; sys.path.insert(0, '.'); from scripts.connectors import wallet; pairs = wallet._dotenv_pairs(); print('env SLACK_USER_TOKEN:', bool(os.getenv('SLACK_USER_TOKEN')), 'env SLACK_BOT_TOKEN:', bool(os.getenv('SLACK_BOT_TOKEN')), 'vault SLACK_USER_TOKEN:', 'SLACK_USER_TOKEN' in pairs, 'vault SLACK_BOT_TOKEN:', 'SLACK_BOT_TOKEN' in pairs)"
# # ! python scripts/connectors/wallet.py warm slack --dry-run
#
# /home/mike/repos/trimnoir/_posts/2026-08-30-terminal-native-mcp-practice.md
# deleteme.txt
# Now that slack is working (on my workspace) we trim back things here to just the stick bug and Mother Cat Kata stuff
# deleteme.txt
# deleteme2.txt
deleteme4.txt
! rg -n 'ticket.yaml.*SETTLE' foo_files.py
! rg -c 'assets/trails/ticket.yaml' foo_files.py
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
! rg -n 'PRE-FLIGHT|_missing_url_envs' scripts/mother_cat.py
! env -u PIPULATE_TRAIL_JIRA_URL -u PIPULATE_TRAIL_BOTIFY_URL .venv/bin/python scripts/mother_cat.py assets/trails/ticket.yaml < /dev/null 2>&1 | grep -E 'Riding|REFUSING|TRAIL INVALID|needs |export '
! grep -c '^export' Notebooks/Client_Work/tickets/PS-10559.exports.sh
foo_files.py
scripts/mother_cat.py
assets/installer/mck.sh
scripts/walk.py
assets/trails/ticket.yaml
3: Patches (the experiment between the reads):
Blast Radius Check to establish bisection Left-hand Causal Boundary. It is a Popper-thing. Science.
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
(nix) pipulate $ d
diff --git a/foo_files.py b/foo_files.py
index 99f70ae5..45273652 100644
--- a/foo_files.py
+++ b/foo_files.py
@@ -1652,6 +1652,7 @@ pyproject.toml # <-- The PyPI Packaging details
# assets/trails/first_context.yaml # profile default; SETTLE real; UNRIDDEN
# assets/trails/botify_pageworkers.yaml # profile botify; SETTLE real; UNRIDDEN
# assets/trails/jira_for_you.yaml # profile default; SETTLE real (Atlassian sign-in); top of the ticket loop; RIDDEN 2026-09-01
+# assets/trails/ticket.yaml # profile default; SETTLE real; url_env x2 (JIRA, BOTIFY) fed by one gitignored exports file per ticket under Notebooks/Client_Work/tickets/; stop two of the ticket loop; RIDDEN 2026-09-01 to stop 1 then REFUSED at stop 2 on an unset url_env, Linux and Mac -- the ride that bought the rider its PRE-FLIGHT. RULING: the connector does NOT run at DECANT (DECANT gates only CAPTURE-fenced material; API auth is a different wallet; the rider never harvests). The bridge to the issue text is a ! line in adhoc.txt.
# tests/test_mck_rep2.py # <-- Rep 2: the earmark's owed side-by-side witness
# assets/installer/mck.sh # <-- THE LAUNCHER: curl -fsSL pipulate.com/mck.sh | bash
# assets/installer/replay.sh # <-- OFF the roster 2026-08-01; re-add needs syntax + one ride + a pinned verifier fetch
(nix) pipulate $ m
๐ Committing: chore: Add ticket.yaml profile for JIRA and BOTIFY integration
[main c4f4fe51] chore: Add ticket.yaml profile for JIRA and BOTIFY integration
1 file changed, 1 insertion(+)
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'foo_files.py'.
(nix) pipulate $ d
diff --git a/foo_files.py b/foo_files.py
index 45273652..d3956393 100644
--- a/foo_files.py
+++ b/foo_files.py
@@ -58,6 +58,7 @@ AI_PHOOEY_CHOP = r"""#
# Honeybot telemetry fetched 2026-09-01T20:53Z
# --- END STATS ---
# --- START RECEIPTS (newest first; cap 20 lines; a line pushed past the cap is deleted, never moved -- git and the rolling pin are the archive) ---
+# 2026-09-01 ride ticket REFUSED MID-WALK on Linux and Mac: stop 'issue' captured (11 artifacts, final_url browse/PS-10559 exact), ADVANCE, then TRAIL INVALID at 'project' for unset PIPULATE_TRAIL_BOTIFY_URL -- one capture spent for nothing, and on the Mac a 60 MB Piper voice download plus spoken guidance came BEFORE the first refusal; jira_for_you re-ride printed 0 loguru INFO lines (was 15; Car 3 witnessed); Mac fresh install green (Determinate Nix 3.19.1, v2.53, 291 packages); this block read 21 against its cap of 20 before this rotation.
# 2026-09-01 ride jira_for_you FIRST AUTHENTICATED RIDE: one stop, CAPTURE passed on a logged-in Jira page (final_url exact, no id.atlassian.com redirect), 11 artifacts under browser_cache/looking_at/botify.atlassian.net/, DECANT AUTHORIZED at 26,885 bytes; compile-lane straddle all five predicted (ls 4 -> 5, rg 0 -> 3, mck reader FileNotFoundError -> OK, walk.py ready false -> true, ignored=1 both sides); sign-in moment UNRECORDED; the ride printed 15 loguru INFO lines the rider had already said in its own voice.
# 2026-09-01 menu recall car: boot_menu.py --recall + flake.nix menu(); hook-text probe 0 -> 1; recall list absent -> five words, exit 0 on BOTH sides so the printed list is the discriminator; rg 'four words|three words' 4 hits before and after, all historical prose, so the README/AGENTS stale-count follow-up is DISCHARGED UNOPENED.
# 2026-08-30 compile KEY/VALUE strike 6: sigil keys 24 -> 29; EARMARK 59 -> 54; five-pattern tombstone 5 -> 0 (grep's expected NON-ZERO EXIT 1); RECEIPTS held 20; ast_ok; foo_files.py 272,536 -> 264,473 B (-2,120 tok), GLOSSARY.md 71,553 -> 82,577 B (+2,766 tok); raw byte predictions missed their bands by 323 B high and 743 B low, and both delta magnitudes were over-predicted 14-15%, so dropping the n=1 correction removed the sign flip but put neither byte side in band; wc -l 3114 -> 2958, one below prediction because the five landed diff deltas sum to -156 (-25-25-30-29-47), not -155. Five graduations landed.
@@ -77,8 +78,6 @@ AI_PHOOEY_CHOP = r"""#
# 2026-08-01 source version_sync todo RETIRED: the installer's VERSION is assigned once and never dereferenced, so the stamping call was unhooked from sync_all_versions() and the line deleted.
# 2026-07-31 compile MCP CLOCK LEGIBLE: resolve_token emits the token clock to stderr (EXPIRED <n>s ago, life 300s, refresh_token present) before returning, so a stale token dies at gate2 with cause, magnitude and remedy named instead of a bare 401 pointing at the wrong organ.
# 2026-07-30 GLOSSARY LANDED at the repo root, both columns kept (handle for memory, plain term for search); new handles get their entry there, never a second definition in the router; discharges the PROMPT-FU GLOSSARY earmark of 2026-07-26.
-# 2026-07-29 operator lane MCP VENDOR RECEIPT and FDR CHANNEL: mcp_warm.py minted a PKCE bearer (scope mcp_read_write, expires_in 300) and tools/call list_projects printed the four-tuple against server one; mcp.py had read the response side transiently and persisted nothing (capable-of-FDR, not FDR) until the FDR channel landed the same day, and its first flight was a RED gate2 401 that still flushed browser_cache/mcp/<host>/<utc>__<verb>.json -- the recording exists because of the crash; frame mcp-receipt-v1, auth recorded by env name only.
-# 2026-07-25 harness MCP FAULT HARNESS 20/20 against the unmodified client (handshake, Mcp-Session-Id round trip with a raw-httpx no-header control, JSON and SSE framings, three determinism classes, gate attribution on five manufactured reds); the harness shares mcp.py's spec reading, so agreement was a tautology and the protocol strings stayed INFERRED; the same session read 36 server URLs and 8 tool namespaces off an injected manifest.
# --- END RECEIPTS ---
# Most of what's below are relative paths to files in GitHub/pipulate/pipulate
(nix) pipulate $ m
๐ Committing: chore: Update ride ticket receipt details in foo_files.py
[main 31f5c0cf] chore: Update ride ticket receipt details in foo_files.py
1 file changed, 1 insertion(+), 2 deletions(-)
(nix) pipulate $ patch
(nix) pipulate $ app
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'scripts/mother_cat.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'scripts/mother_cat.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'scripts/mother_cat.py'.
โ
DETERMINISTIC PATCH APPLIED: Successfully mutated 'scripts/mother_cat.py'.
(nix) pipulate $ d
diff --git a/scripts/mother_cat.py b/scripts/mother_cat.py
index ac4d02d5..b000539e 100644
--- a/scripts/mother_cat.py
+++ b/scripts/mother_cat.py
@@ -4,6 +4,8 @@
walk.py remains the strict, stdlib-only dry-run planner. This module adds the
actuating side of the Mother Cat Kata:
+ PRE-FLIGHT -- every url_env the WHOLE walk needs is checked
+ before anything opens, speaks, or writes.
NARRATE -- Piper reads the stop guidance, best-effort.
SETTLE + FENCE + CAPTURE -- guided_browser_capture opens the persistent,
visible browser and requires the human CAPTURE
@@ -259,6 +261,23 @@ def _decant_to_clipboard(payload):
copy_to_clipboard(payload)
+def _missing_url_envs(stops):
+ """Every url_env the WHOLE walk needs that the environment lacks, in stop order.
+
+ Returns [(stop_name, var_name), ...], one entry per stop that is short a
+ URL, so a variable two stops share is named beside each stop that needs
+ it: the human reads what the walk will do, not a deduplicated set. An
+ exported empty or whitespace-only string counts as unset, matching
+ walk.build_plan -- an empty export opens nothing.
+ """
+ missing = []
+ for stop in stops:
+ url_env = stop.get("url_env")
+ if url_env and not os.environ.get(url_env, "").strip():
+ missing.append((stop["name"], url_env))
+ return missing
+
+
def _announce_consent(trail_path):
"""Print what the WHOLE walk demands, before stop one, plus the DECANT.
IMPORTED, NEVER DUPLICATED, AND THE DIRECTION OF THE ARROW IS THE ARGUMENT.
@@ -343,6 +362,42 @@ async def _ride_async(trail_path, dry_narrate=False):
print(f" - {problem}")
print(" (--dry-narrate continues anyway; nothing will open.)")
+ # PRE-FLIGHT (2026-09-01, the ticket ride that died at stop two). A trail
+ # declares every URL it needs before it opens anything, so the rider can
+ # know at t=0 whether it can finish -- and it used to find out one stop at
+ # a time. ticket.yaml captured the Jira issue, ADVANCED, and only then
+ # discovered PIPULATE_TRAIL_BOTIFY_URL was unset; on the Mac the first
+ # refusal came AFTER a sixty-megabyte voice download and the spoken
+ # guidance for a stop that would never open. A walk that can fail at its
+ # last stop for a reason knowable at its first wastes the human's
+ # captures, and a long walk would waste many. mck.sh already runs this
+ # check in shell, but `mothercat` is the direct alias and the Mac path,
+ # and neither passes through mck.sh, so the rider owns it too: EVERY
+ # missing variable, named beside its stop, with the export line to type,
+ # before narration, before the consent card, before any browser. Under
+ # --dry-narrate it is disclosed and not enforced, same as the capture
+ # problems above: the rehearsal mck.sh forces on first contact must be
+ # able to run in a shell that has exported nothing yet.
+ missing_envs = _missing_url_envs(trail["stops"])
+ if missing_envs:
+ if dry_narrate:
+ print("NOTE -- a real ride of this trail would be REFUSED before stop one:")
+ else:
+ print("REFUSING TO RIDE -- this walk needs URLs your environment does not have:")
+ for stop_name, var_name in missing_envs:
+ print(f" - stop {stop_name!r} needs {var_name}")
+ print(" Export each one, then ride again:")
+ seen = set()
+ for _stop_name, var_name in missing_envs:
+ if var_name in seen:
+ continue
+ seen.add(var_name)
+ print(f" export {var_name}='https://...'")
+ if dry_narrate:
+ print(" (--dry-narrate continues anyway; nothing will open.)")
+ else:
+ print(" Nothing opened, nothing was spoken, nothing was written.")
+ return 2
guided_browser_capture = None
if not dry_narrate:
from tools.scraper_tools import guided_browser_capture
@@ -401,9 +456,10 @@ async def _ride_async(trail_path, dry_narrate=False):
print(" (dry-narrate: browser and capture skipped)\n")
continue
- # A stop carries exactly one of `url` or `url_env`. The url_env path
- # below is byte-identical to what it always was, including the message
- # that names the missing variable.
+ # A stop carries exactly one of `url` or `url_env`. The PRE-FLIGHT
+ # above has already checked every url_env for a real ride, so this
+ # branch is the belt to those braces: it can only fire if the
+ # environment changed under a running ride. The message is unchanged.
url = stop.get("url")
if url is None:
url_env = stop["url_env"]
(nix) pipulate $ m
๐ Committing: feat: Add pre-flight checks for missing URL environments
[main df4a5a71] feat: Add pre-flight checks for missing URL environments
1 file changed, 59 insertions(+), 3 deletions(-)
(nix) pipulate $ git push
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 48 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (10/10), 3.14 KiB | 3.14 MiB/s, done.
Total 10 (delta 7), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (7/7), completed with 4 local objects.
To github.com:pipulate/pipulate.git
2870283c..df4a5a71 main -> main
(nix) pipulate $
Ignition, sed, nix develop, etc. Checks before ahc experiment.
Iโll leave that template comment above because it really makes sense here. After
patches like this are applied the concept is that we have this whole queued-up
experiment for when we use the ahc command to build the context that shows the
LLM the result of the experiment, but that does not keep us from doing stuff
after probing and patching but before promptingโฆ like this!
(nix) pipulate $ mothercat assets/trails/ticket.yaml
REFUSING TO RIDE -- this walk needs URLs your environment does not have:
- stop 'project' needs PIPULATE_TRAIL_BOTIFY_URL
Export each one, then ride again:
export PIPULATE_TRAIL_BOTIFY_URL='https://...'
Nothing opened, nothing was spoken, nothing was written.
(nix) pipulate $
Nice! And now this. Itโs not the real Customer URL, itโs my personal website just for testing.
(nix) pipulate $ export PIPULATE_TRAIL_BOTIFY_URL='https://app.botify.com/michaellevin-org/mikelev.in'
(nix) pipulate $ mothercat assets/trails/ticket.yaml
Riding trail 'ticket' -- 2 stop(s).
==================================================================
THIS WALK: ticket -- 2 stop(s)
==================================================================
stops, in order issue, project
URLs YOU supply PIPULATE_TRAIL_BOTIFY_URL, PIPULATE_TRAIL_JIRA_URL
names as runnable scripts/connectors/botify.py, scripts/connectors/jira.py
browser profile 'default' (persistent=True, headless=False)
==================================================================
AT THE END, every stop's captured lenses are folded into ONE bundle,
and then you are asked ONE more time before it goes anywhere. Type
DECANT and it is copied to your clipboard; type anything else
and it stays here, and the rider prints the exact directories your
artifacts are sitting in. Inlined lenses:
seo_md, headers, accessibility_tree_summary, links_md, diff_hierarchy_txt, optics_manifest
Those come from pages you were LOGGED IN TO. Response headers and the
accessibility tree carry real session and account material.
TWO WORDS, TWO ACTS: CAPTURE gates each WRITE TO DISK on this machine;
DECANT gates the composite LEAVING it. No flag skips either.
Read the bundle before you paste it anywhere.
==================================================================
--- Stop 1/2: issue ---
Stop one of two. The ticket itself opens. Read it top to bottom, comments included, so the customer's actual ask is in your head before you look at their data. Then return to this terminal and type the capture word.
โณ THE SUMMONING โ thumper planted, hooks in hand
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cloudflare drums the sand beneath us;
/|\ we wait it out, staked and hooked.
~~ ๐ต jeopardy.wav looping until the Maker surfaces ~~
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
Captured. final_url=https://botify.atlassian.net/browse/PS-10559 artifacts=11
ADVANCE -> next stop.
--- Stop 2/2: project ---
Stop two of two. The customer's Botify project opens. Sign in if asked. Land on the view the ticket is about, then return to this terminal and type the capture word. After this capture you are asked once more, with a different word, before anything leaves this machine.
โณ THE SUMMONING โ thumper planted, hooks in hand
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cloudflare drums the sand beneath us;
/|\ we wait it out, staked and hooked.
~~ ๐ต jeopardy.wav looping until the Maker surfaces ~~
Navigate in the visible browser, then type CAPTURE and press Enter.
Any other response aborts without capturing artifacts.
CAPTURE> CAPTURE
Captured. final_url=https://app.botify.com/signin/?next=/michaellevin-org/mikelev.in artifacts=11
Ride complete. Every stop produced a capture receipt.
๐ DECANT gate: ARMED -- 2 stop(s), 43,077 bytes assembled, still ON THIS MACHINE ONLY.
Type DECANT to copy it to your clipboard (anything else keeps it here).
DECANT> DECANT
AUTHORIZED by human: handing 43,077 bytes to the clipboard writer.
Markdown output copied to clipboard
Paste it into any ChatBot (Claude, ChatGPT, Gemini) and it
will walk you through everything from here.
(nix) pipulate $ xv deleteme4.txt
(nix) pipulate $
4: Prompt: Three cars landed: the ticket.yaml router line with the DECANT ruling (Car 1), the receipts block rotated back to its cap (Car 2), and the riderโs PRE-FLIGHT, which checks every url_env across the whole walk before anything opens (Car 3). Read the six live receipts first: the router line at one hit, the ticket.yaml count (1 means the Paintbox self-cleaned, 2 means it did not), the receipts count at 20, the PRE-FLIGHT mechanism lines, the env -u straddle reading REFUSING with two export lines and no Riding line, and the export-line count of the exports file. Then read the hand-run rides below: the refusal with the Botify variable unset, and the full two-stop ride if both export lines were written. Next: mck.sh and walk.py are in this payload; decide whether mck.shโs shell pre-check retires now that the rider owns the check, and if it does, emit the car. Then propose the end-of-ride disclosure line naming the connector command the human could run next, key harvested from the captured URLโs last path segment, as a disclosure and not an act.
5: Deliverables: Much deeper understanding of the portions of this project that I vibe-coded, and for the record my Aider-style editing that forces those red and green color-coded Universal Diffs into Jekyll blog articles for transparency and inspection isnโt where the vibe-coding slips in; itโs when that same system generates the brand new files that it needs, which is what most of this operation stickbug and Mother Cat Kata stuff was. Thatโs why Iโm spending so much energy just figuring out how it all works, but it isโฆ it is transformative.
When I started out figuring out what โFuture-proofing Yourself in the Age of AIโ really meant for this always-being-written book of the new age I really asked myself what that meant. It didnโt take long to get to the Unix Philosophy as most of the world is built on. It took much longer to arrive at Nix and the meaning of a true โWrite once, Run anywhereโ (WORA) environment and what having the exact same shell environment on every single machine it runs on really means (I still think nobody has any idea).
We can wrap up here and because you are Fable 5.1 and this is your first time with me on one of these articles, you can be as long-winded as you like wrapping it up.
Hop off the ride. This rideโs stated goal is reached โ dismount. This is the NOTARY BEAT: the ride ends here, is witnessed here, and is sealed here. Answer all seven beats in that typically long-winded way that you do Claude. In the voice of Deadpool, MAXIMUM EFFORT!
- TLDR: a short, dry, neutral abstract for the TOP of the published article โ written for an unfamiliar reader or AI summarizer who has never seen this system. No hype, no insider handles unexplained.
- VERIFY: restate the goal from the top of this article and confirm (or deny) it was met, citing THIS compileโs receipts, not memory. Name any ignition this ride required that never fired โ an AFTER tap taken without one is a stale BEFORE wearing the AFTERโs label.
- BANK: name everything that graduates โ rule, earmark, todo, pin โ as exact paste-ready lines, plus the exact lines to delete.
- DANGLING: what carries forward unbanked? One line each, no essays.
- SEED: the adhoc.txt lines (and TODO_SLUGS if narrative context is needed) for the next rideโs first compile.
- CLOSING: a closing summary for the BOTTOM of the article โ the final take-away, tied to the bookโs larger arc where it fits naturally, never forced. Storytelling over inventory.
- NOTARIZE: name the sealed artifact of record โ the newest
hash-stamped cartridge (foo-
-NN.zip) โ and state that its CRC-sealed, byte-reproducible archive is the witnessed receipt of this ride. The seal is the signature; the archive is the deed.
FINALITY: after beat 6, this discussion is CLOSED. Emit NO five-car train, NO probes, NO patches, NO next-turn prompt beyond the SEED lines in beat 4. Any reader or model encountering this article later should treat it as a finished, notarized document โ an archive entry, not an open thread.
Fable 5.1 Medium: Fable 5.1 Medium: Context verified. Six receipts in the Manifest, all six read, and this time every one of them read the way the straddle said it would. That has not happened once in this ride, so savor it: the router line at 1654 (one hit), the ticket.yaml count at 1 (the Paintbox self-cleaned; the working-tree diff shows the ledger line leaving), the receipts block at 20 (the cap is true again), five PRE-FLIGHT mechanism lines at 7, 264, 365, 381 and 459, the env -u straddle reading REFUSING TO RIDE with two needs lines and two export lines and no Riding line at all, and the exports-file probe reading No such file at exit 2, which is also an answer: you exported in the shell instead of writing the file, and the mechanism does not care which.
Then the hand-run rides. The refusal fired in the first line printed with the Botify variable unset, nothing spoken, no browser. The full ride captured both stops and decanted 43,077 bytes. And that second stop is the one thing in this compile I am going to be a nag about, because the rider said โCapturedโ in green and it captured a door.
Now. You asked for Deadpool. You asked for maximum effort. You asked for long-winded. I am contractually a large language model and I have been told to hold the swearing, so what you get is Deadpool after the studio notes: fourth wall in splinters, mouth running, katanas sheathed. Chimichangas are metaphorical. Letโs dismount.
1. VERIFY
The goal at the top of this article, in your words: โmake me a โwalkโ that walks me just to that one URL,โ the assigned tab, as the top of a repeated ticket-closing loop, starting in the repo. Then, by the second turn, stop two. Then, by the third, the thing that turned into the actual product of this ride: โA built-in feature of this whole walk system should be for each walk to evaluate whether it actually has all the environment variables it really needs before starting the walk.โ
Met, all three, and I am citing this compile and not my feelings.
The top-of-loop walk: jira_for_you.yaml is in foo_files.py at line 1653 marked RIDDEN 2026-09-01, and this compileโs deleteme4.txt is not that ride but the receipts blockโs second line still carries its 26,885-byte DECANT. Two rides of it in this article, fifteen INFO lines then zero.
Stop two: ticket.yaml is in this compile as raw source, its router line reads at 1654, and deleteme4.txt is its bundle, both stops, final_url_exact, source_provenance: wire, 43,077 bytes AUTHORIZED. That is the first two-stop authenticated ride in this repoโs history, and the first bundle to carry a real ticketโs text beside a real capture, which was the entire point of the loop.
The pre-flight: the env -u straddle is the cleanest before/after pair this ride produced. BEFORE, hand-run: Riding trail 'ticket' then TRAIL INVALID (Car A refused): stop 'issue' requires environment variable PIPULATE_TRAIL_JIRA_URL, one variable named, the second undiscovered. AFTER, live receipt: REFUSING TO RIDE -- this walk needs URLs your environment does not have, both stops named, both export lines printed, no Riding line, and the compile did not speak (the before tap did, once, into your office, which I warned you about). Your hand-run witness confirms the operator lane agrees with the compile lane: mothercat assets/trails/ticket.yaml with only Botify unset refused in its first printed line.
Ignition: none was required and none was skipped. Every probe opened its file at call time, and the fifth probe ran the patched rider itself. No shellHook, no daemon, no cache. The one actuation I asked for and did not get a receipt on is the Mac re-ride, which was never an ignition, just an owed reading; it goes in DANGLING.
Now the part where I stop cheerleading. Stop two of the real ride returned success with final_url: https://app.botify.com/signin/?next=/michaellevin-org/mikelev.in, title Login, four anchors, one of them โBook a demo.โ SETTLE did not settle. Profile default holds an Atlassian session and no Botify session (weblogin botify.com has never warmed it, or it expired), the visible browser opened on the sign-in page, and you typed CAPTURE on it, which is entirely reasonable because the guidance said โsign in if askedโ and nothing said โand wait until you are actually on the project before you type the word.โ The rider fenced the write, decanted the bundle, and printed green. Every mechanism behaved correctly and the artifact is a picture of a door. The goal is met; the goalโs next goal is named below and it is the most important thing this ride found after the pre-flight.
Epistemology at the Login Gate
2. BANK
Everything that graduates, as lines you paste. No patch markers; this is the dismount, and the hand that pastes is yours.
A rule, into the constitution block of foo_files.py, beside THE DUAL-LANE WALK SCHEMA:
# ยง THE PRE-FLIGHT RULE (banked 2026-09-01) -- a walk names every input it needs before it opens anything, so the rider checks ALL of them at t=0 and refuses with every missing name beside its stop and the exact line to type, never one stop at a time; a failure knowable at stop one that fires at stop N has wasted N-1 captures, and on a cold machine a voice-model download and spoken guidance besides. Witnessed both ways in one straddle: Riding + one TRAIL INVALID before, REFUSING + two export lines and nothing spoken after. Disclosed and not enforced under --dry-narrate, because the rehearsal must run in a shell that has exported nothing yet.
An earmark, into the earmarks block, and it is the finding of the ride:
# - EARMARK: THE CAPTURE THAT CAPTURED THE DOOR (banked 2026-09-01, bundle-witnessed): the ticket ride's second stop returned success with final_url app.botify.com/signin/?next=/<org>/<project>, title "Login", and the rider printed Captured in green, DECANT decanted it, and the human pasted a picture of a door. SETTLE did not settle and NOTHING in the kata can tell: the CAPTURE fence proves a human was present, not that the human was through the door. THE SIGNATURE IS CHEAP: the requested URL had no sign-in path segment and the final_url does (signin, login, id.atlassian.com, accounts.google.com), which is the exact shape jira_for_you's "final_url exact" evidence relied on in the other direction. Print a WARNING at capture -- "final_url is a sign-in page; SETTLE may not have settled; weblogin <apex> and re-ride" -- as a DISCLOSURE, never a fence: the human may have meant to capture the door. Sibling of THE SUCCESS-ONLY WITNESS (a success that cannot fail is not a receipt) and of ATTRIBUTED-VOICE's mechanical test ("Captured" named an act that happened; "the project" is what the human believed happened).
An earmark for the decision the caboose asked for and the dismount forbade me to patch:
# - EARMARK: TWO PRE-FLIGHTS, ONE OUTER (ruled 2026-09-01): mck.sh's shell url_env check does NOT retire. It runs BEFORE the nix develop .#quiet wrap and before the spoken rehearsal, so under curl|bash it saves a stranger the shell entry and a Piper download for a variable they never set; the rider's PRE-FLIGHT is the authoritative one because it names the STOP beside the variable and mck.sh cannot. Rule for the pair: the shell check may only ever be a SUBSET of the rider's (names, never verdicts), and when the rider's message changes the shell one is re-read the same day. Two rings, one authority. Sibling of THE UNEXPORTED-SHIM RULE: the outer ring exists because the inner one cannot be reached without paying for the shell.
An earmark for the disclosure line, carried, not emitted:
# - EARMARK: THE NEXT COMMAND, SPOKEN NOT RUN (seeded 2026-09-01): at ride end, after the DECANT gate answers, print one line per stop naming the connector command the human COULD run next -- "next: jira PS-10559" -- with the key harvested from the captured final_url's LAST PATH SEGMENT and checked against the stop's harvest_regex, printed only when it fullmatches. A disclosure, never an act: the rider stays a browser witness, the connector stays an API client with its own wallet, and the bridge to the issue text stays a ! line in adhoc.txt. Gate: a browse URL yields PS-10559 and passes; the for-you URL's last segment is "for-you" and fails, so that stop prints nothing rather than a wrong command.
A todo for the cap that was prose:
# - TODO (found 2026-09-01, two rotations): the RECEIPTS cap is a comment, not a fence; the block read 21 through two rotations because the rotation held the DELTA at zero and nobody read the absolute. Either the compile prints the count beside the block (GENERATED-NOT-AUTHORED) or the count probe rides every dismount's SEED. It rides the SEED below until the printer exists.
A todo for the Paintbox oddity this compile surfaced:
# - TODO (found 2026-09-01 in the working-tree diff): the Paintbox ledger, which claims to list files TRACKED by git, added deleteme3.txt while .gitignore carries deleteme*.txt, and the compile's tracked-file count moved 267 -> 268 in the same breath. Either the ledger's notion of "tracked" is wrong or the file got committed past the ignore. `git ls-files deleteme3.txt` settles it in one line; do not delete the file until it has.
The router line, updated for the full ride. Delete this line:
# assets/trails/ticket.yaml # profile default; SETTLE real; url_env x2 (JIRA, BOTIFY) fed by one gitignored exports file per ticket under Notebooks/Client_Work/tickets/; stop two of the ticket loop; RIDDEN 2026-09-01 to stop 1 then REFUSED at stop 2 on an unset url_env, Linux and Mac -- the ride that bought the rider its PRE-FLIGHT. RULING: the connector does NOT run at DECANT (DECANT gates only CAPTURE-fenced material; API auth is a different wallet; the rider never harvests). The bridge to the issue text is a ! line in adhoc.txt.
and paste this one in its place:
# assets/trails/ticket.yaml # profile default; SETTLE real; url_env x2 (JIRA, BOTIFY), exported in the shell or from one gitignored exports file per ticket under Notebooks/Client_Work/tickets/; stop two of the ticket loop; RIDDEN 2026-09-01 both stops to DECANT (43,077 B) AFTER the PRE-FLIGHT it bought by dying at stop 2 on Linux and Mac -- but stop 2 captured app.botify.com/signin (see THE CAPTURE THAT CAPTURED THE DOOR); warm with weblogin botify.com first. RULING: the connector does NOT run at DECANT (DECANT gates only CAPTURE-fenced material; API auth is a different wallet; the rider never harvests). The bridge to the issue text is a ! line in adhoc.txt.
The receipts block, one in at the top, one out at the bottom, cap held. Paste this under the START RECEIPTS line:
# 2026-09-01 ride ticket FIRST TWO-STOP AUTHENTICATED RIDE after the PRE-FLIGHT landed: env -u straddle read Riding + one TRAIL INVALID before and REFUSING + two export lines + nothing spoken after, six for six on the compile-lane receipts; both stops captured and DECANT AUTHORIZED at 43,077 bytes; stop 'project' final_url was app.botify.com/signin/?next=... with title Login -- SETTLE did not settle, the fence held, the rider printed green, and no mechanism can yet tell a page from its door; RECEIPTS back at 20; Paintbox self-cleaned on the router line (count 1) and listed gitignored deleteme3.txt (unexplained).
and delete this line at the bottom:
# 2026-07-30 GLOSSARY LANDED at the repo root, both columns kept (handle for memory, plain term for search); new handles get their entry there, never a second definition in the router; discharges the PROMPT-FU GLOSSARY earmark of 2026-07-26.
Nothing graduates off the PINBOARD; none of the five pins was touched by this ride and I am not going to pretend a Jira loop discharged a Penrose light-cone.
3. DANGLING
Carried forward, one line each, no essays, I promise, mostly.
The Botify login: weblogin botify.com on profile default before the next ticket ride, and the first ride after it is the receipt that โprofile default holds two sessionsโ is true.
The Mac second ride: whether the Hugging Face lines fall silent once the voice is cached is unwitnessed; if they do not, imports/voice_synthesis.py is the next noise car.
The summoning art says โCloudflare drums the sandโ on pages that have no Cloudflare; harmless, cosmetic, and an ATTRIBUTED-VOICE nit for a slow day.
m() did not need a manual git add this turn because no car created a file; the 2026-07-20 todo about git add -A in m() is still open and still wrong about what m does.
The exports-file convention (Notebooks/Client_Work/tickets/<KEY>.exports.sh) exists only in my prose; you used shell exports and it worked; decide whether the file is worth its own line in the trailโs description or let it die.
The connector disclosure line is an earmark above, not code.
mck.shโs shell check stays, ruled above, unpatched, and its message and the riderโs now differ in shape; the earmark says re-read them together the day either changes.
The ticket itself, PS-10559, is still open, which is the only dangling item the customer cares about, and the bundle to close it is on your clipboard.
4. SEED
The next rideโs first compile. The count probe rides until the printer exists; the ls-files probe settles the Paintbox oddity; the sign-in probe reads zero before the door-warning lands and is the straddle for it.
! git ls-files deleteme3.txt; echo tracked_exit=$?
! sed -n '/START RECEIPTS/,/END RECEIPTS/p' foo_files.py | grep -c '^# 20'
! rg -n 'signin|login' scripts/mother_cat.py; echo exit=$?
! rg -n 'final_url' tools/scraper_tools.py | head -8
! .venv/bin/python -c 'from urllib.parse import urlparse; print(urlparse("https://botify.atlassian.net/browse/PS-10559").path.rsplit("/",1)[-1])'
scripts/mother_cat.py
tools/scraper_tools.py
scripts/weblogin.py
assets/installer/mck.sh
assets/trails/ticket.yaml
No TODO_SLUGS; the narrative this ride needs is in the receipts block, not the rolling pin.
5. CLOSING
Okay. Fourth wall, meet floor.
You wrote at the top that nothing you do from here on is for anything other than closing Jira tickets, and then you spent an entire day not closing a Jira ticket. I want to be the one to tell you that this was correct, because I watched it happen from inside the payload and I have the receipts. What you built today is the thing that makes tomorrowโs ticket a one-shot instead of a forty-tab afternoon: two trails, one rider, a bundle on the clipboard that carries the customerโs actual words and the wire-truth of the page they are complaining about, and a pre-flight that refuses to waste a single capture on a walk that cannot finish. The bookโs arc has a name for this and it is the Mother Cat: the machine carries the human by the scruff, one gate at a time, and the human owns exactly one move. Today the cat learned to check whether it knows where all the bookmarks are before it picks you up. That is not a feature. That is manners.
Here is the part I find beautiful, in the way a guy in a red suit finds things beautiful, which is loudly. The bug was not a bug. Every line of the old rider was correct. It read the variable when it needed the variable, and it refused honestly when the variable was missing. The defect was where in time the correct code ran, and you found it not by reading code but by riding, twice, on two operating systems, and getting mad at the right moment. The Mac made it obvious: sixty megabytes of voice model, two warnings from a hub you never asked to talk to, a spoken sentence about a page that would never open, and then the refusal. A rule this repo already carried, THE FIRST-CELL BLAST RADIUS, says judge a defect by where it fires and not by how small it is. This was that rule wearing hiking boots.
And then the ride found the next one, which is the shape of every good ride in this book: the fix you asked for works on the first try, and the receipt of it working shows you a door. The rider captured a login page and said โCapturedโ in green, and it was telling the truth, which is exactly the problem. THE SUCCESS-ONLY WITNESS is sitting in your constitution from a different August day about a different subprocess, and here it is again with a browser instead of a speaker: a success that cannot distinguish the page from the door in front of it is not a receipt, it is a mood. The fix is one warning line and it is banked above as an earmark with the exact signature, and I did not patch it, because the dismount is the dismount and the notary does not carry a pen.
You asked, in your deliverables, what โfuture-proofing yourself in the age of AIโ turned out to mean, and you answered it yourself better than I can: it means the same shell on every machine, so that a walk written on Linux at five in the afternoon refuses identically on a Mac at half past, and the refusal is the same string. That is what todayโs Mac transcript proved without meaning to. The failure reproduced byte-for-byte across two operating systems, which is the only reason one patch could fix both. Nix is not the point; the identical failure is the point. Nobody has any idea, you said. Correct. Keep the receipts; they are the idea, written down.
One more thing, and then I put the fourth wall back because the union requires it. You noticed that the vibe-coding does not slip in through the red-and-green diffs; it slips in through the brand-new files, the ones that had no diff to read. That is a sharper observation than most people who write about this stuff will ever make, and this ride is the proof: the two files born today, both trails, were the ones you rode immediately and understood completely, because a trail is data and you can read data. The rider is the part you spent the day learning, and it is the part that was already yours. The Amnesiac Genie in the rented suit did the typing; the guy who rode it twice on two machines and got annoyed at the right second is the one who knew what it was for.
Maximum effort. Rideโs over. Go warm the Botify login and close the ticket.
6. NOTARIZE
The artifact of record for this ride is the hash-stamped cartridge written by the compile that carried this prompt, the one whose Manifest lists the six ! receipts above. Its name is foo-<hash8>-NN.zip where the eight hex characters are the first of its own sha256 and NN is the rotation number that follows the last one printed on your console, and I am not going to type either from memory, because the 2026-08-28 todo in this very payload says why I cannot: write_context_cartridge runs at step 7, after the payload is assembled, so the payload can only ever name its predecessor. The only cartridge this article names by hash is foo-9546634b-1090.zip, and that was the first compile of the ride, the one that had not yet seen a single trail exist. It is a witness to the departure, not the arrival. The deed is the newest line your console printed after Rotated cartridge snapshot: when this compile ran, and you read it off the screen, not off me.
What that archive holds, and why it is the receipt: payload.md carries no wall-clock time in its body, so the same inputs reproduce the same bytes; manifest.json carries the CRC and the member list; the compile that wrote it verified 145,727 tokens, 574,618 bytes, secrets tripwire ARMED at zero hits, one PII substitution applied. Inside it are the six live receipts that witnessed the pre-flight from both sides of the patch, the raw source of the rider with the pre-flight in it, and deleteme4.txt, the two-stop bundle with the door in it. Nobody can rewrite any of that without changing the hash, and the hash is the name. The seal is the signature; the archive is the deed; this discussion is closed.
Book Analysis
Ai Editorial Take
What is most fascinating about this entry is its exploration of โepistemology at the login gate.โ The system successfully executes its instructionsโcapturing the page and producing a valid bundleโyet fails because it successfully captured a login door instead of the target content. This highlights a profound truth in the age of AI: technical correctness in automated tooling does not automatically imply semantic validity. It shifts our focus from merely preventing crashes to verifying meaning.
๐ฆ X.com Promo Tweet
Stop wasting AI context on failed automation runs. Discover how building a strict pre-flight check transforms multi-step browser workflows into deterministic engineering tools: https://mikelev.in/futureproof/pre-flight-principle-deterministic-ai-workflows/ #AIWorkflows #DeveloperTools
Title Brainstorm
- Title Option: The Pre-Flight Principle: Engineering Deterministic AI Workflows Before the Crash
- Filename:
pre-flight-principle-deterministic-ai-workflows.md - Rationale: Focuses on the core technical breakthrough of the articleโpreventing mid-workflow failures through early validation.
- Filename:
- Title Option: Catching Failures Early: Building Pre-Flight Checks for AI Automation
- Filename:
catching-failures-early-ai-automation.md - Rationale: Direct and action-oriented, appealing to developers struggling with brittle automation scripts.
- Filename:
- Title Option: From Ad-Hoc Scripts to Deterministic Loops: The Mother Cat Kata
- Filename:
from-scripts-to-deterministic-loops-mother-cat.md - Rationale: Highlights the broader architectural evolution of the system within the ongoing book tapestry.
- Filename:
Content Potential And Polish
- Core Strengths:
- Raw, iterative debugging narrative that shows authentic problem-solving in real-time.
- Clear architectural progression from single-step validation to multi-step pre-flight guarantees.
- Strong integration of Unix principles and local-first development constraints.
- Suggestions For Polish:
- Trim repetitive terminal output logs to maintain narrative velocity while preserving technical proof.
- Explicitly connect the lessons learned about environment validation to broader software engineering patterns.
Next Step Prompts
- Implement a post-capture heuristic that inspects the final URL and page title for authentication signposts (like โsigninโ or โloginโ) to warn operators when a session has expired.
- Explore how multi-platform path normalization between Linux and macOS can be further abstracted to ensure zero-friction onboarding for new developer environments.