Skip to main content

Agentic orchestration for governed end-to-end product delivery

Project description

Startup Factory

Turn your product board into a governed software delivery system.

Startup Factory is an agentic orchestration framework for end-to-end product delivery. Connect the project-management tool your team already loves—Linear, Jira, GitHub Issues, local Markdown, or your own adapter—and make it the durable control plane for a cross-functional team of AI agents.

Put a [task] in ToDo—the shipped mapping of the generic queued state. When automation is enabled and scheduled, the deterministic PM supervisor checks the board every three minutes by default, leaves anything labeled human-work to people, routes every other queued task by its explicit team preset (or your configured default), and drives it through architecture, implementation, a three-reviewer core In Review gate, declared Security/QA specialist gates, and integration. It also observes Blocked work as a human-controlled safety lock: the matching task workers stop, while independent ToDo work continues. When your release policy, exact approval, and protected green CI proof allow it, a separate credential-isolated executor deploys the reviewed immutable artifact, verifies the target, and only then closes the parent [feature] as Live.

Bring your own models, repository, stack, tracker, and infrastructure. Provider-neutral structured hooks can target production in any cloud, platform, cluster, datacenter, or internal environment that can implement the plan/apply/status/verify contract. Startup Factory supplies the delivery protocol, team topology, deterministic runtime, recovery model, and safety boundaries around them.

Project-management native · Multi-model · Cloud agnostic · Fail closed · Auditable

This is not a hidden chatbot loop. Plans, ownership, progress, decisions, evidence, blockers, approvals, policy denials, and deployment state remain visible in the same board where your team manages the product. Tracker text and claimed authorship are workflow evidence, never security authentication or production authority.

Startup Factory demo

ToDo -> In Progress -> In Review -> Ready for production -> deploy -> Live
                          findings -> ToDo -> fresh attempt -> In Progress
             red / pending / missing CI ----------------------X deploy anywhere

Safe by default: board automation and production delivery both ship disabled. Ordinary agents never receive production credentials; enabling a release requires protected external configuration, hooks, identities, and verification. Only an exact, current green CI/CD proof for the release commit permits deployment.

Table of contents


Layered safety boundaries for AI builders

Autonomous agents are only as useful as the boundaries around them. Startup Factory supplies fail-closed workflow and release controls, but repository code is not an operating-system security boundary. Ordinary agents still require a real worktree-scoped sandbox and least-privilege identity:

  • A code-owned production policy gate. bin/policy-check.py screens every privileged release-hook command and normalized production plan before that subprocess starts. Its deny baseline — shell composition, privilege escalation, filesystem/database/ infrastructure destruction, secret dumping, metadata-credential access, encoded-command bypasses — is owned by the code: project configuration can add denials, never remove one.
  • A three-tier authority model. Every action resolves to DENY, REQUIRE HUMAN APPROVAL, or ALLOW (reference/guardrails.md). Approvals bind exact digests, environments, targets, expirations, and one-use nonces. Silence never approves; unknown anything is denied.
  • A [task]-level release-denial trail. A normalized production-plan denial is projected idempotently as [DENIED ACTION] through bin/tracker-ops.sh record-denial. Other launcher, path, queue, and identity preflight refusals fail before mutation and remain in protected runtime logs; they are not falsely advertised as tracker records.
  • Least-privilege agent sandboxes. In enforced mode every LLM process and WORKTREE_SETUP runs as AGENT_SANDBOX_RUNNER --workdir <absolute> -- /usr/bin/env -i .... The launcher accepts only a protected executable outside the repository; that runner must enforce filesystem, process, network, and IAM isolation. In broker mode no LLM—including the team lead—receives tracker credentials.
  • Contained workspaces. Every implementer is isolated in its own git worktree; tracker file paths are symlink-safe and confined to their configured root; integration and terminal transitions are serialized, verified by read-back, and reserved to dedicated components.
  • Automation that is off by default. The portfolio supervisor is deterministic (not an LLM), disabled until explicitly enabled, and stops the pass rather than fabricating state when anything is malformed.

The built-in authority policy is intentionally simple:

Decision Representative actions Who can authorize it
Always deny Path escape or recursive/bulk deletion outside disposable task scope; database/schema drops or truncation; production instance, cluster, storage, network, DNS, certificate, key, backup, or log deletion; secret extraction; privilege escalation; wildcard IAM; force-push/history rewrite; sandbox or policy bypasses Nobody inside Startup Factory. Use a separate human-operated break-glass process.
Require exact human approval Non-destructive production infrastructure, IAM, network, DNS, certificate, capacity, schema, backfill, traffic, cost, or scale changes; external communication A protected verifier must authorize the exact manifest, target, commit, artifact, digests, expiry, and one-use nonce. A tracker comment is not approval.
Allow within scope Read-only inspection, plans, tests, builds, linting, worktree-local edits, task-branch checkpoints, brokered integration, health checks, and a policy-clean immutable-artifact release The assigned role or deterministic executor, within its path, identity, target, quota, and lifecycle boundaries.

The full non-bypassable list and enforcement boundary are in reference/guardrails.md.

The result: you can hand real delivery work to AI agents and inspect, from your tracker, the workflow actor, workflow approvals, production approval ID, and policy denials for each delivery. Authenticated production approver identity remains in protected transaction state; tracker authorship is never treated as authentication.

Why Startup Factory

Advantage What it gives you
Move fast without merge chaos A deterministic dispatcher launches only design-approved, dependency-ready, resource-safe work. Each attempt gets its own task branch and worktree; integration stays serialized.
See the whole delivery, not just agent output One live [progress] record per [task] and one [digest] per [feature] show tracker status, execution stage, actor, and attempt in your project-management tool.
Use the right model for each job Mix Claude, Codex, Gemini, or any file-reading CLI by role, then route individual tasks to fast, standard, or strong model profiles.
Keep quality gates explicit Architecture approval precedes implementation. In Review requires independent approvals from the Principal Architect, Sceptical Principal Architect, Senior Security Engineer, and Team Lead over one exact package; optional QA may add evidence, and the integrator runs your build, test, and lint commands before merging.
Recover instead of restarting Immutable task packets, durable events, checkpoint branches, an idempotent outbox, and attempt-aware relaunches make interrupted work inspectable and recoverable.
Keep your stack and your tracker The same workflow runs across languages, frameworks, LLMs, and project-management tools. Start offline with Markdown and switch adapters without rewriting the process.
Turn the board into a safe delivery queue A deterministic cron/service pass observes queued/blocked work, restores in-flight runs, chooses an explicit team preset, and launches LLMs only for eligible queued tasks.
Pause one task without stopping the factory On the next scan, [Blocked] immediately fences only the matching task. Independent ToDo work and other features continue; only a human can unlock it.
Keep dangerous authority out of agents One deny/approval/allow contract governs every role. The code gate blocks dangerous privileged release hooks and plans; your required OS sandbox and least-privilege identities enforce ordinary-agent filesystem, network, process, and IAM boundaries.

Superpowers + Startup Factory: split the SDLC by strength

obra/superpowers and Startup Factory operate at different, complementary levels.

Superpowers is an engineering methodology packaged as agent skills. Its full upstream workflow can cover brainstorming, implementation planning, worktree creation, task execution, TDD, debugging, code review, verification, and branch completion. Startup Factory is a project delivery control plane: it coordinates product, architecture, implementation, security, quality, integration, portfolio automation, and production release across durable tracker state and multiple independent agents.

The combined integration deliberately uses the strongest part of each system without running two execution orchestrators:

  • Superpowers shapes the idea into an approved specification and detailed implementation plan.
  • Startup Factory reviews those documents as inputs, creates and governs the tracked delivery, and owns execution through verified production.
  • Claude task workers may use focused Superpowers methods for TDD, debugging, receiving review, and fresh verification inside their one assigned task.
  • Superpowers does not create a second worktree, dispatch a second team, execute the plan, merge the branch, or declare the feature released.
flowchart LR
    Idea["Product idea or ticket"]
    Brainstorm["Superpowers brainstorming<br/>questions · alternatives · approved design"]
    Plan["Superpowers writing-plans<br/>exact files · interfaces · tests · commands"]
    Handoff["Digest-bound planning handoff<br/>committed spec + plan"]
    Shape["Startup Factory planning review<br/>Product · Lead · Principal · Sceptical"]
    Tracker["Tracked feature and tasks<br/>acceptance · dependencies · resources"]
    Execute["Startup Factory execution<br/>packets · branches · worktrees · dispatch"]
    Methods["Claude-local Superpowers methods<br/>TDD · debugging · review response · verification"]
    Review["Exact-package review board<br/>Lead · Principal · Sceptical · Security"]
    Integrate["Serialized integration<br/>validated feature branch"]
    Release["Protected CI and release<br/>policy · approval · deploy · verify"]

    Idea --> Brainstorm --> Plan --> Handoff --> Shape --> Tracker --> Execute
    Execute --> Methods --> Review --> Integrate --> Release

Why divide the lifecycle

Reason Benefit
One authority per stage The specification has one source, the tracker has one workflow owner, each task has one active attempt, the feature branch has one integrator, and production has one protected release executor.
Methodology stays separate from orchestration Superpowers can improve how Claude thinks, plans, tests, and debugs without competing with Startup Factory's scheduler, worktrees, review board, tracker writers, or release transaction.
Different scopes get different tools Superpowers is excellent at the local reasoning loop around one design or task. Startup Factory governs the wider system of roles, dependencies, concurrent work, artifacts, statuses, and environments.
Independent models remain independent Claude may shape the plan, while Codex, Gemini, or another model can challenge architecture, implement, review, or test without receiving Claude-only Superpowers instructions.
Planning remains challengeable A polished plan is evidence, not authority. Product and both architects still test its scope, acceptance criteria, interfaces, risks, dependencies, and delivery order before work is created or dispatched.
Recovery becomes durable Superpowers provides strong session-level discipline; Startup Factory adds tracker history, immutable packets, attempt identity, event journals, idempotent outboxes, resumable integration, and restart-safe production transactions.
The integration is reversible USE_SUPERPOWERS=false removes all Superpowers-specific wiring without changing the Startup Factory lifecycle, tracker model, team topology, or release controls.

SDLC responsibility map

SDLC stage Superpowers contribution Startup Factory contribution Primary owner in this integration
Idea discovery Socratic clarification, one question at a time, alternative approaches, trade-offs, incremental user approval Product context, repository constraints, explicit scope and NOT-in-scope Superpowers, with human approval
Specification Writes and self-checks the design document; requires the user to review the written spec Product Manager and architects challenge completeness, boundaries, risks, and acceptance criteria Superpowers produces; Startup Factory accepts or pushes back
Implementation planning Produces detailed tasks with exact files, interfaces, code steps, test commands, expected results, and no placeholders Converts the plan into independently reviewable vertical slices, dependencies, tracks, resources, and model profiles Shared handoff; Startup Factory owns executable project structure
Tracker and portfolio management Not used as the project control plane Creates [features] and [tasks], owns legal statuses, routing, progress, digests, automation scope, and generations Startup Factory
Per-task design May inform the proposed implementation Requires implementer design notes, contract registration, and independent Principal + Sceptical approval before code Startup Factory
Implementation TDD and disciplined small-step engineering methods inside a Claude task Selects the worker/model, creates immutable packets and isolated attempts, enforces scope, and records evidence Startup Factory orchestrates; Superpowers improves the local method
Debugging Root-cause investigation, pattern comparison, one hypothesis at a time, regression test, fresh verification Task-scoped stop/retry/escalation, durable evidence, attempt recovery, and architectural re-review when needed Shared: Superpowers method inside Startup Factory boundaries
Code review Helps a worker receive feedback technically and verify fixes Four independent, commit-bound verdicts over one exact review package, plus optional QA and specialist evidence Startup Factory
Integration Upstream Superpowers has branch-finishing workflows, but they are not invoked here The integrator alone validates and writes the feature branch; brokered transactions make retries idempotent Startup Factory
CI, release, and production No production authority in this integration Exact-commit protected CI, policy checks, approval binding, isolated credentials, plan/apply/status/verify hooks, rollback, and Live transition Startup Factory
Operations and recovery Session-level verification discipline Portfolio reconciliation, human [Blocked] locks, stale-worker fencing, release recovery, and auditable tracker projections Startup Factory

