Back to blog

SSI automation. How I built 13 cron jobs without getting banned from LinkedIn.

In one week my LinkedIn SSI dropped from 38 to 37. I'm fine with that. I just finished building a system of 13 cron jobs, and the first things I put in were a STOP file and an approval folder.

AI writes drafts, I approve. AI clicks "follow." AI does not publish anything under my name.

Here is why I made it that way and what it actually consists of.

What SSI is and why I bothered

Social Selling Index is LinkedIn's internal metric. Four categories, 25 points each: Brand, Find people, Insights, Relationships. You can see it at /sales/ssi. My baseline on 2026-05-20 was 38/100. My target by Q3 2026 is 58. Not "top 1% of the profession," just a normal senior engineer with an active network.

To get there I need to do the same routine every day. Look at the profiles of relevant people, drop useful comments under their posts, follow hashtags, reply to comments under my own posts, occasionally send a connect request with a short personal note.

A five-to-ten-minute checklist. Every morning. Every week. Every month.

I know myself. By the seventh working day I'd close the checklist once and never open it again. I run seven parallel projects, and LinkedIn activity isn't critical for any of them. Nobody opens a Jira ticket saying "Ivan didn't comment on post X today."

So either I drop SSI as a metric and stop complaining about thin inbound. Or I move it into a system that runs without me.

What I am NOT automating

Before I describe the 13 jobs, three things that are deliberately not in the system. They are the LinkedIn ban triggers.

First, content published under my name without approval. The bot never posts a comment, reply, post or connect-note before showing me the draft. Technically I could wire in a local LLM that drops "great post, +1" under every feed item. The account would be gone in a week.

Second, mass-connect and like farms. There are scripts that mash "connect" through a list of a thousand URLs. That is not SSI growth, that is a ban. LinkedIn sees the pattern and disables the account.

Third, hardcoded positive comments. "Great point!", "Insightful!", "Couldn't agree more." That is not engaging with insights, that is spam. Your Insights score will tick up for a week and then flatline as soon as LinkedIn gets the first abuse report.

My system is the other way around. AI does the work I would do by hand — reads the feed, filters out noise, drafts a phrasing. I do the part only I can do. I decide what goes out under my name.

13 jobs: what each one does

The roadmap lives in my vault as a single document. Thirteen routines, T1 through T13. Plain description, no bash.

  • T1, feed scan. Every day 08:00. Reads 30 fresh posts in the feed, picks 5 from target ICP, drafts comments into Inbox/. I approve in the morning.
  • T2, posts approved comments. 12:00 and 17:00, 3 per batch. Approval already granted at T1.
  • T3, follow hashtags. 1st of each month, 13 target tags. Auto.
  • T4, repost candidate. Monday 09:30. Picks last week's top post from target ICP, drafts a repost comment. I approve.
  • T5, follow 202 companies from Airtable. Running on a separate cron from the earlier experiment. Auto.
  • T6, profile views. 07:00, 5 to 8 ICP profiles. Auto, passive action.
  • T7, connect request with a personal note. 20:00. First two weeks I approve each message. Then auto, within the daily limit.
  • T8, pulls notifications and drafts replies. 08:30. Each comment under one of my posts gets a 1-to-2 line draft in Inbox/. I approve.
  • T9, posts approved replies. 10:00, 14:00, 19:00. Approval already granted at T8.
  • T10, suggests a Featured candidate. 1st of the month at 10:00. I only — the bot does not pin anything itself.
  • T11, SSI snapshot. Monday 09:00. Writes the current SSI into the trend table, pings Telegram if it dropped. Auto.
  • T12, refreshes stats for all posts. Saturday 10:00. Auto.
  • T13, long-form LinkedIn Article. Once a month, generates a 1500-to-2500 word draft. I approve.

Seven out of thirteen produce content that will be published under my name. Seven approval gates.

Five are passive. Follow, view, snapshot. Those run auto.

T10 is the one job that stays with me even at the approval stage. Picking which post to pin in Featured is a question of self-presentation, not of statistics.

Three mechanisms the system cannot run without

If I just drop 13 cron scripts into ~/Library/LaunchAgents and hit bootstrap, within a day I will have a frozen Chrome, duplicate comments under the same feed, and no quick way to stop any of it.

So the system started with three engineering layers, not with prompts.

A file-lock via mkdir

All 13 jobs share one Chrome profile, the same LinkedIn session I logged in by hand a month ago. That profile cannot survive two parallel instances.

The simple solution is mkdir cron/.lock. Atomic. If two crontabs fire at the same time, the second one hits directory exists and bails out. There is a PID file inside the lock directory. If the owner died (crash, kill -9), the next job sees the dead PID and clears the lock itself.

