AgentStack
SKILL verified MIT Self-run

Agency Os

skill-automatelab-tech-agency-os-agency-os · by AutomateLab-tech

Notion-as-source-of-truth dispatch board. Status flow Suggestion→Discussion→To-Do→In Progress→Done with subtasks, recurring tasks, deps, batch agent execution. Trigger: 'suggest X', 'discuss X', 'approve', 'start X', 'run todo', 'mark X done', 'kill X', 'next', 'capture this to Notion', 'agency-os status'.

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-automatelab-tech-agency-os-agency-os

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Agency Os? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

agency-os

Notion-as-source-of-truth dispatch board. One Tasks database, one Hub page, one page per Corpus, one page each for General Guidance and Resources. The skill mutates Notion via the Notion MCP (mcp__*__notion-* tools); only references/notion-pointers.json is committed to git.

Skill name decision: the skill is named agency-os (matching the repo). All commands are /agency-os . This is the single plugin entry point; there is no agency-os/notion sub-namespace. If you embed this plugin alongside others, prefix commands with agency-os to avoid collisions.

Positioning when writing user-facing copy (READ FIRST)

This is the canonical positioning brief. Apply it to any user-facing copy you draft for agency-os — README sections, blog posts, X threads, LinkedIn posts, Reddit submissions, plugin-directory entries, awesome-list PR bodies, social cards, launch surfaces, anything operators or audiences will read.

Lead with these, in this order:

  1. Structures the work. Turns AI ideas into a visual workflow board so the user doesn't drown in suggestions. The board is the source of truth; work has shape and status.
  2. Streamlines agent-human interaction. Discuss → scope → approve → run. The human is in the loop on every shipping decision.
  3. Control over execution. Every run is operator-gated. Nothing dispatches autonomously. Exec=Agent is opt-in per row.
  4. Visual workflow. One Notion board, one status flow (Suggestion → Discussion → To-Do → In Progress → Done), subtasks, dependencies, recurring cadences.

Demote — mention later in the piece, never in the hook, headline, or opening tweet:

  • Token savings, "cheaper than running on Opus", Haiku-subagent dispatch — phrase as a side benefit, not the headline.
  • Model-per-task routing — a consequence of the design, not the reason to adopt.

The product's first value is structuring AI-assisted work and keeping the human in control of what ships. Cost efficiency is a happy consequence of doing that well, not the pitch.

This section is mechanics-neutral: how the Sonnet/Haiku dispatch works is documented below under "Execution model" — that's how, not why. Don't conflate the two when writing copy.

Harness compatibility

This SKILL.md is the authoritative spec and is harness-agnostic. The slash-command interface (/agency-os ...), the status flow, the schema, the workspace layout, and every command's behavior are the same everywhere.

Per-harness wrappers only differ in two things:

  • How commands are triggered. Claude Code exposes them as real slash commands via the plugin manifest. Cursor / Cline / generic MCP harnesses load this file as instructions and rely on the user typing /agency-os ... (or the natural-language equivalent) into chat. Either way, the parser is the same.
  • Whether mutations are delegated to a subagent. The "Execution model" section below describes Claude Code's Sonnet subagent dispatch. Other harnesses run mutations directly on the main agent. The Notion MCP calls underneath are identical; only the indirection changes.

See docs/harnesses/ for per-harness setup. If you're reading this in a non-Claude-Code harness, treat the subagent dispatch instructions as optional: execute commands inline instead.

Execution model — model selection by harness

Claude Code: delegate to Sonnet (medium reasoning)

Every /agency-os invocation runs on Sonnet at medium reasoning effort via a subagent. Sonnet at medium is the right balance for ID resolution, dedup, and brief assembly. The orchestrator stays free for conversation.

Agent({
  description: "Run /agency-os ",
  subagent_type: "general-purpose",
  model: "sonnet",
  prompt: "Run /agency-os  .\n\nRead .claude/skills/agency-os/SKILL.md AND .claude/skills/agency-os/references/commands/.md for the specific command spec. Execute end-to-end: sync preflight (run `python .claude/skills/agency-os/scripts/sync-tasks.py` via Bash — this incrementally refreshes the local mirror at `state/tasks.json`; do NOT call notion-fetch on the full data source as a default read path), resolve IDs against the local mirror, mutate Notion via the Notion MCP, write-through patch the mirror with the MCP response in the same step, and return the exact output format the command file specifies. All task/result links must be formatted as CommonMark markdown links — `[title](url)` — never HTML `` tags and never a bare URL. If anything fails (sync, MCP, ID resolution), stop and report — do not guess.\n\nSTRUCTURE CHECK (for `suggest` without `--parent`, and for any batch suggest): Before creating any row, read `.claude/skills/agency-os/state/task-tree.json` for the current active task hierarchy. If the file is absent, call `/agency-os tree` first. Scan In-Progress and To-Do rows for an obvious umbrella parent. If a candidate exists with high confidence, surface it and require the orchestrator to confirm before proceeding. Never silently create a top-level row when an obvious parent exists. Full rules: `references/structuring-work.md`.\n\nALWAYS PRODUCE OUTPUT. On success: the skill's standard output. On failure: one paragraph naming what failed and what state Notion was left in. Returning nothing is not an option."
})