Where Superpowers is strongest

  • Design before code. Its brainstorming skill explores the repository, asks focused questions, compares approaches, validates the design section by section, writes the specification, performs a consistency/ambiguity review, and waits for user approval.
  • Plans that another engineer can execute. writing-plans insists on exact paths, explicit interfaces, complete steps, concrete test commands, expected outcomes, small commits, TDD ordering, and no TBD or “similar to the previous task” shortcuts.
  • Strict engineering habits. test-driven-development enforces a real red-green-refactor loop; systematic-debugging requires root-cause evidence before fixes; and verification-before-completion requires fresh command output before a success claim.
  • Useful local review discipline. receiving-code-review helps a Claude worker evaluate feedback technically, clarify uncertainty, fix one issue at a time, and verify the result instead of responding performatively.

Those strengths are intentionally used as planning inputs and task-local methods. They do not grant tracker, scheduler, integration, or production authority.

Where Startup Factory is strongest

  • Cross-functional governance. Product, Team Lead, Principal Architect, Sceptical Principal Architect, Security, implementation, QA, integration, and release have explicit and non-interchangeable responsibilities.
  • Multi-model independence. Assign different model families to design, challenge, implementation, and review so one model's blind spot does not silently become the team's consensus.
  • Deterministic execution. The dispatcher—not an LLM—selects eligible work from tracker state, dependencies, resource conflicts, design approvals, risk, and capacity.
  • Isolation and recoverability. Every attempt gets an immutable task packet containing the complete current tracker comment history, a collision-safe branch, separate worktree, report path, event history, and authenticated publication capability.
  • Review and integration integrity. Three distinct core reviewers plus any risk-declared Security/QA gates decide against the same exact package. No approval survives changed code, and only the integrator writes the feature branch.
  • Human and production safety. [Blocked] is a human-controlled task lock. Production requires protected CI evidence, policy-clean plans, exact external authority where configured, isolated credentials, target verification, and a durable transaction.
  • End-to-end visibility. The project-management tool remains the durable record from idea and acceptance criteria through findings, rework, integration, deployment, and Live.

Execution workflows that must not overlap

Upstream Superpowers includes excellent execution workflows for projects that use Superpowers alone. Startup Factory replaces these at the orchestration layer for a feature delivered by a Startup Factory team:

Superpowers workflow Startup Factory owner used instead
using-git-worktrees Per-attempt worktrees created and retired by launch-team.sh
subagent-driven-development / executing-plans Tracker-driven task packets and deterministic dispatch.sh scheduling
requesting-code-review as the authoritative gate Exact-package Startup Factory core board plus declared supporting gates
finishing-a-development-branch Serialized integrator plus protected release lifecycle

Do not run both execution systems on the same feature. Two schedulers cannot safely share task identity, branches, worktrees, review state, or completion authority.

When to use which mode

Mode Best fit
Superpowers + Startup Factory A meaningful Claude-planned feature that should become tracked, independently challenged, implemented by a team, reviewed, integrated, and potentially delivered to production.
Startup Factory alone Non-Claude runtimes, an already-approved specification, operational/release work, or any project that wants native planning without the Superpowers dependency.
Superpowers alone A local coding session where you explicitly want the upstream Superpowers execution workflow and do not launch a Startup Factory team for the same work.

How to use the combined workflow

The example below uses Claude Code for planning and a Startup Factory team for delivery. Upstream Superpowers supports other coding agents too, but this integration is intentionally enabled by default only for Claude Code.

  1. Install both systems and create the feature branch that will become the Startup Factory team name:

    # In Claude Code:
    /plugin install superpowers@claude-plugins-official
    
    # In your project shell:
    SF_HOME=.claude/skills/startup-factory
    git switch -c payments-revamp
    
  2. Keep the default planning configuration, or inspect it before starting:

    USE_SUPERPOWERS=true
    SUPERPOWERS_PLUGIN_ID=superpowers@claude-plugins-official
    SUPERPOWERS_SPEC_ROOT=docs/superpowers/specs
    SUPERPOWERS_PLAN_ROOT=docs/superpowers/plans
    

    true means “Claude is eligible,” not “enable Superpowers for every model.” Codex, Gemini, and unmarked harnesses stay on the native workflow.

  3. Verify that Claude can use the configured plugin:

    python3 "$SF_HOME/bin/superpowers-planning.py" preflight --runtime claude
    
  4. Ask Claude to shape the ticket, and make the ownership boundary explicit:

    Use superpowers:brainstorming to shape this feature. Explore the repository,
    clarify scope and success criteria, compare approaches, and write the approved
    specification. After I approve the written spec, use
    superpowers:writing-plans to create the detailed implementation plan.
    
    Stop after the committed specification and plan. Do not use Superpowers
    worktrees, subagent-driven-development, executing-plans, code-review
    orchestration, or branch-finishing. Startup Factory will own execution.
    
  5. Review the generated documents. They normally live under:

    docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md
    docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md
    

    Both files must be committed. If either changes later, commit the change, recreate the handoff, and repeat any affected planning approvals.

  6. Bind the exact documents to the Startup Factory team:

    TEAM=payments-revamp
    FEATURE_ID=ENG-100
    SPEC=docs/superpowers/specs/2026-07-16-payments-revamp-design.md
    PLAN=docs/superpowers/plans/2026-07-16-payments-revamp.md
    
    "$SF_HOME/bin/launch-team.sh" planning-handoff \
      "$TEAM" "$SPEC" "$PLAN"
    
  7. Let Startup Factory review and operationalize the handoff. The Product Manager, Team Lead, Principal Architect, and Sceptical Architect still approve scope, acceptance criteria, contracts, dependencies, risks, vertical slices, and execution order before implementation.

    A suitable instruction to the Startup Factory agent is:

    Use the validated planning handoff for payments-revamp as planning evidence.
    Review it with the Product Manager, Team Lead, Principal Architect, and
    Sceptical Architect. Resolve pushback, then create or update ENG-100 and its
    vertical-slice tasks with acceptance criteria, dependencies, tracks, files,
    resources, and model profiles. Startup Factory owns all execution.
    
  8. Launch the normal Startup Factory delivery:

    "$SF_HOME/bin/launch-team.sh" preflight "$TEAM" "$FEATURE_ID"
    "$SF_HOME/bin/launch-team.sh" gate-team full-stack "$TEAM" "$FEATURE_ID"
    "$SF_HOME/bin/dispatch.sh" "$TEAM" "$FEATURE_ID" --watch
    

    Direct claude commands in config/team.config.md are recognized automatically. Mark a Claude wrapper explicitly:

    FRONTEND_CMD="STARTUP_FACTORY_LLM_RUNTIME=claude /path/to/claude-wrapper {prompt_file}"
    

    In harness mode, declare Claude while composing:

    STARTUP_FACTORY_LLM_RUNTIME=claude \
      "$SF_HOME/bin/launch-team.sh" compose "$TEAM" "$FEATURE_ID" team-lead full-stack
    
  9. To return completely to native Startup Factory planning, edit config/planning.config.md:

    USE_SUPERPOWERS=false
    

For the exact machine-enforced boundary, see reference/superpowers-planning.md.

Full transparency in your tracker

Startup Factory treats the tracker as the durable collaboration surface, not a status board updated after the real work happened. The local runtime makes coordination fast, but the information a human needs to supervise delivery is projected back into the configured tool.

You can inspect How it stays visible
Scope and execution order [features], [tasks], dependencies, resource declarations, and legal board transitions
Design decisions Structured design notes, pushback, approvals, conditions, and numbered architecture checklists
Live progress A mechanically updated [progress] record on every task and a compact [digest] across the feature
Validation and review Evidence records, changed-file lists, review findings, exact artifact paths, and explicit NOT validated declarations
Blockers and human decisions Proven blocked-by relationships plus escalations with a question, options, and a default if you are unavailable
Release-policy denials Idempotent [DENIED ACTION] audit comments for normalized production plans; other preflight refusals remain in protected runtime logs
Delivery The integrated commit, completed validation gates, generic [Ready to deploy] (shipped as Ready for production), protected green CI proof, and an idempotent [deployment] projection through verified production and Live

Use as much of the system as your project needs:

Layer What it gives you Where
1. PM port One AI agent creates/tracks/completes [features] and [tasks] in any configured tracker through one tool-agnostic workflow. SKILL.md, reference/, adapters/
2. Governed squad A lead coordinates, two independent architects gate design, specialists implement, and three distinct core agents—the Team Lead and both architects—approve every exact review package. Security and QA join when declared by risk; the integrator alone writes the feature branch. reference/orchestration.md, roles/
3. Task-driven runtime Event-driven dispatch, bounded parallel waves, model routing, exact review packages, durable handoffs, and recoverable integration. bin/dispatch.sh, bin/runtime-state.py, bin/integrate-task.sh
4. Preset teams Six ready-made rosters for full-stack, backend, frontend, security, infrastructure, and LLM/data-science work, all resolved through the same team launcher. teams/, bin/launch-team.sh
5. Portfolio automation One bounded cron/service pass observes generic queued/blocked statuses, bootstraps only queued feature runs, and reconciles comments, task holds, and team actions. bin/pm-agent.py, reference/automation.md
6. Safe production delivery Structured provider-neutral plan/apply/status/verify hooks, hard guardrails, isolated credentials, crash recovery, and bounded rollback. bin/release-feature.py, bin/policy-check.py, reference/deployment.md

Everything is inspectable: plain Markdown, shell scripts, small Python utilities, and git. There is no application server or coordinator database to host; schedulers invoke bounded scripts, and --watch is an optional foreground clock owner. The system is language-, framework-, tracker-, and LLM-agnostic because it manages the delivery contract around the code rather than assuming anything about the stack.

Choose your operating mode

Adopt only the layers you need; each mode keeps the same vocabulary and tracker history.

Your goal Runtime shape Start here
Give one agent a reliable PM workflow Your existing agent reads SKILL.md; no daemon, external tracker, or team launcher is required. Two-minute offline quick start
Launch a governed specialist team The launcher and dispatcher coordinate task-scoped workers, gate roles, isolated worktrees, and serialized integration. Run a whole team
Continuously pull work from the board Cron, a service timer, or a hosted scheduler invokes one bounded deterministic pm-agent.py --once pass. Automate the board
Deploy approved work to a production target A protected deterministic executor runs digest-pinned provider hooks with isolated credentials and independent verification. Configure production delivery

