Your Automation Dies Quietly: A Weekly Revenue Gate That Caught One Line Dropping From 14 Files to 0 A developer running 14 content-production lines generating ยฅ1.2M/month in revenue built an automated weekly report script, revenue-gate.sh, to flag underperforming lines. The script, which runs every Monday via launchd, detected that the ASMR line dropped from 14 files to 0 in three days, a change the developer would have missed without automation. The system is designed to surface facts for human judgment, not to auto-stop jobs. A layoff notice doesn't stop the Claude API invoice โ€” that still lands next month, right on schedule. I run 14 content-production lines at the same time and hold ยฅ1.2M/month in revenue, and the reason isn't that I track how much I earned . It's that I built something first that shows me, automatically every Monday, which line has gone into the red . In the first report 2026-07-03 my ASMR line was producing 14 files a week and showing ๐ŸŸข. Three days later, on 2026-07-06, it was at 0 files and flagged โš ๏ธ. Without the report I would have kept believing that line was running. When you run several production lines at once, something strange happens: the busier you get, the less you look at the numbers. The affiliate-article line puts out 28 pieces a week. The LINE-stamp line, 19 sets a week. iOS app ideas, 8 a week. The social-posting line spits out more than 120 files a week. Once you're managing that volume by hand, almost nobody can answer "how much did this line earn last month?" on the spot. And not being able to answer is the same thing as unconsciously feeding a money-losing line. Claude API costs look small. A single prompt run is a few yen. But once 14 lines are generating hundreds of files a week between them, the monthly API bill adds up. At that point, if you can't immediately say which line isn't earning , you can't make a cost-cutting decision. The typical response here is "start a spreadsheet." I didn't do that. Opening a spreadsheet weekly and filling it in has never once survived as a habit for me. Anything that doesn't stick is relying on willpower rather than environment . Willpower is finite. That's the problem revenue-gate.sh solves. Every Monday at 8:20, the Mac generates a report automatically and drops it on the Desktop. You just open it. There's nothing to write. The human only makes the judgment call. This is what building an environment rather than a task means. If the trigger for a decision arrives from outside automatically, you can decide without spending willpower. Once you've built the reflex report arrives = something changed , the weekly revenue check stops being "something to do" and becomes "something that happens." The other design principle is a division of labor: the human decides what to kill, but the machine finds the lines that should be killed. The script never stops anything by itself. Read the code and you'll find this: KILLๆŽจๅฅจใฎใ‚ธใƒงใƒ–ใฏใ€Œไฝ•ใฎใŸใ‚/่ชฐใŒๅฌ‰ใ—ใ„/ใ„ใใ‚‰ๅ„ฒใ‹ใ‚‹/ใ„ใค่ฆ‹ๅˆ‡ใ‚‹ใ€ใซ ็ญ”ใˆใ‚‰ใ‚Œใชใ‘ใ‚Œใฐๅœๆญขใ™ใ‚‹๏ผˆ่‡ชๅ‹•ๅœๆญขใฏใ—ใชใ„ใ€‚ๅˆคๆ–ญใฏไบบ้–“๏ผ‰ Roughly: a job flagged for KILL gets stopped if you can't answer "what is it for / who is happy / how much does it earn / when do you cut it." No automatic stopping โ€” the human decides. The no-auto-stop design matters. If a machine kills a line on its own, you can't verify why it stopped, and a false positive could kill your top earner. The machine's job is to put a fact in front of you: "this line has produced plenty of files for two straight weeks with zero revenue." Everything past that is a human judgment. In the actual first report on 2026-07-03, the ASMR line was producing 14 files a week and was ๐ŸŸข green . In the following report on 2026-07-06, it was at 0 files a week and had turned โš ๏ธ output stopped? . That change didn't happen because I deliberately stopped it โ€” it meant the job had stopped for some reason. Without the report I would never have noticed, and I'd have spent my time on some other optimization while assuming "the ASMR line is running." Here's the whole picture first. โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๆฏŽ้€ฑๆœˆๆ›œ 8:20 / 13:20 launchd ไบŒ้‡็™บ็ซ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ revenue-gate.sh โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ–ผ โ–ผ โ–ผ revenue.jsonl revenue-gate.conf ๅ„ใƒฉใ‚คใƒณใฎ ๅฃฒไธŠใƒญใ‚ฐ ใƒฉใ‚คใƒณๅฎš็พฉ ๅ‡บๅŠ›ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช ใƒ•ใ‚กใ‚คใƒซๆ•ฐใ‚ซใ‚ฆใƒณใƒˆ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ revenue-gate-state.json ้€ฃ็ถšใ‚ผใƒญๅŽ็›Š้€ฑใ‚ซใ‚ฆใƒณใƒˆ โ”‚ โ–ผ Markdown ใƒฌใƒใƒผใƒˆ็”Ÿๆˆ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ–ผ โ–ผ ~/Desktop/Revenue Gate/ Obsidian vault ๅณๆ™‚็ขบ่ช็”จ briefs/revenue-gate/ In words: every Monday at 8:20 and 13:20, launchd double-fires revenue-gate.sh . It reads revenue.jsonl the revenue log , revenue-gate.conf the line definitions , and each line's output directory counting files . It updates revenue-gate-state.json the consecutive-zero-revenue week counter , generates a Markdown report, and copies it to both ~/Desktop/Revenue Gate/ for immediate review and the Obsidian vault briefs/revenue-gate/ . Five kinds of file are involved. Let's go through them in order. ~/.claude/data/revenue-gate.conf manages every production line. The format is three pipe-separated columns. name|ๅ‡บๅŠ›ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช|glob That is: name|output directory|glob . Here's an excerpt from the real file: article|~/Desktop/Article/articles| note|~/Desktop/Article/note| maker|~/Desktop/Article/solomaker| affiliate|~/Desktop/ใ‚ขใƒ•ใ‚ฃใƒช่จ˜ไบ‹| asmr|~/dev/asmr-factory/out| sns-bokuwalily|~/dev/bokuwalily-sns/out| senior-tube|~/dev/senior-tube-factory/drafts| line-stamps|~/digital-products/line-stamps-keigo/out| lead-outreach|~/lead-finder/runs/ logs idea-ios|~/Desktop/iosใ‚ขใƒ—ใƒช| idea-chrome-ext|~/Desktop/Chromeๆ‹กๅผต| affiliate-livedoor|~/dev/affiliate-livedoor/queue| affiliate-blogger|~/dev/affiliate-blogger/queue| affiliate-fc2|~/dev/affiliate-fc2/published| Fourteen lines are defined. If the third column the glob is omitted, it's treated as all files . If you only want to count particular extensions say .mp3 or .md , you specify that in the third column. Adding a new line means adding one row to this conf. You never touch the script itself. Revenue gets recorded in ~/.claude/data/revenue.jsonl . The format is JSON Lines one record per line . {"date":"2026-06-15","source":"note","amount jpy":3200,"note":"ๆœ‰ๆ–™่จ˜ไบ‹1ๆœฌ"} {"date":"2026-06-22","source":"affiliate","amount jpy":8400,"note":"Amazonๅ ฑ้…ฌ"} The source matching a name in the conf is what ties revenue to a line. Recording is done with the bundled rev.sh command. rev.sh note 3200 ๆœ‰ๆ–™่จ˜ไบ‹1ๆœฌ This is the only manual step. I run it whenever a sales notification comes in. Revenue that could be pulled automatically ASPs with an API, etc. could eventually be filled in via cron, but manual is plenty for now. It's a five-second task a few times a week. This holds the "consecutive zero-revenue weeks" count. { "updated": "2026-07-06T08:20:05", "week": "202628", "zero weeks": { "affiliate": 2, "article": 2, "asmr": 2, "idea-chrome-ext": 2, "idea-ios": 2, "lead-outreach": 2, "line-stamps": 2, "maker": 2, "note": 2, "senior-tube": 2, "sns-bokuwalily": 2 } } As of 2026-07-06, every line sits at zero weeks: 2 . That's expected, since this is the week I started logging revenue at all. As operation continues, earning lines get reset to 0 and only the counters of non-earning lines keep climbing. This is the automatic-execution definition registered with macOS launchd. The distinctive part is that it fires twice on Monday.