How to create a team of agents with Harness of your choice.

2026-08-02Firat Dogan

I can let my agent run a task, and with a well designed task spec save you a lot of time; find posts, draft replies, or collect analytics.

But I still had to start every run, explain the context, decide what came next, and remember what happened last time. Handing off a company function is a whole another beast.

For instance, how would you lend your social media to your agent? So that it can show up in the right conversation, engage in right format, and properly represent you?

This is where I think most founders get stuck with agents. They use an agent like a better command line: give it an instruction, watch it work, then give it another one. That's useful, but the founder is still running the process by hand.

When I say a company function, I mean the whole operating loop, not a smarter task. For social media, that means finding opportunities, deciding what is worth a response, drafting in my voice, waiting for approval, publishing, measuring the result, and carrying what it learned into the next run.

Start with the filesystem

I keep coming back to a filesystem and CLI for agents. Filesystem is a fast and reliable way to structure your since everything is code, the agent doesn't need a special interface for every part. More importantly, the structure is inspectable.

Many are taking the same approach as building an agent framework; Eve by Vercel, Open Computer. And some others take hybrid approach of having both database and file system like Lobu.

For a social media function, the folder looks roughly like this:

gtm/social-manager/
  agent.md
  config.yaml
  plans/
    opportunity-discovery-loop.yaml
    draft-content.yaml
    execute-approved-action.yaml
    collect-post-analytics.yaml
    weekly-performance-review.yaml
  playbook/
  logs/runs/

agent.md is the contract. It says what the function owns, what it reads, what it can do, what it must return, and where it must stop.

The plans are not prompts pretending to be processes. They are the recurring paths through the function. Discovery is one plan. Drafting is another. Publishing is separate because it needs approval. Analytics is separate because it happens later.

This distinction sounds small, but it changes the work. The agent no longer has to reconstruct the company from one giant prompt. It enters through the plan that matches the current job.

Guidelines hold judgment

Files give the function shape. Guidelines give it judgment.

For writing, I have separate guidance for voice, audience, channel behavior, approval rules, and examples. A LinkedIn post and an X reply shouldn't have the same shape. A Reddit comment needs live community rules. A public post needs my approval. A like does not need the same ceremony.

The useful part is that these rules are not buried in the conversation. They can be read, changed, reviewed, and tested.

The agent also needs examples of how I actually write. I call that collection the corpus. Mine contains recent X posts and replies, LinkedIn posts and comments, Reddit comments, edits I made to AI drafts, and a smaller group of writers I use for structural inspiration.

It isn't just a folder full of text. Every item is labeled with who wrote it, where it was published, what kind of content it is, when it was written, and whether I consider it a useful example of my voice. Those labels stop a popular essay by somebody else from influencing my voice more than something I wrote myself.

I don't want the agent to load the whole corpus or every guideline all the time. When it writes an X reply, it retrieves the X rules, my recent replies, relevant edits, and comparable performance. When it writes a long essay, it retrieves my longer explanations and may use Paul Graham's essays to help structure the argument. The reference can influence the shape without pretending to be my voice.

My prompts and system prompts keep getting shorter because the system retrieves the right context when it needs it.

Postgres holds state. S3 holds evidence.

The filesystem alone is not enough. It's good for stable instructions, but bad at answering questions like:

  • Have we already seen this post?
  • Did I reject this angle last week?
  • Which version did I approve?
  • Is the 48-hour analytics snapshot due?
  • Which examples match this channel, topic, and format?

That state belongs in a database.

I use Neon Postgres as the organization brain. It stores entities, facts, events, and relationships. Posts, people, channels, decisions, edits, and analytics become queryable records instead of conversation history.

The database is also the index into the writing corpus. Suppose the request is: "write an X reply about agent memory." Postgres first narrows the collection to examples written by me, published on X, formatted as replies, written recently, and accepted as useful voice examples. Only then does semantic search look inside that smaller set for writing about memory or a related idea.

The order matters. If semantic search runs across everything first, a popular long-form essay can win because its topic is similar, even though its author, format, and rhythm are wrong for the job. Structured filtering decides which examples are eligible. Semantic search decides which eligible examples are relevant.

S3 has a different job. It keeps the heavier evidence: raw provider responses, research exports, screenshots, draft variants, and other artifacts I may need to inspect later. Postgres stores the normalized fact and a pointer to the source. S3 keeps the source itself.

Putting everything in one database would be simpler for a week and painful for years. Raw payloads change shape. They get large. Most queries do not need them. Keeping state and evidence separate makes both easier to use.

Tools are capabilities, not context

It's tempting to connect every tool and describe all of them in the prompt. That creates noise quickly.

I treat tools as capabilities the function can load when a plan needs them. The reason isn't tidiness. It's selection accuracy.