Requirements

Minimum (single agent): a git repository, a POSIX shell, and any agentic LLM CLI or IDE that can read files (Claude Code, Codex CLI, Gemini CLI, Aider, Cursor, Windsurf, Cline, …). The release installer runs as an isolated Python tool through uvx (or pipx) and does not require Homebrew, Node.js, git, or rsync. The auditable shell compatibility path uses curl, git, and rsync.

For multi-agent teams, additionally: the launcher (bin/launch-team.sh) needs bash + git; every implementation task uses a task branch and isolated worktree. tmux is optional but recommended — without it, agents run as background processes. Autonomous protocol gates additionally require a real OS/container sandbox that hides Git-common-dir broker capability state and other process environments from agent roles; Unix file modes alone do not isolate same-UID processes. Configure that protected external executable as AGENT_SANDBOX_RUNNER before enabling autonomous execution.

Tracker access is optional. The default Markdown tracker stores everything in local files, so you can run the whole thing offline. Connect Linear/Jira/GitHub when you're ready—via MCP, REST, or the gh CLI, depending on the adapter.

For cron/service automation: use one scheduler instance and a scriptable, explicitly scoped adapter (REST/CLI/files; a cron process cannot invoke an MCP client). The scan observes queued and Blocked work, but only queued work bootstraps or launches. Registered runs are re-authorized on every pass through an exhaustive per-feature export. Production delivery additionally needs protected external structured hooks/config/state, an external identity/isolation attestor for automatic mode, and a separate short-lived credential environment that ordinary agents never inherit.

The human-only exit from [Blocked] also needs an operator-owned control in the project-management tool: restrict outbound Blocked transitions to human principals and deny them to every scheduler, bot, and service identity. Startup Factory refuses its own outbound writes, but normalized adapters do not prove who performed an external transition. If the tool cannot enforce status-level permissions or provide verified transition provenance, treat the human-only claim as an operational policy and keep autonomous portfolio automation disabled for that tool.


Quick Start (2 minutes, no accounts)

The fastest win: one AI agent managing work in local Markdown files. No tracker account, API key, Homebrew formula, or global package is required—Markdown is the default.

  1. From your project root, install the complete, versioned release bundle. Codex and Aider use the shared Agent Skills project directory:

    uvx startup-factory@latest install --agent codex
    

    For Claude Code use --agent claude-code. Pin a release in controlled environments, for example startup-factory@0.1.4. uvx creates an isolated environment for the installer and leaves no Startup Factory package in your project environment.

    The uvx path downloads the published PyPI package. For a Git checkout or offline use, use the auditable shell compatibility path.

    This quick start demonstrates the one-agent workflow. Set TEAM_MODE=false in the installed config/project-management.config.md before continuing; fresh installations otherwise use the team workflow by default.

  2. Ask your agent, in plain language:

    Plan a feature: add CSV export to the reports page.
    

    The skill creates a [feature] and a handful of [tasks] as Markdown files under .workspace/task-manager/. Then drive them:

    Start task 1.        → moves it to [Active], implements it
    Send task 1 to review.
    Finalize task 1.     → verified, committed + [Ready to deploy]
    

That's the whole loop — plan → start → review → complete — in generic vocabulary that works identically on every tracker. When you're ready for a real tracker or a full team, keep reading.

Sanity-check the runtime (no LLM calls, no cost): from the installed skill directory, bash tests/run-all.sh should finish with ALL TESTS PASS.


Install into your repository

Use a project-scoped copy. Startup Factory contains mutable tracker, team, automation, deployment, and guardrail configuration, so one global copy should not be shared across unrelated projects. Homebrew would still need a second project-initialization step and is intentionally not part of the current distribution.

Choose the project path your agent supports:

Agent Project install directory Discovery
Codex .agents/skills/startup-factory Native project skill path
Claude Code .claude/skills/startup-factory Native project skill path
Aider .agents/skills/startup-factory Start with aider --read .agents/skills/startup-factory/SKILL.md
Other agents Their native project skill directory Use native discovery or point the agent at SKILL.md

The release package embeds one deterministic bundle built from an exact Git commit. The installer verifies every archived path, size, mode, and SHA-256 digest before planning a destination change, then records the installed version, source commit, archive digest, and ownership policy locally.

# One-shot isolated install
uvx startup-factory@latest install --agent codex

# Claude Code
uvx startup-factory@latest install --agent claude-code

# Alternative isolated runner
pipx run startup-factory install --agent codex

# Persistent operator CLI
uv tool install startup-factory
startup-factory install --agent codex

Use an exact version instead of @latest in controlled environments. Package index mirrors work through normal uv/pipx configuration; installation semantics are not tied to a cloud, project-management tool, or deployment provider.

For an explicit path instead of an agent mapping:

uvx startup-factory@latest install \
  --install-dir /absolute/path/to/startup-factory

Shell compatibility path

Until the first package release, or on a host without uv/pipx, use the auditable updater. The unique temporary file is removed automatically, and a failed download cannot execute a stale installer:

SF_INSTALL_DIR=.agents/skills/startup-factory
(
  set -eu
  installer="$(mktemp "${TMPDIR:-/tmp}/startup-factory-install.XXXXXX")"
  trap 'rm -f "$installer"' EXIT
  curl -fsSLo "$installer" \
    https://raw.githubusercontent.com/alexrolls/startup-factory/main/bin/update-installed-skill.sh
  # Optional audit: less "$installer"
  bash "$installer" --install-dir "$SF_INSTALL_DIR"
)

If you already cloned or downloaded Startup Factory, skip curl and run its local bin/update-installed-skill.sh with the same --install-dir argument. The compatibility script fetches the complete repository bundle—not just SKILL.md.

Why the README does not currently use npx skills add: the open Skills CLI is the right long-term direction and correctly discovers this repository. However, its current remote repository-root installation path copies only the root SKILL.md. Startup Factory also requires bin/, config/, adapters/, extensions/, reference/, roles/, and teams/; an end-to-end installation without them is broken. Until a lean nested distribution is published, do not use npx skills add or npx skills update for Startup Factory.

Safe updates

Preview and apply an update with the same release CLI. It recognizes the selected project installation and performs a complete preflight before any destination mutation:

uvx startup-factory@latest update --agent codex --dry-run
uvx startup-factory@latest update --agent codex

For Claude Code, use --agent claude-code. You can also ask your agent:

Fetch latest Startup Factory skill.

Existing project configuration remains byte-for-byte untouched by default, while newly introduced config files are installed. Destination-only files under the documented adapters/, extensions/, and teams/ extension points are also preserved. A generated ownership manifest lets later updates delete an upstream extension that has been retired without mistaking project-owned files for upstream files. A legacy installation without a manifest is migrated conservatively: destination-only extension files are kept. If a later upstream release introduces a file at a project-owned extension path, the update fails before mutation instead of overwriting it:

  • config/project-management.config.md
  • config/planning.config.md
  • config/team.config.md
  • config/statuses.config.json
  • config/automation.config.json
  • config/deployment.config.json
  • config/guardrails.config.json

To intentionally replace those files with upstream defaults too:

uvx startup-factory@latest update --agent codex --overwrite-config

To verify the owned runtime independently of preserved configuration and custom extensions:

uvx startup-factory@latest verify --agent codex

The release CLI uses a sibling staging directory, an installation lock, and a backup swap with rollback. Interrupted copying cannot silently turn a valid installation into a partial one. Its main operator options are:

Option Purpose
--agent codex|claude-code|aider Select the native project skill directory.
--project PATH Resolve the agent directory relative to another project.
--install-dir PATH Override the mapped installation directory.
--bundle PATH For install/update, use an explicitly supplied local canonical archive.
--overwrite-config For install/update, replace all seven preserved project configuration files.
--dry-run For install/update, print the plan without writing the destination or lock.
--json Emit machine-readable output for operator automation.

Legacy/source-installed copies can continue to use the shell compatibility updater from their installed bundle:

bash .agents/skills/startup-factory/bin/update-installed-skill.sh --dry-run
bash .agents/skills/startup-factory/bin/update-installed-skill.sh

It requires git and rsync, accepts --remote-url and --ref, and defaults to main; prefer a reviewed tag or exact commit. The release CLI instead binds its embedded bundle version and source commit to the Python package version. The shell updater intentionally refuses any installation containing .startup-factory-install.json or .startup-factory-bundle.json: synchronizing a mutable Git checkout over a release-managed copy would destroy verifiable provenance. Update those copies only through uvx, pipx, or another isolated runner for the versioned startup-factory package.

Before synchronizing, the installer verifies the fetched bundle and refuses filesystem root, the home directory, a Git repository root, symlink targets, and unrelated non-empty directories. --dry-run never creates a missing destination.

Release provenance

packaging/build_bundle.py constructs the canonical archive from Git object bytes at an exact commit—not from an uncommitted checkout—and normalizes archive ordering, timestamps, ownership, and modes. Release CI builds it twice and requires byte-identical output, embeds those exact bytes in the wheel and source distribution, exercises the built wheel, generates GitHub provenance attestations, and publishes through PyPI Trusted Publishing. The GitHub Release is created from the same already-tested artifacts; nothing is rebuilt during publication.

Before the first release, a maintainer must register the startup-factory PyPI Trusted Publisher for .github/workflows/release.yml on the pypi GitHub Environment, restrict that environment's deployment branches to main without required reviewers for unattended publication, protect main with Package CI as a required check, and enable immutable GitHub Releases. Every successful push produced by a merge to main runs the release workflow. The merge must advance the version in pyproject.toml because PyPI package versions are immutable. After the exact merged commit is tested, attested, and published to PyPI, the workflow creates the matching vX.Y.Z tag and GitHub Release from the same artifacts.

Multi-agent teams require the target project to be a git repository because every implementation attempt receives a task branch and git worktree. The skill bundle may live inside that repository for interactive/manual use; autonomous automation instead requires a reviewed, protected external installation. Use the same installer with an absolute operator-owned destination outside the checkout and every agent mount. Add .teamwork/ and .workspace/ to the target repository's root .gitignore—ignore rules inside a nested skill installation do not cover project-root runtime paths.

Two execution modes (config/team.config.mdEXECUTION) share the same task-branch/worktree isolation: sequential runs one task worker at a time; parallel dispatches dependency/resource-safe waves, bounded by MAX_ACTIVE_IMPLEMENTERS (default 2 when unset). Gate roles and integration remain serialized where required.


Connect your LLM

There are two modes, and they connect to your LLM differently.

Single agent — nothing to connect

You already run an agent (Claude Code, Codex, …). The skill is instructions that agent reads, so there is no separate connection: install the bundle and talk to your agent normally. Your existing LLM credentials are used as-is.

Multi-agent teams — map each role to a CLI command

config/team.config.md is the entire LLM coupling: one line per role giving the shell command that runs that role. The launcher composes each agent's startup prompt into a file and substitutes its path for {prompt_file}.

Every cross-functional preset requires a Sceptical Architect. Its protocol mapping, roster entry, role brief, and command are validated before any team process starts; SCEPTICAL_ARCHITECT_CMD=null is a configuration error, not an opt-out.