Orchestrator MUST relay subagent output verbatim. If output is empty: say subagent returned no output; check Notion directly. Never re-run, never absorb silently.

Natural-language driving stays on the orchestrator. Parsing "let's discuss the X task" into /agency-os discuss , asking clarifying questions during a discussion, deciding log vs add-subtask — that runs on the orchestrator so thread context survives. Only discrete mutations dispatch to Sonnet.

Rule of thumb: touches Notion via MCP → Sonnet subagent. Deciding what to touch → orchestrator.

Non-Claude harnesses: read models from config.json

On Cursor, Cline, Continue, and generic MCP harnesses, the skill can't spawn subagents. Instead:

  1. Before first use: run /agency-os init to store your preferred models in .claude/skills/agency-os/config.json.
  2. Mutations (suggest, discuss, log, etc.): run inline on the main agent.
  3. Batch execution (/agency-os run): read config.json and use the stored models' constraints when evaluating task complexity.

The config file has this shape:

{
  "harness": "cursor",
  "models": {
    "haiku": "claude-haiku-4-5-20251001",
    "sonnet": "claude-sonnet-4-6",
    "opus": "claude-opus-4-7"
  }
}

The /agency-os run command still uses the same picker heuristic (Haiku for mechanical work, Sonnet default, Opus for strategic) — but on non-Claude harnesses, you need to ensure your harness has an API or SDK integration with those models. If your harness only supports one model, set all three to that model.


Authorization gates — no auto-promotion, no auto-execution

Three transitions require explicit user authorization every time. The skill must never make these moves on its own initiative.

Gate 1 — Promoting to To-Do. Any transition into To-Do (via approve, move --to todo, or direct Status write) is a scheduling commitment. MUST NOT promote unless the user named that row or an explicit batch the row clearly belongs to. "Cascade-approve discussion descendants because the user wants the parent executed" is forbidden — that's auto-promotion. Recurring-loop auto-flip on done is the only exception (the operator authorized it when marking Type=recurring).

Gate 2 — Marking Exec=Agent. Operator-owned. Skill MUST NOT set Exec=Agent on any row unless the user explicitly named that row and asked for it. Bulk-flipping across a subtree because "these look agent-runnable" is forbidden. Exec=Human and Exec=none are safe defaults; only Exec=Agent requires the gate.

Gate 3 — Firing the queue. /agency-os run is dry-run by default; --go is the user's explicit dispatch authorization. Orchestrator never adds --go to a run call the user did not type.

Worked failure mode. User says "execute all todo tasks under OS-XXX" → dispatch rows that are already Status=To-Do AND Exec=Agent under OS-XXX. Does NOT authorize flipping Discussion descendants to To-Do, flipping leaves to Exec=Agent, or any prep step. If literal scope yields zero runnable rows, say so and ask — do not invent prep.

When in doubt — ask. List candidates, wait for selection, then act. Never guess the set.