The second instance waits up to ten minutes, logs skipped_locked and exits cleanly. I might miss one batch, but I will never have two instances colliding in the same Chrome.

The STOP file

In 06 - Operations/cron/ there is an empty file called STOP. If it exists, every routine checks for it on the first line and exits without doing anything.

touch "06 - Операции/cron/STOP"

One command, one minute to a full stop. This matters more than it looks. If tomorrow LinkedIn shows a captcha or a security alert, I have a "stop everything" button that works faster than launchctl unload on thirteen plist files.

One file, one check at the top of each wrapper script. No config layer on top.

Approval folders as an inbox

Any job that generates content drops it into 04 - Контент/<type>/Inbox/ with status: draft in frontmatter. For a comment under someone else's post it looks like this:

---
post_url: https://www.linkedin.com/posts/...
author: First Last
icp_tag: founder-ru-relocated
suggested_comment: "Saw the same situation on a project in 2024..."
status: draft
---

In the morning I open Inbox/, read the drafts, delete the noise, set status: approved on the rest and move them into Queue/. At noon T2 picks everything approved out of Queue/, posts it and moves the files into Published/.

No dashboard, no UI. Markdown files in three folders. Five to ten minutes of my time in the morning. Same time I would spend on the checklist by hand, but now the drafts are already written.

Rate limits I borrowed from watching LinkedIn

LinkedIn doesn't publish official limits, but it bans for crossing them. The numbers in my scripts come from public write-ups on automation and from my own scars on the company-follow experiment with 202 entries.

  • Comments: no more than 6 per day. Five targeted plus one buffer.
  • Replies on my own posts: no more than 10 per day.
  • Connect requests: no more than 5 per day and 25 per week.
  • Profile views: no more than 10 per day.

I add a pause of 30 to 90 seconds between same-kind actions. Between batches of different kinds (done posting comments, switching to profile views) the wait is 2 to 15 minutes.

These numbers aren't magic. They're two to three times below what I've seen described as "still safe." The buffer is cheaper than recovering a banned account.

What I measured after week one

T11 (snapshot) and T1 (feed scan) passed smoke tests on 2026-05-21. T1 produced five comment drafts in 7 to 10 minutes that survived my morning review without voice edits. That's unusual with any AI helper, and the credit goes not to the model but to the voice guide in my vault that T1's prompt references directly.

T11 took a minute to write the current SSI into the trend table. It also surfaced something I didn't want to see.

baseline 2026-05-20 — 38/100. snapshot 2026-05-21 — 37/100.

The Insights category went from 7.00 to 6.95. Not a disaster, but also not "46 in a month." LinkedIn recomputes SSI daily, and one of the four measurements went down on the same day the system came online.

So that is the real baseline. From here on I measure in weeks, not days.

What does not work yet

A few honest gaps.

T6 and T7 (profile views and connect requests) are sitting idle. They need an Airtable shared view with 50 to 100 ICP people, the human counterpart of the company view I already have. That list doesn't exist yet, and until I carve out two hours to build it, the jobs just wait. Which is fine: the Find people SSI component depends mostly on T7, and there's real ban risk in running mass-connect too fast. Better to leave it dark for now.

launchd hasn't bootstrapped the jobs. I'm running them by hand for now: trigger the wrapper from a terminal, watch the JSONL logs, tune the prompts. In a week, once the smoke tests stay green, I'll copy the .plist files into ~/Library/LaunchAgents and bring them up with launchctl bootstrap.

The thing I'm least sure about is voice. T1 produces good RU comments under RU posts and good EN under EN. On a mixed feed, which LinkedIn loves to serve, the bot occasionally drifts into formality. That's not an architectural bug, it's iterative prompt tuning in prompts/T1.md. A few more passes will get it there.

Closing

Most of the writing on "LinkedIn automation" is about scripts that automate publishing. Mine is about a system that automates preparation and keeps publishing on me.

I design the architecture. What counts as a polite touch on LinkedIn, where the limits sit, what I am willing to put my name on. AI plays the role of an assistant, not a marketer.

This is the second large engineering system I've built inside my Obsidian vault through Claude Code in the past month. The first one was about keeping project documentation alive, the previous post on this site. The shared idea is simple: I make decisions, the agent executes, and the files between us hold the state that survives a restart.

Three months from now I'll know whether I reached 58 SSI. The logs and trend table in my vault are the best cure I know for fooling myself.

If you have the same problem (a LinkedIn profile that you keep meaning to "grow" but never quite get around to), drop me a DM. Not as a service offer — more like a conversation between two engineers who don't enjoy open social feeds.