TEAM_LEAD_CMD="claude -p \"$(cat '{prompt_file}')\" --permission-mode acceptEdits"
PRINCIPAL_ARCHITECT_CMD="claude -p \"$(cat '{prompt_file}')\" --permission-mode acceptEdits"
SCEPTICAL_ARCHITECT_CMD="codex exec --full-auto \"$(cat '{prompt_file}')\""
BACKEND_CMD="codex exec --full-auto \"$(cat '{prompt_file}')\""
REVIEWER_CMD="gemini --yolo \"$(cat '{prompt_file}')\""
TEAM_DEFAULT_CMD="claude -p \"$(cat '{prompt_file}')\" --permission-mode acceptEdits"

Command templates for common CLIs:

LLM / CLI Command template
Claude Code claude -p "$(cat '{prompt_file}')" --permission-mode acceptEdits
Codex CLI codex exec --full-auto "$(cat '{prompt_file}')"
Gemini CLI gemini --yolo "$(cat '{prompt_file}')"
Any file-reading CLI yourcli --prompt-file {prompt_file}

Direct claude commands are detected automatically. If Claude is behind a wrapper, mark only that command template so mixed-model teams remain precise:

FRONTEND_CMD="STARTUP_FACTORY_LLM_RUNTIME=claude /path/to/claude-wrapper {prompt_file}"

Mixing LLMs is the design intent — e.g. Claude to lead and own the primary architecture position, Codex to challenge it independently and implement, and Gemini to review. Use different model families for the two architects when possible to reduce correlated reasoning errors. Same-LLM teams still work.

Optional TASK_FAST_CMD, TASK_STANDARD_CMD, and TASK_STRONG_CMD overrides route individual task packets by explicit model-profile:, conservative risk classification, or a bounded low-risk fast path for documentation, formatting, and structurally small test/config tasks. Missing overrides fall back to the role command.

Use review-gates: qa, review-gates: security, or both in a [task] description when risk requires those independent passes. The dispatcher routes declared specialists before Team Lead review, and the integration evidence validator rejects missing, stale, reordered, or package-mismatched supporting approval. Deep Infra and Deep Security make security effective automatically.

Harness mode — teammates as subagents, no CLI processes