An agent choosing from forty tools picks the wrong one far more often than an agent choosing from four. It's the same reason a person handed a twelve-page menu orders worse than one handed a short list — every irrelevant option is another chance to pick it. The model isn't reasoning about your architecture when it selects a tool. It's pattern-matching against whatever you put in front of it, so what you put in front of it is the whole game.

So the plan decides the menu, and each plan gets a small, purpose-built set.

The Social Manager uses Bright Data for broad public discovery, Zernio for connected social context and supported actions, Composio as a capability fallback, and an authenticated browser when the providers can't safely complete the exact action. Notion is the editorial calendar. PostHog can connect website outcomes later.

The agent doesn't need all of those tools to write one paragraph. The discovery plan loads discovery capabilities and nothing that can write anywhere. The publishing plan gets write access only after an approval has been recorded — before that, the capability doesn't exist to be misused. The analytics plan gets read-only metrics, and not until 48 hours after publication.

That last detail matters more than it looks. Scoping tools by plan isn't only about accuracy; it's how you make a whole class of mistake structurally impossible. An agent that cannot post cannot post by accident.

The order matters too. If a provider returns an ambiguous result, the agent verifies the public state before trying another provider. Otherwise a fallback can become a duplicate post.

The tool list is not the system. The rules for when to use each tool are.

One function becomes a loop

The Social Manager now works as a simple loop:

retrieve context
→ discover opportunities
→ persist candidates
→ present decisions
→ draft selected ideas
→ get approval
→ publish
→ measure after 48 hours
→ review what worked

Here is what one run actually does.

It starts from the campaign I'm running, which is what defines the topics worth watching — agent infrastructure, developer tooling, founder-led GTM. It searches those topics across X, LinkedIn, and Reddit. Then it filters what comes back against my own details: is this recent enough to still be live, does it have enough engagement to be worth entering, is it actually in my territory, have we already seen it, and do the community's rules allow the action I'd be taking.

About fifteen candidates survive the search. Nine survive the filter, evenly split across the three channels. Of those, roughly five are worth my attention — and because it runs every six hours, I see about twenty a day.

Then it stops. I pick which ones to engage with. It drafts only the ones I picked, retrieving my writing examples before it writes anything. The rest stay as reference rather than being padded into recommendations I'd only have to reject.

Public posts, replies, comments, DMs, and emails always stop again for approval before anything leaves.

After publication, the system separates three kinds of memory:

  • Notion keeps standalone editorial content I may want to schedule, edit, or republish.
  • The organization brain keeps every English post, reply, comment, and quote-post I authored, plus the normalized 48-hour analytics.
  • S3 keeps the raw payloads and evidence behind those records.

That separation matters. A reply is useful training data and performance data, but it does not need to clutter the editorial calendar. A like is neither authored content nor a useful writing sample, so it does not enter the corpus at all.

Once a week, the function can review repeated evidence. My edits change the voice model immediately. Engagement can strengthen a distribution pattern, but it doesn't get to rewrite my personality. One viral post should not turn every future draft into the same post.

The human should own the decisions, not the sequence

Human-in-the-loop usually means the agent stops every few minutes to ask what to do next. That is babysitting — the human is the scheduler.

My loop also stops for me, twice a run: pick the idea, approve the exact copy. The difference is that it stops at named decisions instead of asking me to sequence the work. Between those points nothing waits on me.

As models get better, the loop gets simpler. My job is to create and sort the work, define what done means, and hold the boundaries that matter. The agent keeps going until the success criteria pass or it reaches a real exception.

This costs time early. The human feedback loop is the expensive part, and for a while I could write faster myself. What changes is that every correction makes the next draft closer to right.

The goal is not to remove judgment. It is to stop spending judgment on orchestration.

Build one function first

This architecture is not specific to social media.

A research function has source rules, recurring scans, an evidence store, and a review queue. A sales function has qualification rules, account state, approved messaging, and follow-up plans. A product function has tickets, success criteria, repository access, and verification.

But I wouldn't start by building an "AI company." That creates a folder full of agent names and no working loop.

Start with one function you already understand. Write its contract. Separate its recurring plans. Put stable judgment in files, durable state in Postgres, raw evidence in object storage, and tools behind clear capability rules. Decide exactly where a human must approve. Then make the outcome observable.

The interesting part is that the model becomes almost replaceable. You can change the model or harness without rebuilding the function from zero because the company context lives outside the session.

The model can do the task. The execution layer is what lets it keep doing the job.

Roster is a thin, agent-facing CLI and context framework around a working directory. It turns a folder into a purpose-built agent system for Claude Code or Codex without becoming a second agent runtime. Try it out:

https://github.com/firatcand/roster