kova-ops
the automation layer
What the 73 tests actually check
Two suites, run together, built against real throwaway repositories — one dirty, one clean — rather than mocks, because half of what these hooks decide depends on whether there is anything to lose.
- 20theme-push-guard · must ask. Anything that reaches production: a push to
mainin seven spellings, a merge onmain,shopify theme push, andgh pr mergein four forms — including when a compound commandcds into the theme first. - 14theme-push-guard · must pass silently. Ordinary work: branch pushes,
git status,git commit,shopify theme dev, a push in the docs repo, andgrep -rn 'push'. A guard that cries wolf gets routed around. - 5theme-push-guard · permission mode.
askin every mode a human can answer;denyunderbypassPermissions, where a prompt reaches nobody and the run would hang on a question no one sees. - 7git-destructive-guard · history. Always ask, even on a clean repo:
reset --hard <ref>,branch -D,stash drop,stash clear, force push. - 8git-destructive-guard · working tree. Ask only when something is at risk. The same command is a question on a dirty repo and silence on a clean one, which is why the suite needs real repos.
- 10git-destructive-guard · ordinary work. Must pass silently — including
git clean -n, a dry run, andgit branch -d, the safe delete. - 4git-destructive-guard · the
cdblind spot. The hook payload'scwdis where the shell was BEFORE the command runs, socd <other repo> && git clean -fdwas judged against the wrong repo and waved through. Found by probing, not by reading. - 5git-destructive-guard · permission mode. The same ask/deny split.
- Shopifyorders
- Squarepayments
- Xerobooks
- Notioncanon
- Gmailcomms
- Cloudflaredeploy
Two hooks stand between the agent and anything it can break: a deploy reaching the live storefront, and a destructive git command.
What it taught me: I found three production bugs in these hooks by probing them with crafted payloads. Reading the code said they were fine. A guard you have not attacked is a guard you are guessing about.
What one sitting actually does
The mechanical tier only, and Juan sits with it. Everything below is a rule; the moment a judgement is required the gate hands it back.
- 1Read. Square card takings, Shopify payouts, and six Xero bank accounts.
- 2Match on rules and dates. Internal transfers, Shopify invoice matches, rule-driven deposits.
- 3Stop at expense coding. Business-versus-personal is a tax position rather than a rule, so a human answers it. This is the boundary, not a gap.
- 4Result. 95 unreconciled items to zero, all six accounts green, receivables $656.65 to $0.00.
- Squarecard takings
- Shopifypayouts
- Xero6 accounts
One sitting: 95 unreconciled items to zero, all six bank accounts green, receivables $656.65 → $0.00. Expense coding is deliberately NOT automated — business-vs-personal is a tax position, so the gate stops there and a human answers it.
What it taught me: where to stop. Expense coding is deliberately NOT automated — business-vs-personal is a tax position, not a rule — so the gate hands it back to a human. Knowing what to leave alone is part of the design.
How a delivery run gets built
Live orders in, one map link out. Two of these four steps exist only because a plausible shortcut was measured and failed.
- 1Pull. Live unfulfilled Shopify orders, addresses as written.
- 2Find the departure time by binary search. The latest you can leave and still make every stop inside the hard 9pm cap.
- 3Check the freezer against capacity before anything is loaded, and make the defer-or-deliver call on a late order.
- 4Emit one Google Maps link with every stop in order. A ZIP-centroid fallback was tested for the geocoding and rejected: four miles off.
- Mapsone-tap run
- freezer checkcapacity
- defer calllate orders
Orders in, an ordered run and a single map link out. The departure time is found by binary search — the latest you can leave and still make every stop. A ZIP-centroid fallback was tested and rejected: four miles off.
What it taught me: a fallback that looks reasonable can be four miles wrong. The ZIP-centroid shortcut only failed once it was measured against real addresses, which is the only way it was ever going to surface.
The three stages
A library of 46 raw shoots and 46 finals, each with a textless master, so a cut can be re-subtitled or re-hooked without going back to the footage.
- 1Transcribe. The spoken take becomes an SRT with timings.
- 2Derive the cut list. Offsets differ from month to month, so the timing is measured per shoot rather than assumed — that assumption is what used to put every cut a beat late.
- 3Assemble. One keystroke, and the result is a rough cut plus a textless master.
- textless masters46 finals
- Notioncalendar
A three-stage pipeline: transcribe, build the cut list from the transcript, assemble. It runs against a library of 46 finished pieces with clean textless masters, which is what makes re-cutting old footage cheaper than shooting new.
What it taught me: re-cutting the library is cheaper than shooting new — but only because the masters were kept textless months earlier. Most of what makes a pipeline cheap is a decision made long before it runs.