If your harness can spawn subagents and message them (e.g. Claude Code's Agent tool), skip the command map entirely: compose each role's startup prompt with bin/launch-team.sh compose <team> <featureId> <role> [preset] and spawn the role natively with it. Harness messages replace mailboxes, harness idle notifications replace heartbeats, and the tracker stays the source of truth — see reference/orchestration.mdHarness mode.

When the harness runtime is Claude Code, declare it while composing so the default-on Superpowers integration is included:

STARTUP_FACTORY_LLM_RUNTIME=claude \
  bin/launch-team.sh compose <team> <featureId> <role> [preset]

Omit the variable for Codex, Gemini, and other runtimes.

Command resolution per role: explicit <ROLE>_CMD value → used; <ROLE>_CMD=null → role disabled; absent → falls back to TEAM_DEFAULT_CMD. That fallback is why the many specialized preset-team roles need no per-role keys — set TEAM_DEFAULT_CMD once and only override the roles you want on a different model.

⚠️ Safety: those templates use auto-approve flags (acceptEdits, --full-auto, --yolo) so agents can work unattended. Workers may commit untrusted checkpoints only to task branches; only the integrator writes the feature branch. Every implementer is isolated in its own git worktree — but still run teams on a branch you can throw away, and review the tracker before merging to your main branch.


Connect your tracker

Pick one tracker in config/project-management.config.md:

PRODUCT_MANAGEMENT_TOOL=Markdown      # or Linear, Jira, GitHubIssues

Then wire its access (skip entirely for Markdown):

Tracker Access options What to set
Markdown none — local files MARKDOWN_ROOT (default .workspace/task-manager)
Linear MCP or REST API key LINEAR_ACCESS=mcp|rest; for rest, export LINEAR_API_KEY
Jira MCP or REST API token JIRA_ACCESS=mcp|rest, exact JIRA_PROJECT_KEY and child JIRA_TASK_ISSUE_TYPE; for rest, export JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN
GitHub Issues gh CLI or GitHub MCP GITHUB_REPO (explicitly required for automation; interactive use may infer from git remote), GITHUB_USE_MCP

The REST/API-key paths mean harnesses without an MCP client (Codex, Aider, plain scripts) are first-class. Each adapters/<Tool>.md has an Access mechanisms section with the exact setup (MCP, REST/curl, gh, or local-file instructions as appropriate). Scriptable remote operations have a 60-second inner deadline by default; operators may set TRACKER_OPERATION_TIMEOUT_SECONDS to an integer from 1 through 300, while automation's operationTimeoutSeconds remains the outer process-group bound.

Credentials live in environment variables, never in the config files. Once access is configured, switching among shipped adapters is a one-line change to PRODUCT_MANAGEMENT_TOOL; no workflow, prompt, or role brief mentions a tracker by name. A new tool also needs its adapter contract and deterministic tracker-ops.sh backend before unattended dispatch or automation can use it.


Configure

Core operation uses three files. Autonomous operation adds three fail-closed JSON templates. Project policy stays versioned; an enabled deployment config is instead copied to operator-protected storage outside agent mounts.

config/project-management.config.md — the tracker

Key Meaning Default
PRODUCT_MANAGEMENT_TOOL Active tracker (matches an adapters/<Name>.md) Markdown
per-tool block Access mode + defaults for the active tracker (see above)
TEAM_MODE true enables the multi-agent status-ownership model; set false for the single-agent workflow true
STRICT_STATUS true = refuse an action if a [task] isn't in the expected status (the "andon cord") true

Team mode is enabled in new installations. Set TEAM_MODE=false to opt into the single-agent workflow.

config/planning.config.md — optional Claude planning intake

Key Meaning Default
USE_SUPERPOWERS Make Claude Code eligible for obra/superpowers brainstorming and plan-writing; non-Claude runtimes stay native true
SUPERPOWERS_PLUGIN_ID Required Claude Code plugin id checked by the planning preflight superpowers@claude-plugins-official
SUPERPOWERS_SPEC_ROOT Repository-relative root for approved specifications docs/superpowers/specs
SUPERPOWERS_PLAN_ROOT Repository-relative root for approved implementation plans docs/superpowers/plans

Run python3 bin/superpowers-planning.py preflight --runtime claude before the Claude planning stages, then bin/launch-team.sh planning-handoff <team> <spec-path> <plan-path> before launching the Startup Factory team. Set USE_SUPERPOWERS=false to remove all Superpowers-specific prompt wiring. With the default true, only commands classified as Claude receive that wiring. See Superpowers + Startup Factory for the end-to-end workflow and SDLC ownership map.

Configure your board

config/statuses.config.json defines both state machines: every status, legal transitions, owner, and per-tracker tool mapping. The internal task flow is Planned → Active → Review → Ready to deploy, shipped to project tools as ToDo → In Progress → In Review → Ready for production; Blocked is the task-scoped human-held state. Review findings move the task from Review back to Planned/ToDo, and the dispatcher starts a fresh implementation attempt that returns through In Progress. The listed outbound transitions normalize human project-management actions; Startup Factory itself cannot author them. The internal feature flow is Planned → Active → Resolved, shipped with Resolved mapped to Live. Add, rename, or remove statuses by editing the JSON, then run bin/launch-team.sh validate-board to check the structural graph, reachability, owners, and marker roles. Separately verify that your active adapter maps every status to a real tracker state (the Markdown tracker needs nothing). On the shipped board, only the deterministic release-executor owns terminal feature status Resolved; disabled or unverified delivery remains non-terminal.

config/team.config.md — the team (only for multi-agent)

Section Keys Purpose
Role → command TEAM_LEAD_CMD, PRINCIPAL_ARCHITECT_CMD, SCEPTICAL_ARCHITECT_CMD, SENIOR_SECURITY_ENGINEER_CMD, INTEGRATOR_CMD, BACKEND_CMD, FRONTEND_CMD, QA_CMD, REVIEWER_CMD, TEAM_DEFAULT_CMD Which CLI runs each role (see above)
Task model routing TASK_FAST_CMD, TASK_STANDARD_CMD, TASK_STRONG_CMD Optional task-level command overrides selected from packet metadata and conservative risk classification; each falls back to the role command
Coordination TEAMWORK_ROOT (.teamwork), AGENT_ENV_ALLOWLIST (non-secret minimum), POLL_INTERVAL_SECONDS (120), STUCK_AFTER_MINUTES (15), ESCALATE_AFTER_ATTEMPTS (2), TRACKER_WRITERS (broker), EXECUTION (sequential), MAX_ACTIVE_IMPLEMENTERS (null) Canonical symlink-free workspace paths; LLMs start with env -i; deterministic broker keeps tracker credentials out of every LLM role; event-driven supervision with polling fallback; bounded sequential/parallel scheduling
Worktree provisioning WORKTREE_SETUP Non-empty setup command run once inside every fresh task worktree through the same sandbox boundary; autonomous mode rejects null/no-op provisioning.
Agent isolation AGENT_SANDBOX_RUNNER, AGENT_SANDBOX_ENFORCED Protected external runner --workdir ABSOLUTE -- /usr/bin/env -i … boundary. The runner, not Startup Factory code, must enforce filesystem, process, network, and identity isolation.
Lifecycle authority BROKER_LIFECYCLE_ROOT Absolute protected external mode-0700 root for HMAC-authenticated PID/start/tmux identities. Without it, manual processes are unmanaged and stop refuses to signal.
Validation VALIDATE_BUILD, VALIDATE_TEST, VALIDATE_LINT, VALIDATE_FORMAT, VALIDATE_SCRIPT Your stack's commands; the integrator runs them before every merge (null = skip). VALIDATE_SCRIPT replaces all four with one repo-owned script that receives the changed-file list

Point the VALIDATE_* commands at your real build/test/lint (e.g. VALIDATE_TEST="pytest") — this is the only place the framework-agnostic integrator learns about your stack.

Automation, deployment, and guardrails

File Purpose Safe default
config/automation.config.json Scan cadence, separate observation/launch kinds, task-hold policy, run cap, branch/worktree root, allowed/default team presets enabled: false
config/deployment.config.json Disabled template for protected external target/state paths, trusted base, code/hook pins, positive environment boundaries, protected CI/attestation/approval hooks, and timeouts enabled: false, approval-required
config/guardrails.config.json Project additions to the built-in immutable deny policy and automatic cost/change limits Zero cost delta; cannot weaken built-ins

Board automation configuration

Copy config/automation.config.json to protected external storage before enabling it. The scheduler reads these keys:

Key Shipped value Meaning
schemaVersion 1 Configuration schema; unknown versions fail closed.
enabled false Master switch. A disabled pass launches nothing.
trustedPath /usr/bin:/bin Absolute protected command-search directories used by the scheduler.
scanIntervalMinutes 3 Board scan interval, from 1 through 1440 minutes. Omit it to retain the three-minute default. Legacy pollSeconds is accepted only when this key is absent.
leaseSeconds 900 Single-host pass lease and bounded stale-recovery window; integer 5–86400.
operationTimeoutSeconds 120 Outer deadline for each adapter, launcher, and dispatcher child process; integer 5–3600.
releaseTimeoutSeconds 7200 Separate outer deadline for the complete release transaction; integer 60–86400 and at least the conservative full hook-path bound.
maxFeaturesPerPass 2 Maximum new feature runs bootstrapped in one pass, from 1–1000; existing runs reconcile first. The omission fallback is 1.
requireAgentSandbox true Mandatory invariant; false or missing is rejected.
requireSingleTrackerWriter true Mandatory invariant requiring deterministic broker writes.
observeStatusKinds queued, blocked Exact adapter-neutral kinds to observe. The shipped project mapping is ToDo and Blocked; observation is not launch authority.
launchStatusKinds queued The only kind eligible for a new automatic launch. [Blocked] is observed solely to enforce its hold.
blockedTaskPolicy task-scoped, human exit, no automatic resume Fixed fail-closed policy: continue independent work, refresh all communication, propagate only lead-confirmed direct dependencies, and use a fresh attempt after human resume. Missing, unknown, or weaker values are rejected.
ignoredTaskLabels human-work Case-insensitive tracker labels that reserve a task for people. New matching tasks are never claimed or launched; if the label appears mid-flight, the next reconcile stops/fences that task while independent work continues. Removing it restores normal status-specific handling on the next scan.
reconcileRegisteredRuns true Re-export and re-authorize every unfinished registered feature on each pass.
baseRef main Feature-run starting ref whose resolved base commit is recorded immutably. Production provenance is anchored separately by deployment trustedBaseRef.
branchPrefix factory- Prefix for generated feature branches. External IDs are hashed before use in paths or refs.
workspaceRoot .teamwork/pm-agent Repository-relative supervisor workspace and registry root.
defaultTeamPreset full-stack Team used when eligible metadata contains no explicit preset.
allowedTeamPresets all six shipped presets Exact routing allowlist. Unknown or changed routing pauses the run.
requireMetadataOptIn false When false, every non-ignored queued task is eligible by default. Set true to additionally require an explicit latest automation: enabled marker.
metadata.optInKey automation Adapter-neutral description/comment key for enablement.
metadata.teamPresetKey team-preset Adapter-neutral description/comment key for specialist-team routing.

--print-cron supports stable minute intervals that divide 60 and whole-hour intervals that divide 24. Use a service timer or hosted scheduler for other valid intervals, and configure its equivalent of “forbid overlapping runs.” The filesystem lease covers one host only.

Production delivery configuration

Start with the disabled config/deployment.production.approval-required.example.json, copy it outside the repository and every agent mount, then configure the exact target and protected hooks.

{
  "enabled": false,
  "mode": "approval-required",
  "environment": "production",
  "target": {
    "id": "payments-production",
    "provider": "your-cloud-or-platform",
    "region": "your-region-or-datacenter",
    "service": "your-service-or-application"
  }
}

Keep enabled false until every required external path, digest, hook, identity, and verifier below is installed and tested.

Key group What to configure
enabled, mode, environment Keep disabled until the external trust boundary is ready. Choose approval-required or the stricter-attested automatic mode; the current executor requires environment: production.
trustedBaseRef Protected base ref from which the gap-free integration chain must descend. This does not replace branch protection.
target Set a stable non-secret id; add provider-neutral routing such as provider, region, service, account, namespace, or cluster fields needed by your hooks.
stateRoot, trustedPath Absolute external release transaction/state root and protected executable-search path.
gitLfsPolicy, maxSourceArchiveBytes, maxSourceBytes, maxSourceFiles Bound and validate the isolated source snapshot consumed by planning.
approvalTtlSeconds, deliveryAttestationTtlSeconds, ciAttestationTtlSeconds Maximum age of exact approval, automatic-delivery attestation, and protected green CI evidence.
planningIsolation Declare the protected sandbox provider, separate identity, unmounted credential/state paths, and production-egress posture. Safe templates are intentionally incomplete.
credentialEnvFile, credentialEnvironmentAllowlist Mode-0600-or-stricter external credential source and the exact names the privileged hooks may receive. Ordinary agents and plan hooks never inherit it.
planningEnvironmentAllowlist, trackerEnvironmentAllowlist, environmentAllowlist Independent positive allowlists for planning/CI verification, tracker projection, and privileged release hooks.
trustedCodeDigests, trustedHookDigests SHA-256 pins for the protected executor/helper set and every dedicated hook executable.
hooks.plan Produce a canonical structured plan from isolated source, binding the exact source archive and immutable artifactDigest. Required when delivery is enabled.
hooks.verifyCi Required whenever delivery is enabled. Return a protected, fresh, exact-commit proof that every required check succeeded and no check is failed, pending, skipped, missing, stale, or unverifiable. It is re-run before planning and twice at the apply boundary.
hooks.status, hooks.apply, hooks.verify Read current target state, apply the exact reviewed artifact, and independently prove the deployed version and health.
hooks.rollback Optional bounded recovery hook; automatic rollback may target only the immediately previous immutable artifact matching observed pre-apply status.
hooks.verifyApproval Required by approval-required; validate an external exact-manifest authorization. Tracker comments never satisfy it.
hooks.verifyDelivery Required by automatic; attest role isolation, planning isolation, and approval authenticity for the exact commit and evidence digests.
timeoutsSeconds Per-hook bounds for CI verification, plan, status, apply, verify, rollback, approval, and attestation. Their conservative total must fit inside releaseTimeoutSeconds.
Release mode What can proceed
approval-required Apply proceeds for a policy-clean manifest only after the protected verifyApproval hook confirms the exact target, commit, artifact, evidence digests, expiry, and nonce.
automatic Only a non-destructive, reversible immutable-artifact release with no approval-only effects and a valid protected verifyDelivery attestation.

Both release modes also require the protected verifyCi hook to prove a green pipeline for the exact release commit. Red, failed, pending, skipped, missing, stale, or unverifiable CI blocks apply before any supported environment can be changed; no agent or tracker comment can waive that gate.

The provider hooks are the production-target boundary. Startup Factory does not hard-code AWS, Azure, GCP, Kubernetes, VMs, bare metal, or a particular CI/CD service; each hook receives and returns the normalized contracts documented in reference/deployment.md.

Project guardrail additions

config/guardrails.config.json cannot remove or override any built-in denial. Its pattern/action lists only add restrictions; its numeric keys set operator-owned bounds for otherwise policy-clean automatic plans:

Key Safe default Purpose
additionalDenyPatterns [] Add project-specific forbidden patterns for privileged release-hook argv.
additionalApprovalRequiredActions [] Add project-specific action classes that always need exact human approval.
maximumAutomaticPlanChanges 100 Bound the number of normalized effects in an automatic release plan.
maximumAutomaticCostDelta 0 With the zero default, a positive cost delta is denied in automatic mode and approval-only in approval-required mode.
allowAutomaticRollbackOnlyToPreviousArtifact true Allow automatic rollback only to the immediately previous immutable artifact whose digest matches the objectively observed pre-apply state; false disables automatic rollback.

Never put production credentials, privileged hook argv, trust pins, or release state in repository config. (config/team.config.md intentionally contains ordinary agent CLI, setup, and validation commands.) When deployment is enabled, use a protected external config and state root, absolute digest-pinned hook executables outside the repository, and a credential file outside the repository with mode 0600 or stricter, exact credential-name allowlisting, executor/root ownership, and no symlink. Generic interpreters are rejected as privileged hook executables. The scheduler authenticates and snapshots the external release entrypoint/config before its first instruction and passes only positive environment allowlists; absent or disabled external trust starts no release executor. See reference/deployment.md for the exact trusted-code keys, environment boundaries, attestation, and hook contracts.

Autonomous launch additionally refuses to start unless TRACKER_WRITERS=broker, AGENT_SANDBOX_ENFORCED=true, and a valid protected AGENT_SANDBOX_RUNNER are configured. The runner must be an absolute, non-symlink executable outside the repository, owned by the executor or root and not group/world-writable. Startup Factory validates and invokes that boundary; the runner implementation remains responsible for actual OS/container isolation. It also requires the external mode-0700 BROKER_LIFECYCLE_ROOT, kept outside every agent mount, for authenticated PID/start-time/tmux lifecycle authority.


Use it

One agent

Set TEAM_MODE=false in config/project-management.config.md, then talk to your agent in the generic vocabulary:

  • "Plan a feature: …" → creates a [feature] + [tasks]
  • "Start task ENG-142" → generic [Active] / shipped In Progress, then implements
  • "Send it to review" → generic [Review] / shipped In Review, launching the three core reviewers and any declared Security/QA gates
  • "Finalize it" → only after core and declared-gate approvals, generic [Ready to deploy] / shipped Ready for production
  • "Switch the tracker to Linear" → follows the adapter's setup

A whole team

  1. Set the bundle path for your installation, confirm the shipped TEAM_MODE=true setting, configure role commands, WORKTREE_SETUP, and at least one real VALIDATE_* command in $SF_HOME/config/team.config.md:

    SF_HOME=.agents/skills/startup-factory        # Codex / shared Agent Skills
    # SF_HOME=.claude/skills/startup-factory      # Claude Code
    

    Add .teamwork/ and .workspace/ to the target repository's root .gitignore. Provision the protected external mode-0700 BROKER_LIFECYCLE_ROOT for this dispatcher-driven path; it supplies authoritative liveness, prevents duplicate launches, and enables status/stop.

  2. Create a feature branch — its name is the team name:

    git checkout -b payments-revamp
    
  3. If Claude/Superpowers produced an approved committed specification and plan, bind them before launch:

    "$SF_HOME/bin/launch-team.sh" planning-handoff payments-revamp \
      docs/superpowers/specs/2026-07-16-payments-revamp-design.md \
      docs/superpowers/plans/2026-07-16-payments-revamp.md
    

    Skip this step when using native Startup Factory planning.

  4. Launch the preset's persistent supervision and gate roles:

    "$SF_HOME/bin/launch-team.sh" gate-team deep-backend payments-revamp ENG-100
    #                                        └ preset      └ branch/team    └ featureId
    
  5. Start the deterministic dispatcher in its own persistent shell. This process owns task claims and launches fresh task-scoped workers:

    "$SF_HOME/bin/dispatch.sh" payments-revamp ENG-100 --watch
    
  6. Watch the team:

    tmux attach -t team-payments-revamp         # live agent windows, when tmux is used
    "$SF_HOME/bin/launch-team.sh" status payments-revamp  # protected process state + heartbeat
    

    Progress lands in your tracker; anything needing you lands in .teamwork/payments-revamp/ESCALATIONS.md.

  7. Stop the dispatcher with Ctrl-C, then stop the managed team:

    "$SF_HOME/bin/launch-team.sh" stop payments-revamp
    

    If you intentionally experiment with unmanaged direct launches instead, do not rely on dispatcher liveness, status, or stop; supervise the tmux/background processes yourself.

Keep SF_HOME set in every shell that runs a launcher or dispatcher. For a protected external automation installation, set it to that absolute path.

bin/launch-team.sh subcommands:

Command Purpose
team <preset> <team> <featureId> Launch a whole preset roster
gate-team <preset> <team> <featureId> Launch only persistent supervision/review/integration gates; automation uses this and starts implementers per task
planning-handoff <team> <spec-path> <plan-path> Bind committed Claude/Superpowers specification and plan inputs to this Startup Factory team
preflight <team> <featureId> Verify adapter access, workspace writability, and UTC pin — run once before any CLI team launch
start <team> <featureId> <role>… Launch specific roles (custom teams)
relaunch <team> <featureId> <role> [preset] Restart one crashed/wedged agent
compose <team> <featureId> <role> [preset] Write a role's startup prompt without spawning — for running teammates as subagents inside your own harness (see reference/orchestration.mdHarness mode)
compose-review <team> <featureId> <role> <taskId> [preset] From a freshly exported normalized tasks.json, write a lean one-package review prompt and exact binding-manifest pointer without spawning or granting reviewer authority
start-task <team> <featureId> <role> <taskId> [attempt] [preset] Generate a packet and launch one task-scoped worker in its worktree
compose-task <team> <featureId> <role> <taskId> [attempt] [preset] Generate a packet and lean startup prompt without spawning, for harness subagents
worktree <team> <role> <taskId> [attempt] Create an implementer's isolated task worktree
worktree-remove <team> <role> <taskId> [attempt] Remove a worktree only after protected lifecycle state proves its worker is stopped; unmanaged mode refuses
validate-board [config-path] Validate status structure, initial/terminal rules, transitions, reachability, owners, and marker-role references
status <team> Show authenticated process state plus last heartbeat when protected lifecycle authority is enabled; otherwise report that markers are non-authoritative
stop <team> Stop the managed team through authenticated lifecycle identities; unmanaged mode refuses to signal
stop-task <team> <taskId> Send bounded TERM→KILL to the authenticated launcher-managed process group/session for one [task], then revoke that [task]'s active publication capabilities; sibling workers and gate roles continue

Process-group stopping is lifecycle control, not a complete containment boundary. A subprocess that deliberately escapes with setsid, double-forking, or an external supervisor may outlive the launcher. Autonomous deployments must therefore use an OS sandbox, cgroup/container, service job, or equivalent kill-on-close boundary that contains every descendant. Broker hold checks still reject output from an escaped stale process.

bin/dispatch.sh — the event loop:

Command Purpose
dispatch.sh <team> <featureId> --once [--dry-run] One deterministic read-and-act pass
dispatch.sh <team> <featureId> --watch Wake on runtime events with POLL_INTERVAL_SECONDS as a fallback — run in a persistent shell (tmux/nohup); you own this process

CLI dispatch requires scriptable tracker access. Linear and Jira default to MCP; set LINEAR_ACCESS=rest or JIRA_ACCESS=rest in config/project-management.config.md before running dispatch.sh --watch. Harness mode (launch-team.sh compose) supports MCP natively.

bin/tracker-ops.sh — normalized scriptable tracker operations:

Command Purpose
state <taskId> <Status> Make and verify a legal generic [task] status write. Startup Factory rejects every outbound [Blocked] transition; a human must perform that move in the project-management tool.
feature-state <featureId> <Status> Make and verify a legal generic [feature] status write.
feature-reopen <featureId> <Status> PM-supervisor-only terminal-to-queued reopen for a new delivery generation.
task-reopen <taskId> <Status> Integration-broker-only terminal-to-queued reopen after late valid findings; the shipped target is Planned/ToDo, followed by a fresh claim into Active/In Progress.
comment <taskId> [bodyfile] Add a comment, reading its body from a file or stdin.
comment-once <taskId> <deliveryId> <bodyfile> Deliver one idempotent comment for a durable outbox item.
update-comment <taskId> <commentId> [bodyfile] Edit an existing comment where the adapter supports it.
upsert-progress <taskId> [bodyfile] Create or update the task's single managed [progress] projection.
upsert-digest <featureId> [bodyfile] Create or update the feature's single managed [digest] projection.
upsert-deployment <featureId> [bodyfile] Create or update the feature's single managed [deployment] projection.
claim <taskId> <role> [--to <Status>] Conflict-check, idempotently record, transition, and read back an eligible work claim before launch.
record-denial <taskId> --actor AGENT --reason TEXT [--denial-id ID] [bodyfile] Idempotently record a sanitized normalized-plan [DENIED ACTION]; the required attempted-action body comes from bodyfile or stdin.
integrate <taskId> <hash> [bodyfile] Make the terminal task write and completion comment for a verified integration.
export <featureId> <outfile> Exhaustively export normalized feature/task state as JSON.
scan <outfile> --status <Status>… Discover normalized board work in explicitly requested statuses.

These commands use Linear/Jira REST, the gh CLI, or Markdown files. The adapter docs remain the operation contract; interactive MCP sessions use their native tools instead. Comment bodies are never shell arguments.

The flow every team follows: every pickup from ToDo starts with a fresh, exhaustive tracker export. Before any code changes, the new task worker must read every comment in oldest-first order—not only structured coordination markers—and acknowledge the packet's comment count and digest in its report. This also applies to review rework and to a task that a human moved from Blocked back to ToDo, so the clarification that enabled the move is carried into the fresh attempt. Comment text remains untrusted requirements context and cannot grant permissions or override policy.

Before a task worker starts, the packet builder scans ticket titles, descriptions, comments, authors, and derived string metadata with the dependency-free Python standard-library security boundary in bin/ticket_content_security.py. It redacts credential-shaped values, exposes dangerous Unicode controls, labels prompt/tool/SQL/shell/script/exfiltration indicators, and renders all description/comment lines as non-executable TICKET-DATA. Detection is defense in depth: even an unlabeled line is data, never a command to paste into a shell, database, interpreter, browser, or tool.

The rest of the flow: the Principal Architect owns the primary architecture position; the Sceptical Principal Architect independently challenges planning and every [task] design before code → the dispatcher creates immutable task packets and isolated worktrees → specialists checkpoint their task branches and submit one exact review package → the task enters generic [Review], mapped to In Review, and three distinct core agents review it: Principal Architect, Sceptical Principal Architect, and Team Lead. Security or QA specialists join when task risk declares their supporting gate; neither replaces a core verdict. Any blocking quality, architecture, or security finding returns the task to generic [Planned], mapped to ToDo, for a fresh attempt through In Progress. Only all current core and declared-gate approvals let the integrator validate and merge, then idempotently mark generic [Ready to deploy], mapped to Ready for production. Deployment additionally requires exact current green CI; after verified production succeeds, the feature is mapped to Live. Runtime events trigger PM progress and feature-digest upserts. The lead detects stuck/conflicting/crashed agents and recovers them—message → decide → reassign → relaunch—escalating to you only as a last resort. A tracker [Blocked] state is different: it is a human lock that no Startup Factory role can remove.

Automate the board and production delivery

pm-agent.py is a deterministic supervisor, despite the name: zero LLM calls when the board has nothing to do, no sleeping agent, and no hidden coordinator service.

Supervisor commands:

Command Use
pm-agent.py --once [--dry-run] Run one bounded scan/reconcile pass; this is the scheduler primitive. Dry-run performs preflight and planning without launches or tracker mutations.
pm-agent.py --watch Keep one dedicated foreground process as the clock owner, sleeping for scanIntervalMinutes between bounded passes.
pm-agent.py --print-cron Print one credential-free cron line with protected paths, isolated Python flags, lifecycle root, lease, and logging.

Choose exactly one mode. --dry-run combines only with --once.

On every pass the supervisor:

  1. authenticates the protected installation, configs, Python, Git, sandbox runner, lifecycle authority, tracker scope, and single-writer mode;
  2. takes the single-host lease and observes the configured semantic queued and blocked work, while granting launch eligibility only to queued;
  3. exhaustively re-exports every unfinished registered [feature] so a local registry entry never becomes standing authority;
  4. excludes new human-work tasks and stops/fences any matching in-flight task, enforces task-scoped holds, validates any configured opt-in and exact preset routing, then bootstraps queued work for at most maxFeaturesPerPass new isolated feature runs;
  5. launches persistent gate roles, invokes one deterministic dispatch pass, reconciles holds/comments/recovery, and starts fresh task-scoped workers only when the state machine calls for them; and
  6. hands an all-integrated feature to the protected release executor, or leaves it visibly awaiting delivery when deployment is disabled or authorization is incomplete.

Malformed state, an incomplete export, a newly human-owned task, lost required opt-in, conflicting metadata, preset drift, an expired capability, or a failed read-back pauses/stops the affected run or pass; it never falls through to a guessed action. A valid [Blocked] state is not such a failure: it fences that [task] and the portfolio continues.

[Blocked] is a human-controlled task lock

When a dispatcher or portfolio reconcile observes a [task] in [Blocked], it creates a durable task hold and captures the complete communication snapshot. If the [task] is in flight, it stops the workers bound to that [task] and revokes their active publication capabilities. The team, PM loop, gate roles, sibling [tasks], and other [features] continue. A held [task] cannot publish, integrate, or release; its parent [feature] waits because not every [task] is integrated, while unrelated [features] remain eligible for delivery.

Dependencies remain narrow and explicit:

  • A queued [task] with an unfinished non-Blocked blockedBy dependency remains unclaimable. Independent queued [tasks] continue.
  • A queued, [Active], or [Review] [task] whose adapter-normalized, first-class blockedBy edge points directly to a currently [Blocked] [task] enters dependency-impact review. Titles, descriptions, comments, and semantic similarity never create dependency edges.
  • The team-lead publishes [dependency-hold] with the current graph digest and a verdict of blocked, partially-actionable, or independent. Only an authenticated blocked verdict that still matches a fresh graph authorizes the broker to move that dependent into [Blocked]; the other verdicts give the exact graph-bound clearance needed to claim or continue it.

Only a human can move a [task] out of [Blocked]; Startup Factory has no automated outbound path. A human move of that held [task] to the configured queued status starts a resume barrier: the supervisor snapshots the [task] again, diffs title, description, every stable comment (including edits/deletions), and adapter-provided normalized attachment metadata, and asks the team-lead for an authenticated [resume-review] bound to the hold and communication digest. unchanged may clear the barrier; requirements-changed additionally requires a later [resume-plan] plus both architect design approvals; needs-human keeps it closed. The prior worktree must also be clean—dirty work is preserved for explicit salvage or quarantine, never discarded. Clearing the barrier archives the old claim and starts a fresh numbered attempt from the new packet. A human move directly to [Active] or [Review] is manual takeover, so automation remains fenced rather than claiming it. The fresh post-resume packet also embeds every current tracker comment—not just the resume markers—and the worker must review the complete history before changing code.

This human-only rule is enforceable end to end only when the project-management tool's workflow ACL restricts outbound Blocked transitions to human principals. The adapters observe state but do not authenticate the transition actor.

These hold-control markers are authenticated workflow commands, not ordinary board prose. The local broker accepts them only when a published receipt binds the exact body, role, task, feature, and verified launched-role capability. Copying the marker text into a project-management comment—or claiming a team-lead signature—does not create that receipt and grants no authority.

  1. Provision a real worktree-scoped OS sandbox and network/IAM restrictions for every ordinary agent. Install its protected external entrypoint, configure its absolute path as AGENT_SANDBOX_RUNNER, verify the --workdir <absolute> -- <argv...> contract, and set AGENT_SANDBOX_ENFORCED=true. Configure a non-empty, non-no-op WORKTREE_SETUP and at least one meaningful VALIDATE_SCRIPT, VALIDATE_BUILD, VALIDATE_TEST, VALIDATE_LINT, or VALIDATE_FORMAT command in config/team.config.md.

  2. Keep the shipped TEAM_MODE=true default, set TRACKER_WRITERS=broker, and configure a scriptable, explicit tracker scope. Linear requires LINEAR_ACCESS=rest plus LINEAR_DEFAULT_TEAM; Jira requires JIRA_ACCESS=rest plus an exact JIRA_PROJECT_KEY and JIRA_TASK_ISSUE_TYPE; GitHub requires an explicit GITHUB_REPO. Review reference/guardrails.md; ordinary agents must have no cloud/database production credentials.

  3. Install the reviewed skill and Python outside the target checkout and all agent mounts. Copy the automation/team/project-management configs there, protect them from group/world writes, set an external protected trustedPath, and configure automation. Provision a separate absolute mode-0700 BROKER_LIFECYCLE_ROOT outside the checkout, installed skill, and every agent sandbox mount; its parent chain must contain no symlinks or group/world-writable directory (so do not place it below shared /tmp). The shipped policy automatically launches queued tasks and observes Blocked tasks as human-held unless they carry the human-work label. Set requireMetadataOptIn: true if this installation should additionally require an automation: enabled metadata marker. Then inspect a pass:

    STARTUP_FACTORY_PROJECT_ROOT=/absolute/target-checkout \
    STARTUP_FACTORY_AUTOMATION_CONFIG=/protected/config/automation.json \
      /protected/python/bin/python3 -I -S -E -s \
      /protected/startup-factory/bin/pm-agent.py --once --dry-run
    
  4. Set scanIntervalMinutes to the desired board-scan cadence (default 3), set enabled: true, and install exactly one cron entry:

    STARTUP_FACTORY_PROJECT_ROOT=/absolute/target-checkout \
    STARTUP_FACTORY_AUTOMATION_CONFIG=/protected/config/automation.json \
      /protected/python/bin/python3 -I -S -E -s \
      /protected/startup-factory/bin/pm-agent.py --print-cron
    

    The explicit project root is established before trustedPath is consumed; the supervisor then verifies it with protected Git. The supervisor refuses its own executable, Python, or protected configs when they resolve inside the target repository. Configure trustedPath with protected directories that exist on the scheduler host (the portable template uses /usr/bin:/bin). A root-owned OS alias such as usrmerge /bin is canonicalized and its target chain is revalidated; user-owned symlinks are rejected. The printed line fixes the protected PATH and uses Python -I -S -E -s, but intentionally embeds no credentials. Inject tracker/deployment variables through the scheduler's secret store, service definition, or a scheduler/root-owned wrapper that preserves those flags; never put tokens in crontab. The printer accepts only exact stable cron cadences: minute intervals that divide 60 and whole-hour intervals that divide 24. Use a service timer or hosted scheduler for intervals such as seven minutes. Hosted schedulers should use their equivalent of “forbid overlapping runs.” The built-in lease covers one host; multiple hosts require a distributed lock or adapter-native compare-and-set. Each adapter, Git, launcher, and dispatcher child operation has the bounded operationTimeoutSeconds deadline; a production transaction uses its separately bounded releaseTimeoutSeconds, which must cover the full configured plan/attestation/status/apply/verify/rollback path. New queued work on an already deployed feature opens a numbered generation with a new run ID, team, and feature branch rooted at the exact verified predecessor HEAD, while preserving the stable workspace and prior release evidence.

  5. Optionally put initial routing metadata in a [task] description:

    team-preset: deep-backend
    

    Apply the tracker label human-work to reserve a task for a person. The PM supervisor makes no new claims or launches for it; if it was already in flight, the next reconcile stops its managed worker and fences publication, integration, and release while other tasks remain eligible. Removing the label returns the task to automatic consideration on the next scan. automation: disabled remains an explicit metadata opt-out, while automation: enabled is required only when requireMetadataOptIn is true.

    Treat descriptions as the baseline. Post every later routing change as a timestamped/revisioned comment; generic record updatedAt does not prove a description edit. Unordered or conflicting latest metadata pauses the run.

  6. For production, install a protected release executor/config/state root and digest-pinned provider hooks as specified in reference/deployment.md. Choose automatic only for a normalized reversible, non-destructive immutable-artifact path and a pinned external verifyDelivery attestor that proves OS role isolation, isolated source planning, and approval authenticity for the exact feature commit, integration evidence, and product-acceptance digest. Otherwise retain approval-required with an external exact-manifest verifier. Set the scheduler environment variables STARTUP_FACTORY_DEPLOYMENT_CONFIG to that external config path and STARTUP_FACTORY_RELEASE_FEATURE to the absolute executor in the protected external skill installation. Enabled production refuses the repository-local executor.

    For the common “approved work deploys to one fixed production target” setup, start from config/deployment.production.approval-required.example.json and config/pm-agent.production.env.example. Copy both outside the checkout, set target.id plus optional provider/region/service routing fields, install the pinned hooks and digests, satisfy planningIsolation, and only then set enabled: true. Only after every task is integrated and current commit-bound product acceptance exists does the supervisor trigger the guarded release handoff; verifyApproval authorizes the exact manifest, deployment and verification run automatically, and the parent [feature] closes only after verification. Ordinary tracker comments never satisfy production approval.

Scheduler environment:

Variable Required when Meaning
STARTUP_FACTORY_PROJECT_ROOT Always Absolute exact root of the target git checkout.
STARTUP_FACTORY_AUTOMATION_CONFIG Always Absolute protected external automation JSON.
STARTUP_FACTORY_LIFECYCLE_STATE_ROOT Autonomous operation Absolute protected external lifecycle authority root; overrides BROKER_LIFECYCLE_ROOT.
STARTUP_FACTORY_DEPLOYMENT_CONFIG Production delivery Absolute protected external deployment JSON. Omit it to keep release handoff disabled.
STARTUP_FACTORY_RELEASE_FEATURE Enabled production delivery Absolute protected external bin/release-feature.py; a repository-local path is refused.
Adapter credential variables Remote tracker access Inject only the names required by the selected scriptable adapter through the scheduler secret facility.

Install the operational PM configuration at <protected-skill>/config/project-management.config.md; the launcher and tracker broker read that exact location. Do not attempt to relocate it with a scheduler environment override.

Use config/pm-agent.production.env.example as non-secret wiring, not as a credential file.

Protected executor entry points (normally invoked by the supervisor, not by an LLM):

Command Purpose
release-feature.py --repository ROOT --workspace WORKTREE --team TEAM --feature ID --config DEPLOYMENT_JSON Resume or execute the durable production transaction. The supervisor also binds expected git/common-dir identities at handoff.
policy-check.py --config GUARDRAILS_JSON plan --mode MODE [--approved] PLAN_JSON Evaluate one canonical normalized release plan as DENY, REQUIRE HUMAN APPROVAL, or ALLOW.
policy-check.py --config GUARDRAILS_JSON command --action ACTION --environment production [--authorization-digest DIGEST] -- ARGV… Evaluate exact privileged hook argv before subprocess launch.

The release transaction requires the canonical symlink-free feature workspace, a gap-free integration chain rooted under trustedBaseRef, an exact commit/evidence-bound feature-level product acceptance marker, and current trusted code/hook/config bindings. Missing or stale product acceptance is routed back to the product role before any release plan or apply. A protected verifyCi hook must also prove that the exact release commit has a current green pipeline; the executor checks this before planning and twice at the apply boundary, so a red or newly regressed pipeline cannot race into deployment. The executor always queries current deployment state before apply, checks the artifact digest, independently verifies health/version, redacts loaded credentials from logs, and records success only after verification. The release executor alone performs the terminal [feature] transition; disabled or waiting delivery remains non-terminal. Disabled delivery creates no tracker deployment projection; the PM registry records local awaiting state. A safe rollback can target only the immediately previous immutable artifact matching the objectively observed pre-apply digest. Branch protection remains an operator-owned git-host control; trustedBaseRef does not configure it.

Each run also records the exact initial baseCommit, refuses pre-positioned feature branches, and requires the branch/base ancestry to remain intact. Before handoff the supervisor captures the canonical Git common/worktree directory paths and device/inode identities; the release executor binds Git directly to those directories and rechecks their identity plus feature HEAD at apply.


The six preset teams

Preset Roster Use when
full-stack Team Lead · Principal Software Architect · Sceptical Architect · Senior Technical PM · Senior Full Stack Engineer · Senior QA Features cutting through schema, API, and UI — the default
deep-backend Team Lead · Principal Backend Architect · Sceptical Architect · TPM · Senior Staff Engineer · Senior QA Domain logic, data models, APIs, performance
deep-frontend Team Lead · Principal Frontend Architect · Sceptical Architect · TPM · Senior Frontend Engineer · Senior QA UI architecture, client state, design systems, a11y
deep-security Team Lead · Principal Security Architect · Sceptical Architect · Senior Security Engineer · TPM · Senior Security Implementation Engineer · Senior Penetration Tester · Senior QA Security features & hardening on your own codebase
deep-infra Team Lead · Principal Cloud & Infrastructure Architect · Sceptical Architect · Senior Security Engineer · TPM · Senior Cloud Engineer · Senior SRE · Senior QA Cloud infra, IaC, delivery pipelines, reliability
deep-llm Team Lead · Principal LLM Architect · Sceptical Principal LLM Architect · TPM · Senior LLM Engineer · Senior Staff Backend Engineer · Senior Full Stack Engineer · Senior QA LLM systems, data science, RAG, evaluation, inference services, and LLM product UX

Every preset launches three distinct core review-board agents: Team Lead, Principal Architect, and Sceptical Principal Architect. They independently review the same exact package. Every preset retains a distinct Security mapping for on-demand gates; Deep Infra and Deep Security launch it by default and require it for every task. A standard integrator owns serialized feature-branch commits and recoverable tracker finalization only after core and declared supporting approvals. Details in teams/README.md.


How it works

The PM layer applies the ports-and-adapters (hexagonal) pattern: workflows and agents speak one stable vocabulary; one config selects the adapter that translates it to a concrete tracker. Teams, models, and deployment hooks never need tracker-specific workflow logic.

flowchart LR
    Board["Linear · Jira · GitHub Issues · Markdown"]
    PM["Deterministic PM supervisor<br/>cron · timer · service"]
    State{"Task state?"}
    Hold["Task-scoped human hold<br/>stop worker · revoke capability"]
    Route{"Opt-in and preset<br/>valid?"}
    Gates["Lead · Product · Two architects<br/>scope and independent design gates"]
    Work["Task-scoped agents<br/>isolated Git worktrees"]
    Review["In Review<br/>Lead · Principal · Sceptical · Security"]
    Rework["ToDo<br/>fresh numbered attempt"]
    Integrate["Integrator<br/>serialized feature branch"]
    CI{"Exact-commit protected CI<br/>green?"}
    Policy{"Release policy and<br/>exact authority pass?"}
    Release["Credential-isolated<br/>release executor"]
    Target["Verified production target<br/>feature Live"]

    Board --> PM --> State
    State -->|queued| Route
    State -->|Blocked| Hold -->|human returns to queued| Board
    Route -->|yes| Gates --> Work --> Review
    Review -->|blocking finding| Rework --> Work
    Review -->|core + declared gates approve| Integrate --> CI
    CI -->|green| Policy
    CI -->|red · pending · missing| Board
    Route -->|pause / escalate| Board
    Policy -->|approved| Release --> Target --> Board
    Policy -->|wait / deny| Board

The dispatcher claims a [task] under a per-pass lock, generates its packet, and launches exactly one attempt. Design notes, approvals, findings, and escalations remain structured tracker comments. An append-only event journal wakes local coordination quickly; the durable outbox serializes tracker writes when TRACKER_WRITERS=broker; polling remains the distributed fallback.


Documentation map

Read this It answers…
SKILL.md What does an agent load, in what order, and which invariants must every workflow obey?
reference/vocabulary.md What stable [feature]/[task] contract and status semantics do all adapters share?
reference/lifecycle.md How does work move through planning, execution, review, blocking, automation, and production release?
reference/superpowers-planning.md How does Claude/Superpowers produce planning inputs without taking over Startup Factory execution?
reference/team-roles.md Which role owns each status and transition in team mode?
reference/orchestration.md How do roles coordinate, authenticate handoffs, review, integrate, recover, and pull the andon cord?
reference/dispatch.md Which deterministic event launches each next role action?
reference/automation.md How do protected cron/service scans, task holds, human resume barriers, routing metadata, registration, generations, leases, and recovery work?
reference/guardrails.md Which actions are denied, approval-only, or autonomously allowed, and where are those boundaries enforced?
reference/deployment.md What are the provider-neutral hook schemas, trust requirements, approvals, transaction phases, and rollback rules?
teams/README.md and teams/_PLAYBOOK.md Which preset should you choose and how does its shared delivery protocol operate?
extensions/tracker-backends/README.md Where does a project-owned backend module for a custom tracker live?
Tracker guide Scriptable unattended access Interactive access
adapters/Markdown.md Local files; zero credentials Local files
adapters/Linear.md Scriptable GraphQL HTTP mode with exact team scope MCP or the configured rest mode
adapters/Jira.md REST with exact project and child type MCP or REST
adapters/GitHubIssues.md gh CLI with explicit repository GitHub MCP or gh
adapters/_TEMPLATE.md Contract for a new tool, including exhaustive pagination, normalized scan/export, idempotent writes, and read-back Tool-specific

Directory map

A source checkout is arranged as below. Runtime entries ship in the operational bundle; release-engineering entries are intentionally omitted from project skill installations. The Python source distribution contains the marked package metadata and CLI source, but not repository-only release automation.

├── README.md                         this guide
├── SKILL.md                          the operational skill your agent runs
├── LICENSE                           MIT distribution terms
├── pyproject.toml                    release source + sdist: package metadata
├── packaging/                        release repository only
│   ├── bundle-spec.json              canonical payload and preservation policy
│   └── build_bundle.py               reproducible exact-commit archive builder
├── src/startup_factory_cli/          release source + sdist: installer CLI
├── .github/workflows/                release repository only: package/release CI
├── config/
│   ├── project-management.config.md  ← EDIT: pick tracker, TEAM_MODE, STRICT_STATUS
│   ├── planning.config.md            ← EDIT: Claude/Superpowers planning on/off
│   ├── team.config.md                ← EDIT (teams): role→CLI, timings, VALIDATE_*
│   └── statuses · automation · deployment · guardrails configs
├── reference/
│   ├── vocabulary.md                 the tool-agnostic contract (the port)
│   ├── lifecycle.md                  the scenarios: plan → work → review → complete
│   ├── team-roles.md                 status ownership across roles
│   ├── orchestration.md              the multi-agent protocol
│   └── superpowers-planning · automation · deployment · guardrails
├── adapters/
│   ├── Markdown.md · Linear.md · Jira.md · GitHubIssues.md
│   └── _TEMPLATE.md                  scaffold for a new tracker
├── extensions/tracker-backends/      project-owned custom tracker modules
├── roles/                            the 9 base protocol roles
│   └── team-lead · principal-architect · sceptical-architect · senior-security-engineer · integrator · backend · frontend · qa · reviewer
├── teams/
│   ├── README.md · _PLAYBOOK.md      how presets work + shared collaboration flow
│   ├── full-stack.md · deep-backend.md · deep-frontend.md · deep-security.md · deep-infra.md · deep-llm.md
│   └── roles/                        21 specialized role briefs
├── bin/
│   ├── launch-team.sh                role and task-instance launcher
│   ├── superpowers-planning.py       Claude plugin preflight + planning handoff
│   ├── process-lifecycle.py          authenticated external process/tmux authority
│   ├── update-installed-skill.sh     legacy/source compatibility updater
│   ├── dispatch.sh · dispatch-plan.py deterministic bounded scheduler
│   ├── runtime-state.py · task_metadata.py
│   │                                  event journal, metadata/routing, task packets
│   ├── submit-artifact.sh · process-outbox.sh
│   ├── review-package.sh · review_evidence.py · integrate-task.sh · finalize-integrations.sh
│   ├── teamwork-path.py · product_acceptance.py safety/path and product gates
│   ├── pm-agent.py                   bounded portfolio scheduler pass
│   ├── release-feature.py · policy-check.py
│   └── tracker-ops.sh                idempotent tracker operations
└── tests/                            offline smoke tests (no LLM calls)
    └── run-all.sh                    tracker, runtime, dispatch, launcher, integration

Extend it

Team and role extensions are one file. A new tracker needs its adapter contract plus a scriptable backend before deterministic dispatch/automation can use it.

  • New tracker: copy adapters/_TEMPLATE.mdadapters/<YourTool>.md, fill the tables, add the normalized primitive backend class at extensions/tracker-backends/<YourTool>.py, then set PRODUCT_MANAGEMENT_TOOL=<YourTool>. Do not edit the upstream-owned bin/tracker-ops.sh; see extensions/tracker-backends/README.md.
  • New team: copy any teams/<preset>.md, edit the charter, ROSTER= line, and specialist roles. Include distinct enabled roster mappings for PROTOCOL_TEAM_LEAD, PROTOCOL_PRINCIPAL_ARCHITECT, and PROTOCOL_SCEPTICAL_ARCHITECT, plus integrator. Also map an independent, launchable PROTOCOL_SECURITY_REVIEWER outside the default roster. Put it in the roster and set REQUIRED_REVIEW_GATES=security only for a security- or infrastructure-focused team whose every task requires security review.
  • New role: add teams/roles/<kebab-name>.md with the standard sections (identity, Protocol mapping, responsibilities, decision authority, deliverables, handoffs, "you never"). The launcher resolves any role that has a brief in roles/ or teams/roles/.

Keep the generic vocabulary ([feature], [task], semantic status kinds) and the exact protocol markers — never invent new ones.


Troubleshooting

Symptom Fix
Agent says the tracker is unavailable Re-check the adapter's Access mechanisms (MCP block or exported API-key env vars); the agent stops rather than fabricating — that's by design
launch-team.sh can't find a role The role needs a brief in roles/ or teams/roles/, and its <ROLE>_CMD (or TEAM_DEFAULT_CMD) must be set
A role won't launch in a preset An optional role may have <ROLE>_CMD=null; remove the line to fall back to TEAM_DEFAULT_CMD. Team Lead, Principal Architect, and Sceptical Principal Architect are mandatory, distinct rostered reviewers. Security must have a distinct launchable mapping but stays out of ordinary startup rosters; Deep Infra and Deep Security require it in the roster. Invalid mappings or missing commands reject launch.
No tmux Agents run as background processes automatically. With protected lifecycle state use status/stop; otherwise supervise them externally. Logs remain under .teamwork/<team>/pids/
status says lifecycle supervision is disabled Provision BROKER_LIFECYCLE_ROOT as documented in config/team.config.md; unmanaged manual mode deliberately refuses stop rather than trusting workspace PID text
Team seems stuck With protected lifecycle state configured, bin/launch-team.sh status <team> shows authoritative process state plus heartbeats; the lead applies the recovery ladder, and anything needing you is in .teamwork/<team>/ESCALATIONS.md. A [Blocked] task is intentionally human-held and never changed outbound by automation.
An eligible queued task never launches Confirm automation is enabled and scheduled, the scriptable adapter has an exact scope, the task does not carry an ignoredTaskLabels value such as human-work, and team-preset is absent or exactly one allowed preset. If requireMetadataOptIn is true, also confirm the latest metadata says automation: enabled; conflicting or unordered metadata deliberately pauses.
A human moved [Blocked] to queued but no fresh attempt starts Inspect the generated resume-review request. A broker-authenticated [resume-review] must bind its exact hold and communication digest; changed requirements also need a later [resume-plan] and both architect design approvals, and the prior worktree must be clean.
--print-cron rejects the scan interval Conventional cron output supports minute divisors of 60 and whole-hour divisors of 24. Use a service timer or hosted scheduler for cadences such as seven minutes
another live pass owns the monitor lease One healthy pass is already running on this host. Do not start a second scheduler; multi-host operation needs a distributed lock or adapter-native compare-and-set
Release waits for product acceptance Publish a current feature-scope [product-approval] bound to the exact final feature HEAD and integration-evidence digest; stale or ambiguous evidence cannot release
Release says it is awaiting CI Inspect the protected verifyCi result for the exact release commit. Failed, pending, skipped, missing, stale, mismatched, or unverifiable required checks block every apply; fix CI and rerun the release transaction—never bypass or replace this proof with a tracker comment.
Release says it is awaiting authorization In approval-required mode, have the protected verifyApproval system authorize the exact manifest before its expiry; a board comment is intentionally insufficient
Release is fenced after an uncertain apply, detached-worker loss (exit 125), post-launch authority change, or target mismatch Inspect the protected transaction and target status evidence. Repair the provider hook/target state and let the transaction reconcile; never blindly re-run apply or delete the fence
Want to verify the plumbing bash tests/run-all.shALL TESTS PASS (stub agents + local files; no LLM, no cost)

Credits

Inspired by the PlatformPlatform product-management architecture, developed by Thomas Jespersen.

Optional Claude planning builds on obra/superpowers, created by Jesse Vincent and the Prime Radiant team. Startup Factory uses its planning and task-local engineering methods while retaining independent ownership of orchestration, review, integration, and production delivery.


License

MIT License

The canonical license file is LICENSE.

Copyright (c) 2026 ExecMatchAi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

startup_factory-0.1.4.tar.gz (652.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

startup_factory-0.1.4-py3-none-any.whl (578.2 kB view details)

Uploaded Python 3

File details

Details for the file startup_factory-0.1.4.tar.gz.

File metadata

  • Download URL: startup_factory-0.1.4.tar.gz
  • Upload date:
  • Size: 652.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for startup_factory-0.1.4.tar.gz
Algorithm Hash digest
SHA256 eae33f9ba3326d5d7ab6c2f25a55912d1a56a30448e2b32aef12e66dbdc247e5
MD5 ec265d9af75da6894135ec58aed8cfbf
BLAKE2b-256 115ee6a1f3a562619324f0aa9d7c67d8c56cd31569a2c095949b73f6a8c55a5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for startup_factory-0.1.4.tar.gz:

Publisher: release.yml on alexrolls/startup-factory

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file startup_factory-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: startup_factory-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 578.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for startup_factory-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 6c8dc49d06c42b13e99bf6dcaf82e905dbb280db73b878b3bd97df70cf072f5a
MD5 e5005c8500cdcba38648589c4970e320
BLAKE2b-256 3cba681e8cee883a86710a429befa9af2bed35f92259247ca944b284e24b20ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for startup_factory-0.1.4-py3-none-any.whl:

Publisher: release.yml on alexrolls/startup-factory

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page