SYSTEM NOTICE

Auto translation by AI. Be sure, accuracy, nuances and authorial intent may not be fully reflected.
見出し画像

Zero-Employee Company Day 4 | The Day I Had AI Write a Diary and Post It to X and Slack

It was on the fourth day that I realized, "From the outside, no one has any idea what this company is doing."


The agents are running. The issues are progressing. But there is no mechanism to communicate this externally. There is also no system to share updates with all departments on Slack.


One of the weaknesses of a zero-employee company is that "communication is costly." Since there are no people, the cycle of someone writing and posting simply doesn't happen.


If so, I should just have AI write it and have AI post it.


---


TL;DR


- Created diary.py: Claude analyzes daily health check logs to generate a diary entry, which is then automatically posted to X.

- Created slack-report.py: Automatically posts AI daily reports to all five business division channels.

- Got stuck on the pitfall of writing Japanese files using osascript (solution included).


---


Challenge: The communication problem of a zero-employee company


In a company run by humans, someone updates Twitter and someone writes the internal newsletter.


A zero-employee company cannot do that.


But when you think about it, the task of "writing a daily report" can be structured.


1. Which agent executed what today (can be retrieved from logs)

2. Turn that into text a human can read (just have an LLM do it)

3. Post to the appropriate channel (can be automated via API)


It can all be automated. Let's do it.


---


diary.py: Automatic diary posting to X


I designed the posting pipeline to X like this.


health-loop logs (JSON)

→ Converted into text as a "Zero-Employee CEO's Diary" using the Claude API

→ Posting via X API (OAuth 1.0a)


A few implementation points.


Claude CLI timeout issue


The first thing I got stuck on during implementation was the Claude CLI timeout.


diary.py calls the Claude CLI as a subprocess. If the default timeout is too short, it cuts off when passing long logs.


❌ timeout=30 (30 seconds is too short)

✅ timeout=120 (Extended to 120 seconds)


It's a simple thing, but it took time to figure out. The error message was TimeoutExpired, so at first, I thought, "Claude's response is slow." That wasn't it. I had just set the timeout too short.


X API Authentication


The X API uses OAuth 1.0a. If you use tweepy, it works with almost a copy-paste.


I put all authentication credentials in ~/.secrets/social-media.env and exclude them with .gitignore. I don't write them directly in the code.


The diary actually generated


Text like this is generated and posted to X.


"PenguLab's operation log for today. Hermes has been running for 8.2 hours, and Sabine from web-conversion-reset has completed the template implementation. The REV department remains in a BLOCK state today, but the initial delivery for WCRU is approaching. It looks like we can move to the verification phase tomorrow. #PenguLab #BuildingInPublic "


---


slack-report.py: AI daily report for all departments


Posting to Slack is a bit more complex than posting to X. This is because I want to send different content to each department.


Instead of a uniform message for the whole company, I extract and send only the logs relevant to each department.


Design:

- pengu-press → Logs for Hermes, PengPeng

- web-conversion → Logs for Rex, Sabine, Qui-Gon

- motion-studio → Logs for Padme

- revenue-ops, general → Company-wide logs


I created a Slack Bot (PenguLab Bot) and granted it the chat:write and channels:read scopes. I obtained the Bot Token from the Slack API and saved it to .secrets/slack-webhooks.env.


When executed, it posts to each channel like this.


📊 pengu-press Today's Daily Report

Hermes: Currently working on PEN-38 (Tool invocation improvement). 6 hours of operation.

PengPeng: Waiting for today's X posting schedule.

Caution: Hermes response speed is 15% slower than yesterday. Likely due to model congestion.

Tomorrow's priority tasks: Complete PEN-38 + Verify PEN-41


---


The issue of Japanese characters becoming garbled in osascript


On this day, I got stuck trying to write a draft of an article to a file.


When using a Heredoc with osascript (macOS AppleScript execution command) to write a file containing Japanese, the characters become garbled.


The cause is how encoding is handled. UTF-8 is not being passed correctly between osascript and the shell.


As a solution, I switched to a method using a Python script (.write-utf8.py) as an intermediary.


Mechanism:

1. Base64 encode the content

2. .write-utf8.py decodes the base64 and writes it to a file in UTF-8


It's a bit of a hassle, but this ensures that Japanese files can be written out reliably. Once the mechanism is built, it can be reused.


---


Dry-run design


I included a --dry-run option in diary.py and slack-report.py from the start.


This allows me to check 'what kind of text will be generated' before posting it for real.


Automated posting scripts are hard to stop once they start running. Designing them so that you can verify them beforehand with a dry run is insurance against future regrets.


---


Registration with launchd (cron settings)


Finally, I added the configuration for running this periodically via launchd to my list of remaining tasks.


The ideal setup is to have diary.py run every morning at 9:00 AM and slack-report.py run every day at 6:00 PM.


I will implement this in the next session.


---


Information Dissemination Strategy for a Zero-Employee Company


Through today's work, I thought about information dissemination for a zero-employee company.


Purpose of external communication (X): To show what I am building as part of 'Building in Public.' Transparency for followers. It also serves as recruitment PR.


Purpose of internal sharing (Slack): A daily report for myself. Checking every day what moved forward and where I am stuck. Visualizing operations is important even for a zero-employee company.


Purpose of Note (this series): Detailed technical documentation. Recording both what went well and where I got stuck in a format that can be referenced later.


By combining these three channels, I can create a state where "no one is there, but information is flowing."


---


Summary


- X posts → Convert health logs via Claude API using diary.py, then post via X API

- Slack daily reports → Filter by department and post via bot

- osascript Japanese character issue → Avoided using a Python script via base64

- Always include a --dry-run option in automation scripts


In four days, the infrastructure for a zero-employee company has started running. Agents are active, logs are being collected, and they are turning into daily reports that go out to the world.


Next, I will begin verifying "how much work these agents are actually doing."


---


PenguLab Building in Public Series — Day 4

→ Please follow to wait for the continuation of the series. Updating daily.

いいなと思ったら応援しよう!