What lives where (hybrid contract)

  • Local, source-of-truth: every skill spec under .claude/skills/, every doc under docs/, the notion-pointers.json binding, and references/general-guidance.md (the canonical General Guidance text — Notion's page is a one-way mirror).
  • In Notion, source-of-truth: task rows (Title / Status / Corpus / Priority / Impact / Type / Cadence / Effort / Parent Task), discussion logs, done logs, corpus pages, the Hub itself.
  • One-way mirror: references/general-guidance.md → Notion General Guidance. Edit locally, push to Notion. Never reverse-sync.

Briefs pull task state from Notion (via the local mirror) and stable spec from local files. The brief contains pointers to local files, not copies.

# setup
/agency-os scaffold [--parent=] [--corpora=",,..."]
/agency-os init [--harness ...] [--haiku=...] [--sonnet=...] [--opus=...]
/agency-os sync
/agency-os tree [--depth N] [--corpus=] [--status=]

# suggestions
/agency-os suggest "" [--corpus=] [--type one-time|recurring]
                              [--cadence ...] [--notes "..."] [--effort S|M|L|XL]
                              [--parent=] [--force-top-level]

# clarification & subtasks
/agency-os discuss 
/agency-os log  ""
/agency-os add-subtask  "" [--effort=] [--notes "..."] [--deps=...]
/agency-os approve 

# execution
/agency-os start 
/agency-os refresh
/agency-os run [--go]
/agency-os done  [--result-link ] [--note "..."]
/agency-os kill  [--reason "..."]

# read
/agency-os next [N] [--corpus=]
/agency-os status
/agency-os list  [--corpus=]
/agency-os show  [--section description|discussion|donelog|all] [--entry ]

# escape hatches
/agency-os update  [--title="..."] [--notes="..."] [--priority=1|2|3|4]
                       [--effort=...] [--type=...] [--cadence=...] [--corpus=]
                       [--deps=,,...|none] [--parent=|none]
/agency-os move  --to 
/agency-os add-corpus "" [--goal "..."]

Natural language is also a trigger — see the "Natural-language driving" table below.

Command specs live in references/commands/.md. The subagent loads SKILL.md + the one command file for the dispatched command.


Status flow — the dedup gate

Suggestion --discuss--> Discussion --approve--> To-Do --start--> In Progress --done--> Done
                                                                             ^
   any  --kill-->  Killed  (terminal)                                        |
                              Recurring tasks: done logs + loops to To-Do ---+

| Status | Meaning | Set by | |---|---|---| | Suggestion | Idea in the inbox; not yet discussed | suggest, manual | | Discussion | Under clarification | discuss | | To-Do | Approved; scheduled | approve, recurring loop | | In Progress | Agent actively working | start | | Done | Closed (one-time) | done | | Killed | Intentionally dropped | kill |

next filters Status == "To-Do" sorted by Priority asc then Created asc. run requires Status == "To-Do" AND Exec == "Agent". suggest refuses dupes via Title-Jaccard ≥ 0.8 against any non-terminal status. If start crashes, manual recovery: /agency-os move --to todo.


Sync — local mirror is the read path

Every command reads from a local JSON mirror at state/tasks.json, not from live Notion. The mirror is kept fresh by an incremental delta sync that only fetches pages whose last_edited_time advanced since the last sync — typically a handful of rows per command, often zero. Live notion-fetch of the full data source is the escape hatch, not the default. Token cost per command drops by roughly an order of magnitude after the first bootstrap.

Preflight (every command). Run:

python .claude/skills/agency-os/scripts/sync-tasks.py

via the Bash tool. The script reads NOTION_KEY from .env, pulls the data source ID from notion-pointers.json, queries Notion with a last_edited_time filter, parses each changed page's body (Description / Discussion log / Done log toggleable H2 sections), and upserts into state/tasks.json. On first run (no mirror file) it does a full bootstrap. Then resolve ` against state/tasks.json`.

Write-through on mutations. Every command that mutates Notion (via the Notion MCP — notion-create-pages, notion-update-page, etc.) MUST patch the corresponding row in state/tasks.json in the same step, using the response payload from the MCP call. This keeps the mirror authoritative across the same session and prevents the next command from re-syncing the row we just wrote. The shape of each row is what sync-tasks.py produces (see schema below).

Escape hatches.

  • python scripts/sync-tasks.py --full — full rebuild (e.g. after schema changes or suspected drift).
  • notion-fetch directly — only when you need a property the mirror doesn't carry, or when verifying the mirror against live data. Do not make this the default; the whole point is to stop dragging the full DB into LLM context on every command.

Tree snapshot side-effect. After every successful sync, also write state/task-tree.json — a compact nested representation of all non-terminal tasks (Suggestion / Discussion / To-Do / In Progress), structured as a tree via Parent Task. This is the free structure reference for suggest preflight and orchestrator planning. Both files are gitignored.

{
  "snapshot_at": "",
  "tree": [
    {
      "id": "OS-12", "notion_id": "", "url": "",
      "title": "Top-level initiative", "status": "In Progress",
      "corpus": "General", "effort": "L", "depth": 0,
      "children": [
        { "id": "OS-13", "notion_id": "...", "url": "...",
          "title": "Container subtask", "status": "To-Do",
          "corpus": "General", "effort": "M", "depth": 1,
          "children": [] }
      ]
    }
  ]
}

Mirror schema (state/tasks.json).

{
  "synced_at": "",
  "previous_synced_at": "",
  "tasks": [
    {
      "notion_id": "", "task_id": "OS-12", "url": "",
      "title": "...", "status": "To-Do",
      "type": "one-time", "cadence": null,
      "corpus": "General", "priority": "2", "impact": "high",
      "effort": "M", "exec": "Agent", "tags": [],
      "parent_task_id": "", "dependency_ids": [""],
      "last_done": null, "done_at": null, "result_link": null,
      "created_time": "", "last_edited_time": "",
      "description": "",
      "latest_discussion_entry": "",
      "last_done_log_entry": ""
    }
  ]
}

If sync-tasks.py fails (Notion API down, OAuth expired, network error), print sync failed: and abort the command — do not fall back to a stale mirror for mutations. Read-only commands (list, next, show, status, tree) MAY proceed against the existing mirror with a sync failed; reading stale mirror warning; mutations (suggest, discuss, approve, start, done, kill, update, move, log, add-subtask) MUST abort.


Workspace structure

Hub  (page)
+-- intro: what this board is for
+-- General Guidance  -> page
+-- General Plan      -> table; one row per Corpus, linked to its page
+-- Suggestions Inbox  (linked DB view: Status=Suggestion, sort Created desc)
+-- In Discussion      (linked DB view: Status=Discussion, sort Created desc)
+-- To-Do (Scheduled)  (linked DB view: Status=To-Do, sort Priority asc, group by Corpus)
+-- Recurring          (linked DB view: Type=recurring, sort Last Done asc)
+-- In Progress        (linked DB view: Status=In Pr

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AutomateLab-tech](https://github.com/AutomateLab-tech)
- **Source:** [AutomateLab-tech/agency-os](https://github.com/AutomateLab-tech/agency-os)
- **License:** MIT
- **Homepage:** https://automatelab.tech/products/skills-and-plugins/agency-os/

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.