H3Tech · Single-File Guide

Synaptory User Guide

Single-file documentation build for offline distribution.

30 chapters
v1.0.0
27630af
built 2026-05-31T13:13:14Z
Start · 01

Synaptory User Guide

Multi-agent adaptive delivery — orchestrate the best AI for each role.

The Problem

Most AI coding tools make you faster at writing code. You still play every other role yourself: project manager, architect, QA lead, security reviewer, DevOps engineer — all at once. You prompt, review, iterate, manually wire things together, figure out tests, set up CI/CD, and write docs. The AI writes files; you do everything else.

The Shift

synaptory changes what you are doing entirely. You describe what you want to build. Nine specialized agents — Project Owner, Solution Architect, Software Engineer, Code Reviewer, Quality Engineer, Compliance Engineer, Platform Engineer, Technical Writer, and Research Advisor — coordinate through an adaptive delivery lifecycle to produce a complete system: architecture decisions, tested backend and frontend, security audit, infrastructure, and documentation. You sit in the strategist's seat — approving direction, not directing labor.

The system is built on one principle: do the work, don't describe the work. When a decision has a clearly superior option, agents take it and report what they chose and why. Results are reported, not plans.

How It Works

synaptory classifies every request automatically into one of three operation layers. Just describe what you need — the orchestrator routes to the right agents.

flowchart TD
  prompt["Your prompt"] --> orchestrator["Orchestrator classifies intent"]
  orchestrator --> scrum["Scrum Lifecycle"]
  orchestrator --> kanban["Kanban Lifecycle"]
  orchestrator --> util["Standalone Utility"]
  scrum --> inception["Inception → Sprint Loop → Release"]
  kanban --> discover["Discover → Ticket Flow → Release"]
  util --> modes["Debug / Explore / Branch Finish / Story Buddy / ..."]

Scrum Lifecycle (greenfield or brownfield)

For new products or major capabilities built iteratively:

Inception --> Sprint Planning --> Sprint Execution --> Sprint Review
                                                           |
                Sprint Close <-- Sprint Retro (adaptive) <-+
                    |
                    +--> Next Sprint (loop) or Release

Per-story pipeline: Every story flows SE (implement) → QE (test) → CR (review) → DoD evaluation. Quality is verified per story, not at the end.

Kanban Lifecycle (brownfield maintenance)

For post-launch maintenance and continuous ticket flow on existing codebases:

Discover --> Ready --> Execute ticket --> Review --> Ready (loop)
                                                      |
                                                      +--> Release (on-demand)

Standalone Utilities

Debug, Explore, Discover, Preview, Branch Finish, Story Buddy, Retro, Init, Status, Help — no lifecycle context needed. "Review my code" routes to the Code Reviewer. "Debug this error" runs structured root-cause analysis.

What You Get

From a single prompt, a Scrum delivery produces (iteratively, sprint by sprint):

  • Requirements and architecture — BRD, ADRs, system design, API contracts
  • Working code — backend services, frontend UI, design system
  • Tests — unit, integration, e2e, and performance test suites
  • Security — OWASP/STRIDE threat model, dependency scan, compliance audit
  • Infrastructure — IaC modules, Kubernetes manifests, CI/CD pipelines
  • Documentation — API reference, developer guides, runbooks
  • Ticket tracking — stories, epics, sprints managed in your tracker (local, GitHub Issues, Jira Cloud, or Teamwork)

Not every task needs the full lifecycle. Standalone modes handle scoped work — from a targeted Debug or Code Review to Story Buddy per-ticket workflows and brownfield reverse-engineering.

Choosing the Right Path

If your situation is...UseWhy
Starting a new product or major capabilityBuild / ScrumInception, sprint planning, iterative delivery, Release
Existing codebase needing ongoing maintenanceKanbanDiscover first, then continuous ticket-based flow
Know the story and want focused help on one itemStory BuddyRequirements, implement, test, or sprint-planning without the full lifecycle
Active failure needing root-cause analysisDebugStructured reproduce → isolate → understand → fix loop
Verification before merging or shippingBranch Finish or ReleaseBranch Finish is branch-scoped; Release is full production-readiness
Unfamiliar brownfield system to understand firstDiscoverBuilds context packages and risk awareness before delivery starts

Quality Model

One human gate at project start. Continuous automated verification on every story.

CheckpointWhenWhat you review
Inception GateAfter Sprint 0Project direction — vision, epics, Sprint 1 stories, architecture foundations
Per-Story DoDEvery storyAutomated: tests pass, build succeeds, no critical findings, code reviewed (adaptive)
Sprint DoD OverlaySprint Review (Scrum)Sprint Goal met, feedback addressed, no regression, docs updated

Between checkpoints, agents work autonomously — building, testing, reviewing, and fixing their own failures.

AI Model Routing

All agents in this build run on Claude. The Orchestrator selects the model tier based on role type:

TierAgentsRationale
OpusPO · SA · CE · RAStrategic decisions — scope, architecture, risk, direction
SonnetSE · QE · PE · TW · CRExecution roles — implement, test, review, document

The active tier is fixed per role. The only lever is engagement_mode: structured | interactive in .synaptory.yaml.

Configure in .synaptory.yaml:

agents:
  default_backend: "claude"

Ticket Tracking

All story, epic, sprint, and backlog operations go through a pluggable tracker adapter. Every agent calls the same tracker_cli.py commands regardless of backend.

BackendStorageWhen to use
local.synaptory/.orchestrator/tracker-data.jsonDefault. Zero deps. Solo or small team.
githubGitHub Issues (types + milestones + labels)Team with GitHub repo.
jiraJira Cloud (native types + Scrum board)Enterprise with Jira.
teamworkTeamwork Projects (tasks + milestones)Teams using Teamwork.

Runtime Artifacts

synaptory persists lifecycle state and evidence under .synaptory/.orchestrator/:

ArtifactPurposeWhen it appears
pipeline-state.jsonSource of truth for Scrum or Kanban lifecycle stateAfter Init and throughout delivery
receipts/Story-scoped machine-verifiable agent receiptsAfter each subagent completes work
context-packages/Brownfield reverse-engineering outputs from DiscoverAfter Discover or Context Refresh
last-session.mdSnapshot for cross-session resumeOn session stop
tracker-data.jsonLocal tracker state when using the local backendWhen local tracking is enabled

Documentation Guide

Concepts — How synaptory thinks

PageDescription
The Synaptory PlatformHow the plugin, CLI, and Control Plane fit together
Platform ArchitectureDeeper view: per-URL routing, request sequence, where every artifact lives
Identity and AccessEntra OAuth, synaptory-users vs synaptory-admins, project membership
PersonasFive roles that touch the platform and their entry points
Delivery LifecycleThe adaptive lifecycle: Scrum ceremonies, Kanban flow, story pipeline
ModesOperation modes and how the orchestrator classifies requests
AgentsThe 9 agents, their roles, backends, and authority boundaries
Engagement ModesAutonomous vs. Controlled execution
EnforcementReceipts, DoD evaluation, safety nets
v3.0 RoadmapWhat's next: spec graph, four-gate model, evidence ledger, policy/domain packs, runtime adapters

Guides — How to do things

PageDescription
Scrum DeliveryComplete walkthrough: Inception through sprint ceremonies to Release
Kanban DeliveryContinuous ticket-based delivery and brownfield workflows
Multi-Spec DeliveryRunning multiple parallel specs out of one repo + one Jira project
ReleaseShipping to production from Scrum or Kanban
Resuming SessionsCross-session persistence and progress tracking
Using the Control PlanePage-by-page tour of synaptory.h3t.co (role-aware: every signed-in user gets the same app, scoped to their grants)
Inviting MembersEnd-to-end flow for granting and revoking project access

Reference — Lookup information

PageDescription
ConfigurationComplete .synaptory.yaml schema
CommandsAll CLI commands and tools
RoutingEvery mode the orchestrator can dispatch and the tiebreakers between them
RulesThe 10 behavioural rules auto-injected on every session start
HooksLifecycle hooks and enforcement
URLsEvery public URL on synaptory.h3t.co and what it serves
Auth FlowsWeb code-flow, CLI PKCE, and local-auth fallback (sequence diagrams)
PermissionsWhat each Entra group + project role grants
Glossaryv2.5 ↔ v3.0 vocabulary map and platform terminology

Troubleshooting

PageDescription
TroubleshootingCommon issues and fixes

Reading Paths by Role

PM / BA — Requirements and delivery strategy

  1. Delivery Lifecycle — Understand ceremonies and the story pipeline
  2. Scrum Delivery — Sprint Planning, Review, and your role in each ceremony
  3. Agents — Project Owner behavior and authority boundaries
  4. Configuration — build_mode, tracker, and sprint settings

Dev — Implementation and architecture

  1. Modes — Debug, Story Buddy, Branch Finish, and other modes you use daily
  2. Agents — Software Engineer modes, tech packs, Code Reviewer boundaries
  3. Kanban Delivery — Working with existing codebases
  4. Resuming Sessions — Cross-session persistence

QE — Verification and quality

  1. Enforcement — Receipts, DoD evaluation, safety nets
  2. Agents — Quality Engineer modes, Compliance Engineer, Code Reviewer
  3. Delivery Lifecycle — Per-story pipeline and adaptive DoD
  4. Hooks — Verification hooks and enforcement behavior

Control Plane user — Any signed-in member of synaptory-users

  1. Personas — Confirm where you fit
  2. Using the Control Plane — Page-by-page tour (role-aware)
  3. Identity and Access — Why your view is scoped to you
  4. Auth Flows — Sign-in path and session revoke

Project admin — Granting access

  1. Inviting Members — Three paths and their tradeoffs
  2. Permissionsmember vs admin capabilities
  3. Using the Control Plane — Members tab specifics

Global admin — Operator cockpit

  1. Personas — Confirm where you fit
  2. Using the Control Plane — Admin-only pages
  3. Platform Architecture — Where every artifact lives
  4. Permissions — What synaptory-admins grants
  5. URLs — Every URL on synaptory.h3t.co
Start · 02

Getting Started

Four steps from zero to your first delivery run.

New here? The plugin you're installing is the in-IDE component of a larger platform — there's a separate Go CLI, a control plane, and web surfaces. Read The Synaptory Platform for a 5-minute overview of how they fit together.


Step 1 -- Install the plugin and the CLI

The plugin lives in the H3Tech marketplace; the CLI is shipped separately. Install both once.

Plugin:

/plugin marketplace add https://synaptory.h3t.co/marketplace
/plugin install "synaptory@h3tech-ai"

Choose User scope for all projects, or Project scope for the current project only. Restart Claude Code afterwards.

CLI (one install per laptop, shared across every synaptory project):

# macOS / Linux
curl -fsSL https://synaptory.h3t.co/cli/install.sh | bash

# Windows (PowerShell)
iwr -useb https://synaptory.h3t.co/cli/install.ps1 | iex

See Install the CLI for the full walk-through, PATH setup, and updates.


Step 2 -- Sign in

synaptory authenticates through your organisation's Microsoft Entra ID. One sign-in per laptop — the same session works across every project you're a member of (the way gh and aws work).

How it works

After the plugin is installed and Claude Code restarts, the session-start hook checks for a cached session. If none is valid (or refreshable), it surfaces an instruction to run:

synaptory login

A browser tab opens to your org's sign-in page. After sign-in the CLI prints the projects you have access to:

login: signed in as you@yourorg.com (session expires 2026-04-26T09:15:00Z)
login: member of 2 project(s): taskflow-pilot, synaptory-build

The session is cached in the OS keychain — you won't be prompted again until the token expires (typically 24 hours; the CLI refreshes it silently when possible).

Headless environments (no browser)

If you're on a server or CI machine where a browser can't open, run the device-code flow once from a terminal:

synaptory login --device

Follow the on-screen instructions: visit the URL shown, enter the code, and approve. The session is cached in the same keychain store and produces the same user-scoped token as the browser flow.

Telling synaptory which project this repo belongs to

Each repo carries a one-line config that maps it to a control-plane project slug:

# .synaptory.yaml
project_id: "my-project"

Or per-shell:

export SYNAPTORY_PROJECT_ID=my-project

The CLI walks up from your current directory looking for the file, the same way git finds .git/. Telemetry and skill fetches stamp this slug onto each request, and the server checks your membership against project_members per call.

Verify sign-in at any time

synaptory whoami           # UPN, expiry
synaptory projects list    # what you can see, with your role in each

If sign-in fails, check the troubleshooting section or run synaptory status for a full diagnostic.

Note: All skill access is scoped to your session identity. Usage is watermarked and auditable by your H3Tech operator.


Step 3 -- Configure your project

Say "initialize my project" to scan your codebase and generate .synaptory.yaml:

initialize my project

What it auto-detects:

  • Language -- package.json, go.mod, pyproject.toml, Cargo.toml, pom.xml
  • Framework -- next.config.*, nest-cli.json, fastapi, gin, actix
  • Infrastructure -- Dockerfile*, terraform/, k8s/, .github/workflows/
  • Architecture -- monolith, modular-monolith, microservices, monorepo

The orchestrator shows a detection summary and asks before writing. Review the generated config before your first run.

Key configuration choices

build_mode: "scrum"              # scrum (default) or kanban
engagement_mode: "structured"    # structured (default) or interactive

agents:
  default_backend: "claude"      # claude only in this build

Key decision — engagement mode: structured uses Opus for strategic roles (PO, SA, CE, RA) and Sonnet for executors (SE, QE, PE, TW, CR) — agents decide and report without surfacing every choice. interactive uses the same model tiers but strategic roles surface all major decisions for your review before proceeding — no cost premium, just more visibility. Use structured for most sprint work; switch to interactive for Release or regulated-industry builds. See Engagement Modes for a scenario guide.

Ticket tracker (optional)

By default, synaptory uses a local JSON tracker -- zero external dependencies. If your team uses GitHub Issues, Jira Cloud, or Teamwork, add a tracker section:

tracker:
  backend: github              # or: local (default), jira, teamwork
  github:
    repo: your-org/your-repo

GitHub requires gh CLI authenticated (gh auth login). Jira requires JIRA_API_TOKEN and JIRA_USER_EMAIL env vars. Teamwork requires TEAMWORK_API_KEY env var.


Step 4 -- Your first delivery run

Just describe what you want to build:

Build me a SaaS for managing restaurant reservations with a React frontend and Node.js backend

What happens next:

  1. Classification -- the orchestrator identifies this as a Build (Scrum lifecycle)
  2. Engagement mode -- Autonomous (cost-optimized) or Controlled (maximum visibility)
  3. Inception -- Project Owner defines vision and Sprint 1 stories. Solution Architect creates foundation ADRs. Platform Engineer bootstraps CI/CD.
  4. Inception Gate -- you review the project direction and approve
  5. Sprint 1 -- stories flow through the per-story pipeline: SE implements -> QE tests -> CR reviews -> DoD evaluation
  6. Sprint Review -- demo working software, capture feedback, sprint metrics
  7. Sprint 2+ -- ceremonies repeat with adaptive intensity
  8. Release -- when ready, full verification at maximum depth

From first prompt to working increment, you made one strategic decision (Inception Gate). The agents made hundreds.

Quick path chooser

Use these starting prompts when you want to land a specific mode directly:

GoalPromptExpected path
Greenfield product buildBuild me a SaaS for managing restaurant reservationsBuild -> Scrum lifecycle
Brownfield reverse-engineeringUnderstand this codebase and prepare a delivery planDiscover
Brownfield maintenanceWork on TICKET-142 to fix checkout retriesKanban
Focused story executionImplement US-037Story Buddy
Root-cause analysisDebug why login returns 500 in stagingDebug
Production readinessRun Release readiness for this projectRelease

End-to-end examples

Example 1 -- Greenfield Scrum run

  1. initialize my project
  2. Build me a SaaS for managing restaurant reservations
  3. Review the Inception Gate output and approve Sprint 1
  4. Let stories flow through SE -> QE -> CR -> DoD
  5. Continue with next sprint until ready
  6. Trigger release

Example 2 -- Brownfield Kanban run

  1. initialize my project
  2. Understand this codebase and prepare a delivery plan
  3. Choose Kanban after Discover
  4. Work on TICKET-142 to fix checkout retries
  5. Review the completed ticket and DoD evidence
  6. Trigger release when you want a production shipment

Runtime artifacts to expect

synaptory writes working state into .synaptory/.orchestrator/:

  • pipeline-state.json -- current lifecycle state, stories, metrics
  • receipts/ -- per-story or per-ticket evidence from each agent
  • context-packages/ -- Discover outputs for brownfield projects
  • last-session.md -- session snapshot for resume
  • tracker-data.json -- local tracker state when using the local backend

These files are useful when resuming work, auditing a run, or troubleshooting.

Parallel story execution

synaptory can dispatch up to parallelism.max_concurrent_subagents (default: 3) agent tasks simultaneously. The orchestrator manages the pipeline so QE can verify one story while SE implements the next.

If a subagent times out or fails, the orchestrator retries up to resilience.story_retry_cap times (default: 2) before marking the story blocked. Reduce story size if retries happen repeatedly.


Reading paths by role

Everyone should start with Delivery Lifecycle and Engagement Modes for shared vocabulary. Then follow the path for your primary role.

PM / BA -- Requirements and delivery strategy

  • Scrum Delivery -- Sprint Planning, Review, and your role in each ceremony
  • Agents -- Project Owner behavior and authority boundaries
  • Configuration -- build_mode, tracker, and sprint settings

Dev -- Implementation and architecture

  • Modes -- Debug, Story Buddy, Branch Finish, Preview, and other modes you use daily
  • Agents -- Software Engineer modes, tech packs, Code Reviewer boundaries
  • Kanban Delivery -- Working with existing codebases
  • Resuming Sessions -- Cross-session persistence

QE -- Verification and quality

  • Enforcement -- Receipts, DoD evaluation, safety nets
  • Agents -- Quality Engineer modes, Compliance Engineer, Code Reviewer
  • Kanban Delivery -- Coverage ratchet protocol
  • Hooks -- Verification hooks and enforcement behavior

What's next?

Start · 03

Install the synaptory CLI

The synaptory CLI handles sign-in, session state, and encrypted-skill delivery. Install it once per laptop — the same install works across every synaptory project you're a member of (the same way gh or aws work).

The CLI is shipped separately from the Claude Code plugin. Installing the plugin no longer carries the binary; the marketplace publishes a download script that detects your OS / architecture, verifies SHA-256, and drops the binary onto your $PATH.


macOS / Linux

curl -fsSL https://synaptory.h3t.co/cli/install.sh | bash

That's it. The script:

  • Detects darwin-arm64, darwin-amd64, linux-amd64, or linux-arm64.
  • Downloads the binary and sha256sums.txt from the marketplace's cli/latest/.
  • Verifies the SHA-256 before installing.
  • Installs to ~/.local/bin/synaptory.
  • Tells you the line to add to ~/.zshrc / ~/.bashrc if ~/.local/bin isn't on your $PATH.

After install:

synaptory version           # confirm the CLI is on PATH
synaptory login             # sign in via Entra (browser opens)

The login step prints the projects you can see right after sign-in, so you'll know immediately whether the operator has provisioned you correctly.

Custom install location

Set SYNAPTORY_CLI_PREFIX if ~/.local isn't where you want it:

SYNAPTORY_CLI_PREFIX=$HOME/Tools curl -fsSL .../cli/install.sh | bash
# installs to $HOME/Tools/bin/synaptory

Updating the CLI

Re-run the same one-liner. The script is idempotent and overwrites with the latest version.

Uninstall

rm ~/.local/bin/synaptory
synaptory logout            # if you want the keychain cleared first

Windows

iwr -useb https://synaptory.h3t.co/cli/install.ps1 | iex

The script:

  • Detects amd64 (the only Windows build we publish).
  • Downloads synaptory-windows-amd64.exe and sha256sums.txt from the marketplace's cli/latest/.
  • Verifies the SHA-256.
  • Installs to %USERPROFILE%\bin\synaptory.exe.
  • Adds %USERPROFILE%\bin to your user PATH if it isn't already (no admin needed; survives reboot).

If the script added a directory to PATH, open a new PowerShell window so the updated PATH is loaded. Then:

synaptory version
synaptory login

Updating

Re-run the same one-liner.

Uninstall

Remove-Item "$env:USERPROFILE\bin\synaptory.exe"
synaptory logout            # not strictly required; the keychain entry is harmless

Commands every user should know

These are the commands you'll run directly. Hooks call the rest for you.

CommandWhat it does
synaptory loginOpen a browser, sign in via Entra. Session is cached in the OS keychain. No --project flag — one sign-in covers every project you're a member of.
synaptory whoamiPrint the cached UPN and session expiry. First check when something feels wrong.
synaptory projects listList the projects you can see, with your role in each. Calls /v1/me/projects.
synaptory statusFull diagnostic — control-plane URL, session state, skill cache, outbox depth.
synaptory logoutClear the cached session. Next Claude Code session will prompt you to sign in again.
synaptory versionPrint the CLI version. Useful when reporting issues.

Less common, but good to know

CommandWhen to use it
synaptory skills listSee which skills are in your local cache.
synaptory outbox flushManually flush queued telemetry if the control plane was unreachable. Normally automatic on session start.
synaptory projects currentPrint the project slug resolved from .synaptory.yaml / SYNAPTORY_PROJECT_ID.

Switching projects

You don't. The same session works across every project you're a member of. The CLI auto-detects which project you're in by walking up from your current directory looking for .synaptory.yaml:

# .synaptory.yaml
project_id: taskflow-pilot

Telemetry and skill fetches stamp that slug onto requests. The server checks your membership against project_members per request — if you've been removed from a project, the next call returns 403 and the CLI quarantines the event for the operator to review.


What happens behind the scenes

You won't run these commands — Claude Code's session-start hooks call them for you:

  1. synaptory-access-token-check.sh runs synaptory login --if-needed. If your cached session is still valid (or refreshable via the cached refresh token) it's a no-op; otherwise the hook surfaces the install instructions and pauses the session.
  2. synaptory-skills-fetch.sh runs synaptory skills sync to pull the encrypted skill bundle for this project.
  3. synaptory-load-rules.sh decrypts the rules for this session.
  4. synaptory-session-start.sh runs synaptory outbox flush and synaptory telemetry session-start.

If any of those fail, you'll see a clear error message pointing at the fix.


Troubleshooting

SymptomFix
command not found: synaptoryThe install dir isn't on $PATH. Rerun the install one-liner; it prints the line to add to your shell rc.
synaptory: control plane URL not configuredThe CLI binary you installed was built without SYNAPTORY_CP_URL stamped in. Ask your H3Tech operator for a rebuilt binary.
synaptory: Entra OAuth is not configuredSame operator-side issue — the Entra tenant/client IDs weren't stamped at build time.
login: you are not a member of any project yetYour sign-in worked but the operator hasn't added your UPN to any project. Email ops@h3t.co with your UPN.
403 user is not an active member of project '<slug>' mid-sessionEither you've been removed from the project, or the slug in .synaptory.yaml is wrong. Run synaptory projects list to see what you can access.
Session expired mid-workRun synaptory login again. No --project flag, no Claude Code restart needed.
macOS Gatekeeper blocks the binaryRun xattr -d com.apple.quarantine ~/.local/bin/synaptory. The binary is unsigned for the pilot; production builds will be notarized.

For anything else, run synaptory status and include the output when you report the issue to ops.

Concepts · 04

The Synaptory Platform

Where the plugin sits, and what runs around it.

The Claude Code plugin you installed is one component of a larger system. Identity, skill delivery, telemetry, audit, and the marketplace itself live on a control plane operated by your H3Tech operator. This page explains how the parts fit together so the rest of the user guide makes sense in context.

If you only care about using the plugin, skip this and read Getting Started. Come back when you want to understand auth flows, where your data goes, or what "skill cache" means.


Why a platform, not just a plugin

A plugin alone can't enforce three things synaptory depends on:

  1. Per-user, per-project access — a single Claude Code install must work across multiple projects with different membership rules, without bundling credentials into the plugin.
  2. Watermarked skill delivery — the prompts and protocols that drive the agents are H3Tech IP. They're delivered at runtime against your authenticated session, not shipped as plaintext on disk.
  3. Audit and telemetry — every agent run produces a receipt; every receipt and token usage event lands in a place an operator can query.

So the plugin is intentionally thin. It registers hooks, defines agent stubs, and shells out to a separate Go CLI (synaptory) for everything that requires a session, a key, or the network.


Component map

flowchart LR
  subgraph Laptop["Your laptop"]
    CC["Claude Code"]
    Plugin["synaptory plugin<br/>(hooks, agent stubs)"]
    CLI["synaptory CLI<br/>(Go binary)"]
    Cache[("OS keychain<br/>+ skill cache")]
    CC --- Plugin
    Plugin -.shells out.-> CLI
    CLI --- Cache
  end

  subgraph CP["Control plane — synaptory.h3t.co"]
    API["FastAPI"]
    DB[("Postgres")]
    Web["Web<br/>(Control Plane)"]
    MP["Marketplace<br/>(/marketplace.git)"]
    Bin["CLI binaries<br/>(/cli/...)"]
    API --- DB
    Web --- API
  end

  CLI <-.HTTPS.-> API
  CLI <-.HTTPS.-> Bin
  CC <-.git smart-HTTP.-> MP
ComponentLives onWhat it does
Claude Code pluginYour laptopRegisters hooks, defines the 9 agent stubs, ships the /synaptory skill that classifies your request into a mode. Contains no IP-sensitive prompt bodies.
synaptory CLIYour laptop (one install)Authenticates against Entra, caches the session in your OS keychain, fetches skill bodies on demand, queues telemetry, runs doctor and status diagnostics.
Control-plane API (FastAPI)synaptory.h3t.co/v1/*Auth exchange, project membership checks, signed config delivery, watermarked skill delivery, telemetry ingest.
Control Plane (Next.js)synaptory.h3t.co/Single role-aware web app for every signed-in user (ADR-019). Pages auto-scope to the caller's grants — global admins see everything, project admins see their projects with cross-UPN visibility, project members see their own UPN within member projects.
Marketplacesynaptory.h3t.co/marketplace.gitA self-hosted git endpoint. /plugin marketplace add reads from here.
CLI downloadsynaptory.h3t.co/cli/install.{sh,ps1}Install scripts and signed binaries. Resolved by latest.json.

The control plane is operated by your H3Tech administrator. The marketplace and CLI hosts are static, served by Caddy; the API and Web run on a single Azure VM behind the same Caddy.


How auth works

synaptory login           # opens browser → Entra OAuth (PKCE)
   ↓
SYNAPTORY1 token minted by FastAPI, signed Ed25519, audience-scoped to the Entra app
   ↓
Cached in your OS keychain (macOS Keychain / Windows Credential Manager / libsecret)
   ↓
Plugin hooks shell out to `synaptory` CLI; CLI reads the cached token
   ↓
Every request to the control plane carries the token; server checks project_members per call

There is no master password and there is no token bundled in the plugin distribution. If a token expires (~24h), the CLI silently refreshes it; if refresh fails, the next hook surfaces a one-line prompt to re-run synaptory login.

For headless servers and CI, run synaptory login --device once — same end state, different code path.

Project membership is checked per request, server-side, against the project_members table. The SYNAPTORY1 token only proves who you are, not what you can see — that's why a single laptop install works across every project you're a member of (the gh / aws model).


How a request travels through the stack

A typical /synaptory "build me a SaaS" invocation:

  1. SessionStart hooks fire (only on cold start / /clear / compact):
  • synaptory-access-token-check.sh validates the cached session via the CLI.
  • synaptory-skills-fetch.sh syncs the skill manifest; missing or stale bodies are pulled live and cached.
  • synaptory-config-fetch.sh refreshes the policy cache.
  • synaptory-load-rules.sh injects the 10 behavioural rules.
  1. Orchestrator classifies the request using plugin/skills/synaptory/routing-rules.json and dispatches an agent.
  2. SubagentStart firessynaptory-inject-protocols.sh pulls every shared protocol body for the target role from the cache (or live from the control plane on cache miss). Each body is watermarked per-UPN before delivery — there's an <!-- synaptory-id: ... --> comment on the first line and a steganographic zero-width pattern through the body. Both are deterministic per user and survive copy-paste.
  3. The agent runs, writing a receipt to .synaptory/.orchestrator/receipts/<story-id>-<role>.json.
  4. SubagentStop firessynaptory-verify-receipt.sh validates the receipt JSON and re-runs the verification commands listed in the receipt. In Structured mode, a missing or failing receipt blocks the pipeline; in Interactive mode, it warns.
  5. Telemetry queues — token usage, model identity, durations, fallbacks. The CLI's outbox flushes these to the control plane in the background (or synaptory outbox flush manually).
  6. Stop firessynaptory-pipeline-snapshot.sh writes a resume snapshot to .synaptory/.orchestrator/last-session.md.

Skill bodies are never written to plaintext disk. The cache is per-user and bound to the cached session.


What ships in the marketplace vs what stays on the control plane

The marketplace tree (/marketplace.git) ships stubs and plumbing only:

  • Agent stubs (agents/<name>/agent.md) and SKILL frontmatter
  • Hook scripts (hooks/*.sh) and Python helpers
  • The orchestrator skill, modes, ceremonies (these are user-facing, intentionally readable)
  • Routing rules (routing-rules.json)
  • Configuration templates

What stays on the control plane and is delivered watermarked at runtime:

  • Shared protocols (skills/_shared/protocols/*.md)
  • Behavioural rules (rules/*.md)
  • Templates and design assets
  • Backend wrappers and prompt translators

Pulling the marketplace tree by hand gives you a working scaffold but no agent prompts. Without an authenticated CLI session against the control plane, the plugin will fetch nothing and the orchestrator will surface a clear "session required" message.


What you see on the web

You'll touch the Control Plane rarely; it's not part of the in-IDE workflow.

synaptory.h3t.co/ is one app for every signed-in synaptory-users member. The same pages render for everyone; the data and controls auto-scope:

  • As a project member, you'll mostly visit /sessions to revoke a stale session, /audit to see your own receipts, and /skills to confirm what you've used.
  • As a project admin, you also use /projects/<slug> to invite or revoke members, and the analytics pages (/cost, /quality, /reliability, /people) for your project's outcomes.
  • As a global admin, every page is unrestricted: project provisioning, system health, Grafana, audit across all UPNs.

The web app uses the same Entra sign-in your CLI uses. Sign in once at the CLI; the cookie path is independent.


What's next

  • Getting Started — install the plugin and CLI, sign in, run your first delivery.
  • Architecture — deeper view: per-URL routing, request sequences, where every artifact lives.
  • Identity and Access — Entra OAuth, groups, project membership, the local-auth fallback.
  • Personas — six roles that touch the platform and where each starts.
  • v3.0 Roadmap — what's next: spec graph, four-gate model, evidence ledger.
  • Using the Control Plane — the web surface.
  • Hooks — every hook script, when it fires, what it blocks on.
  • Routing — every mode the orchestrator can dispatch and the tiebreakers between them.
  • Rules — the 10 behavioural rules auto-injected at session start.
  • Commands — the synaptory CLI surface and the slash-command modes.
Concepts · 05

Platform Architecture

A deeper view than Platform — the wires between every surface.

Platform covers the component map and why the platform exists. This page goes one layer down: how requests traverse the stack, what every URL on synaptory.h3t.co maps to, and which artifacts live on which host.

Read this once if you operate the platform or you're integrating new tooling against it. Skip it if you're a delivery user — Platform is enough.


Surfaces, by URL

Every public URL is served by one Caddy instance on the prod VM. Three backends sit behind it:

URL patternServed bySource on prod VM
/, /home, /overview, /projects/*, /audit, /sessions, /activity, … (every Control Plane page)Next.js (web container)Built into the container image
/auth/*, /api/web/*Next.js (web container)Built into the container image
/v1/*FastAPI (api container)api/ Python package
/marketplace, /get-startedStatic HTMLweb/static/ (mounted at /srv/web-static)
/marketplace.git/*git-http-backend (FastCGI)/mnt/pgdata/git/marketplace.git
/cli/*Static files/mnt/pgdata/web-dist/cli/
/docs/*Static files/mnt/pgdata/web-dist/docs/
/downloads, /favicon.ico, etc.Static filesweb/static/

The complete list with example URLs is in reference/urls.md.


Cold-start request: a /synaptory invocation

platform.md gives the seven-step summary. Here is the same flow expanded so you can map it onto log lines and Grafana traces.

sequenceDiagram
  participant User
  participant CC as Claude Code
  participant Plugin as synaptory plugin
  participant CLI as synaptory CLI
  participant API as FastAPI (control plane)
  participant DB as Postgres
  User->>CC: /synaptory "build me a SaaS"
  CC->>Plugin: SessionStart hook chain
  Plugin->>CLI: synaptory status
  CLI->>API: GET /v1/projects (SYNAPTORY1 token)
  API->>DB: SELECT project_members WHERE upn=...
  API-->>CLI: 200 + groups + memberships
  CLI-->>Plugin: ok / token-expired
  Plugin->>CLI: synaptory skills sync
  CLI->>API: GET /v1/skills/manifest
  API-->>CLI: signed manifest
  CLI->>API: GET /v1/skills/protocols/receipt-protocol (cache-miss)
  API-->>CLI: watermarked body
  Plugin->>CC: orchestrator classifies → SubagentStart
  CC->>Plugin: SubagentStop with receipt
  Plugin->>CLI: synaptory telemetry queue
  CLI->>API: POST /v1/ingest (background, batched)
  API->>DB: INSERT receipt + token_usage

The two cache layers worth knowing about:

  • OS keychain holds the SYNAPTORY1 token (security find-generic-password -s synaptory on macOS).
  • Skill cache holds watermarked bodies, gated by token validity. Wiped on synaptory logout.

What runs where

ProcessContainerImage sourceRestart policy
CaddycaddyStock caddy:2-alpine + custom Caddyfilealways
Next.js (Control Plane)webBuilt from web/Dockerfilealways
FastAPIapiBuilt from api/Dockerfilealways
Postgres 16postgresStock postgres:16always
GrafanagrafanaStock grafana/grafanaalways
Nightly pg_dumpbackupBuilt from infra/docker/Dockerfile.backupunless-stopped
git-http-backendgit-httpBuilt from infra/docker/Dockerfile.git-httpalways

Local dev adds a fixture-idp container that mints SYNAPTORY1 tokens at /dev/mint so tests don't hit Entra. Local addition only — never enabled in prod.

Compose project name is synaptory (declared via name: directive). If you see orphan containers from earlier project names, docker compose -p <old-name> down cleans them up.


How an artifact gets to a user

Three artifacts ship outside the API. Each takes a slightly different path:

Plugin marketplace (the agent stubs and hooks)

release.yml on self-hosted runner (on prod VM)
  → ./synaptory build --publish-prod-fs
  → rsync into /mnt/pgdata/git/marketplace-worktree/
  → git commit + push to file:///mnt/pgdata/git/marketplace.git
  → Caddy proxies /marketplace.git/* to git-http container (FastCGI to git-http-backend)
  → user runs `/plugin marketplace add https://synaptory.h3t.co/marketplace.git`

CLI binaries

release.yml on self-hosted runner
  → ./synaptory release cli (cross-compile 5 OS/arch)
  → ./synaptory release cli --publish-prod-fs
  → cp into /mnt/pgdata/web-dist/cli/<version>/
  → Caddy serves /cli/* from /srv/web-dist
  → user runs install script → fetches /cli/latest.json → fetches the matching binary

Single-page user guide HTML (this guide)

release.yml on self-hosted runner
  → ./synaptory build (already runs build_user_guide.py as a side-effect)
  → ./synaptory build --publish-prod-fs (also copies web/dist/docs/user-guide.html → /mnt/pgdata/web-dist/docs/)
  → Caddy serves /docs/* from /srv/web-dist
  → user opens https://synaptory.h3t.co/docs/user-guide.html (or via the Control Plane "User Guide" link)

Every other artifact (skill bodies, signed config, telemetry receipts) is API-mediated — never touches the static-file path.


What's next

Concepts · 06

Identity and Access

Who you are (Entra), what group you belong to (synaptory-users / synaptory-admins), and what projects you can see (project_members).

synaptory has three identity questions, and each is answered in a different place:

QuestionAnswered byWhere it's checked
Who are you?Entra OAuth (UPN claim)At sign-in; baked into the SYNAPTORY1 token
Are you an admin?Entra group membership (grp claim)At sign-in; baked into the SYNAPTORY1 token
Can you see project X?project_members tablePer request, server-side, against the live DB

The first two are token-time — set at sign-in and immutable for the token's lifetime (~24h). The third is request-time — re-evaluated on every API call, so revoking access takes effect within seconds of the next request.


Sign-in (the normal path)

Three OAuth audiences exist, all backed by one Entra app registration (SYNAPTORY_CP_ENTRA_CLIENT_ID). The same app holds two platform sections in Azure: a Web platform with a client secret, and a Mobile/desktop platform for PKCE.

CallerFlowRedirect URI
Control Plane browserAuthorization-code with client_secrethttps://synaptory.h3t.co/auth/callback
synaptory CLIPKCE public clienthttp://127.0.0.1/auth/callback (loopback exception, random port)

After Entra issues an ID token, the API exchanges it for a SYNAPTORY1 token:

SYNAPTORY1.<base64url(payload)>.<base64url(ed25519_sig)>

Payload carries sid, upn, grp, iat, exp. There is no prj claim — that was the V1.5 design and was replaced. Project access is a per-request check against project_members, not a token claim.

The Ed25519 signing key lives on disk in dev (settings.signing_key_path) and in Azure Key Vault in prod (kty OKP, curve Ed25519, loaded by api/synaptoryapi/tokens.py KeyVaultSigner). The public key is exposed at GET /v1/public-key so the CLI can verify signed config offline.


Groups: synaptory-users vs synaptory-admins

Two Entra groups gate the platform:

  • synaptory-users — every member of either group. If you don't have this, the API returns 401 at sign-in.
  • synaptory-admins — superset role. Grants access to the legacy /console/* (now retired) and every /v1/admin/* endpoint.

The grp claim is a list, so admins carry both. ADR-019 retired the /console/* and /portal/* URL trees; every page lives at root URLs now, and admin-only entries are hidden from the sidebar (and gated server-side) for callers without synaptory-admins.

Group membership changes in Entra propagate at the next sign-in — the existing token's grp claim is frozen until expiry.


Project membership

Identity tells the API who you are; the project_members table tells it what you can see. Every project-scoped endpoint calls check_project_membership(db, claims.upn, project_id) (see api/synaptoryapi/security.py) which returns:

OutcomeStatusReason
Project doesn't exist404(anti-leak — no row existence disclosure)
Project archived403Archived projects are read-locked
User not a member404Returned as 404, not 403 — anti-enumeration
User membership revoked404Same as above
Active member200Proceed

The "not a member returns 404" pattern is deliberate. A 403 would let an attacker enumerate project slugs.

Membership is granted via ./synaptory api projects add-member <slug> <upn> (CLI on the prod VM) or via the project's Members tab in the Control Plane (project admins can self-serve).


Local-auth fallback

For dev and on-prem deployments where Entra isn't available, the API exposes POST /v1/auth/local. It accepts a UPN+password pair from SYNAPTORY_CP_LOCAL_*_PASSWORD env vars and mints the same SYNAPTORY1 token format.

FlagContainerDefaultPurpose
SYNAPTORY_CP_LOCAL_AUTH_ENABLEDapifalseEnables POST /v1/auth/local
SYNAPTORY_LOCAL_AUTH_ENABLEDwebfalseRenders the password form on /auth/login

Both must be true for the flow to work end-to-end. The admin slot grants [synaptory-users, synaptory-admins]; the user slot grants [synaptory-users] only. Tokens minted via local-auth carry the same upn claim format and are indistinguishable from Entra-minted tokens once issued — the server treats them identically.

Never enable in deployments expected to use Entra. It's a back-door by design, intended for dev fixtures and disconnected on-prem.


Watermarking and IP delivery

Identity also determines watermarking. Every skill-body fetch (GET /v1/skills/<name>) is watermarked per-UPN before delivery:

  1. Visible HTML comment — the first line of every body is <!-- synaptory-id: {sha256-prefix} -->. Explicit deterrent; easily stripped.
  2. Steganographic zero-width Unicode pattern — inserted at positions seeded by a deterministic RNG keyed on the watermark hash. Survives comment stripping. Reproducible per-user on every fetch.

The watermarker lives at api/synaptoryapi/watermark.py and is applied by api/synaptoryapi/routers/skills.py. See ADR-016 for the IP-delivery model.


What's next

Concepts · 07

Personas

Five roles touch the platform. Each touches a different surface for different reasons.

This guide is written for everyone who interacts with synaptory, but the interesting part of the platform changes depending on which role you're playing. Use this page to find the entry points that matter to you.

What changed in v3.0. Through v2.5 the platform served two browser surfaces — /console/* for admins and /portal/* for everyone else. ADR-019 collapsed those into a single Control Plane app at root URLs (/, /home, /projects, /audit, /sessions, etc.) with role-gated sidebar entries and server-side scope filtering. Where this guide previously listed a "Portal user" and a "Console admin" as separate personas, the unified Control Plane treats them as different role grants on the same app.


1. Plugin user (delivery user)

You are: a developer or PM running /synaptory inside Claude Code to build, debug, or maintain a system.

You touch: the Claude Code plugin and the synaptory CLI on your laptop.

You don't usually touch: the Control Plane web app or anything on synaptory.h3t.co except via the plugin/CLI.

Start here:


2. Control Plane user

You are: any signed-in member of synaptory-users. Could be a developer, a stakeholder watching an in-flight project, a project admin, or a global admin — they all use the same web app.

You touch: https://synaptory.h3t.co in a browser. The same URLs (/home, /projects, /sessions, /audit, /skills, /profile) for everyone; the data you see is auto-scoped to what your role grants.

Your role determines what you see:

RoleWhere it comes fromWhat you see
global adminMember of synaptory-admins Entra groupEverything: every project, every receipt, every UPN, system health, Grafana, policy.
project adminproject_members.role = 'admin' for one or more projectsYour admin projects' analytics with cross-UPN visibility. Members tab on those projects shows invite/revoke/promote controls.
project memberproject_members.role = 'member'Your member projects' analytics filtered to your own UPN. Read-only on Members tab.
unaffiliatedSigned-in synaptory-users with no project membershipsYour identity, sessions, and the access-request workflow. Analytics return empty.

You can: view what your role allows, revoke your own sessions, sign out everywhere, and (in Phase 2b) request access to additional projects.

You can't: see another user's row — every endpoint that takes ?project=<slug> returns 404 (not 403) for projects you can't see, so existence isn't leakable.

Start here:


3. Project admin

You are: a Control Plane user plus you hold the admin role on at least one project.

You touch: the Members tab on /projects/[slug] for the projects you administer, plus the per-project drill-ins (Phase 2b: /projects/[slug]/{quality,cost,reliability}).

You can: invite new members to your project, revoke access, promote/demote project roles, view your project's analytics with cross-UPN visibility, approve / deny access requests other users submit against your project.

You can't: create or archive projects (that's global admin); see other admins' projects unless you're a member.

Start here:


4. Operator

You are: the person responsible for keeping the platform running. Often the same human as a global admin acting in a different capacity.

You touch: the prod VM directly via az ssh vm, the GitHub Actions workflows, Grafana, and the Control Plane's /system, /sessions, and /audit pages (admin-gated).

You can: deploy the platform, rotate secrets, run migrations, restore backups, ship plugin / CLI / user-guide releases via labelled commits.

Start here:

This user guide intentionally doesn't duplicate the operator runbook. We link out.


5. Platform developer

You are: working on synaptory itself — agents, hooks, the API, the Control Plane web app, the CLI, infra.

You touch: the source repo. Local dev stack via ./synaptory api up. The plugin via claude --plugin-dir ./plugin.

Start here:

This user guide isn't aimed at you. The module READMEs and ADRs are.


A note on agent roles vs. human personas

The nine agents (Project Owner, Solution Architect, Software Engineer, etc.) are not personas in this list — they're not humans. They're roles played by Claude under the orchestrator. See Agents for that vocabulary.

The Control Plane UI uses "Delivery Owner" as the human counterpart to the "Project Owner" agent. See reference/glossary.md.

Concepts · 08

The Adaptive Delivery Lifecycle

The Shift That Matters

Most AI coding tools make you faster at writing code. Synaptory changes what you are doing entirely.

Without synaptory: You describe what you want. Claude writes code files. You review, iterate, ask follow-up questions, manually wire things together, figure out tests, set up CI/CD, write docs. You are the project manager, the architect, the QA lead, the DevOps engineer -- all at once.

With synaptory: You describe what you want to build. Nine specialized agents -- Project Owner, Solution Architect, Software Engineer (with backend, frontend, AI/ML, and mobile modes), Code Reviewer, Compliance Engineer, Quality Engineer, Platform Engineer, Technical Writer (with docs and report modes), and Research Advisor -- coordinate through an adaptive delivery lifecycle to produce a complete system: architecture decisions, tested backend and frontend, security audit, infrastructure, sprint reports, and documentation. You sit in the strategist's seat. You approve direction. You do not direct labor.

The system is built on one principle: do the work, don't describe the work. When a decision has a clearly superior option, agents take it and report what they chose and why. They don't ask. When a task can be done now, it's done now. Results are reported, not plans.

Quality Through Continuous Verification

synaptory replaces traditional checkpoints with a two-layer quality model: one human gate at project start, and continuous automated verification on every story.

Inception Gate

At the end of Inception (Sprint 0), you review and approve the project direction before any sprint begins:

Vision ✓ | Epics {N} | Sprint 1 {N} stories ready | Architecture {N} ADRs | CI/CD ✓ | Tests ✓

Options: Approve | Show details | I have concerns | Chat

This is the only human approval gate. It checks that the direction is right -- not that the entire design is locked. Architecture evolves incrementally as the project matures.

Per-Story Definition of Done

Every story is verified as it completes the SE->QE->CR pipeline. These checks are automated and continuous -- no waiting for a "quality gate" at the end.

v3 vocabulary: in the Control Plane UI the per-story DoD is rendered as the Evidence / DoD gate — one of four spec gates (Inception, Spec Ready, Evidence/DoD, Release). The underlying signals (tests pass, no critical findings, code reviewed, coverage non-decreasing, build green) are unchanged; the framing moves from "agent says done" to "evidence proves done." Receipts and pipeline behaviour described below continue to use the DoD wording.

CheckSeverityWhat it verifies
Tests passCriticalAll acceptance criteria tests for this story pass
Build succeedsCriticalBuild completes and dev server starts
No critical findingsCriticalZero Critical security findings (Compliance Engineer)
Code reviewedAdaptiveStory code reviewed (Code Reviewer) -- skips Sprint 1, enables Sprint 2+
Coverage no decreaseNon-criticalTest coverage did not decrease

Sprint-Level Overlay (Scrum only)

At Sprint Review, a second layer of checks verifies the sprint as a whole:

CheckTypeWhat it verifies
Sprint Goal metHumanDid the sprint deliver on its stated goal?
Feedback addressedHumanWas stakeholder feedback from prior sprints incorporated?
No regressionAutoNo regression across all sprint stories
Documentation updatedHumanWere docs updated for changed features?

This two-layer model means quality is verified continuously at the story level, with a human sanity check at sprint boundaries. Problems are caught when they are cheap to fix -- not at the end.

Three Operation Layers

synaptory classifies every request into one of three layers. You don't need to specify which -- just describe what you need, and the orchestrator routes automatically.

Layer 1: Scrum Lifecycle (time-boxed delivery)

For greenfield projects and brownfield projects that need structured iteration:

Inception --> Sprint Planning --> Sprint Execution --> Sprint Review
                                                          |
                Sprint Close <-- Sprint Retro (adaptive) <-+
                    |
                    +--> Next Sprint (loop) or Release --> Complete

Inception establishes just enough foundation to start building: a mini-BRD, Sprint 1 stories, foundation architecture decisions (ADRs), CI/CD bootstrap, and test framework setup. The Project Owner defines vision and decomposes Sprint 1 stories. The Solution Architect creates foundation ADRs. The Platform Engineer bootstraps CI/CD and Docker. The Quality Engineer sets up the test framework.

Sprint Planning happens every sprint. The Project Owner refines stories, the Solution Architect reviews if architecture signals are detected in story text, the team selects stories, and a Sprint Goal is set. Planning intensity is adaptive -- lightweight when the backlog is stable, full when new feedback arrives.

Sprint Execution runs the per-story pipeline for each story in the sprint backlog. Stories move through SE->QE->CR with per-story DoD evaluation. Infrastructure stories run in parallel via the Platform Engineer.

Sprint Review deploys the increment to preview (auto-detected for web apps), generates sprint reports via the Technical Writer, demos working software, evaluates the sprint-level DoD overlay, and captures stakeholder feedback.

Sprint Retro is adaptive -- it only runs when the sprint had issues (low completion, blocks, regressions). When it runs, it analyzes metrics, identifies improvements, and feeds suggestions forward to the next sprint's planning.

Sprint Close always runs. It handles carry-over of incomplete stories, records sprint metrics, and presents the next decision: continue to the next sprint, or release.

Release is on-demand -- triggered when you decide to ship. Full regression testing, security audit, production infrastructure, documentation, and a release readiness check.

Layer 2: Kanban Lifecycle (continuous ticket flow)

For brownfield projects in maintenance or post-launch evolution:

Discover --> Ready --> Execute ticket --> Review --> Ready (loop)
                                                      |
                                                      +--> Release (on-demand)

Discover reverse-engineers the existing codebase and builds context packages (dependency map, interface contracts, business rules, data dictionary, risk register, health assessment, UI contracts).

Ready waits for the next ticket -- either user-specified ("fix TICKET-123") or auto-pulled from the tracker (highest priority ready ticket, user confirms).

Execute runs the same per-story SE->QE->CR pipeline as Scrum, with per-ticket DoD evaluation.

Review demos the completed ticket, captures feedback, and returns to Ready for the next ticket.

Release is available on-demand anytime -- same full verification as Scrum release.

Layer 3: Standalone Utilities (no lifecycle required)

For scoped tasks that don't need a delivery lifecycle:

UtilityWhat it does
Debug4-phase root-cause analysis: Reproduce -> Isolate -> Understand -> Fix
ExploreResearch Advisor thinking partner -- ideation, domain research
DiscoverReverse-engineer existing codebase, build context packages
PreviewLaunch dev server, smoke test running application
Branch FinishPer-branch verification, PR creation, merge
Story BuddyPer-story assistance -- requirements, implement, test, sprint plan
RetroStandalone engineering retrospective with git and receipt analysis
InitProject detection, .synaptory.yaml generation
StatusSprint/Kanban state dashboard
HelpQuick reference card

These utilities work independently of the Scrum or Kanban lifecycle. "Review my code" routes to the Code Reviewer. "Debug this error" runs Debug mode. No ceremony context needed.

The Story Pipeline

Every story -- whether in a Scrum sprint or a Kanban ticket -- flows through the same per-story pipeline:

queued --> in_progress (SE) --> testing (QE) --> reviewing (CR) --> done
                                                                    |
                                                              (or blocked)
  1. SE picks the highest-priority story and implements it (code + unit tests)
  2. Hands off to QE immediately -- no waiting for all stories to be built first
  3. QE tests -- acceptance criteria tests, integration tests
  4. CR reviews (if DoD requires it -- adaptive, enabled Sprint 2+)
  5. Per-story DoD evaluated -- tests pass, build succeeds, no critical findings
  6. Concurrent dispatch: up to 3 agents run simultaneously (configurable via parallelism.max_concurrent_subagents)

This is the core difference from traditional AI pipelines: quality verification happens per story, not at the end. Problems are caught within hours of being introduced, not days later.

Adaptive Intensity

DoD checks, ceremony depth, and agent involvement all scale with project maturity:

MaturityWhat's ActiveWhy
Early (Sprint 1 or first 5 Kanban tickets)Critical DoD only: tests, build, no critical findingsMinimal code to review or audit
Growing (Sprint 2-3 or tickets 6-15)+ Code review enabledGrowing codebase needs review
Mature (Sprint 4+ or tickets 16+)+ Full security auditEnough surface area for meaningful assessment
ReleaseAll checks at maximum depthProduction readiness

This prevents ceremony overhead from slowing down early sprints when there is barely any code to review, while ensuring mature codebases get the scrutiny they need.

Progressive Elaboration

synaptory does not try to plan everything upfront. Requirements are elaborated progressively:

  • At Inception: Project Owner decomposes Sprint 1 stories only (foundation mode) or Sprint 1-2 (blueprint mode). Remaining epics exist as high-level placeholders.
  • At Sprint Planning: Project Owner refines stories for this sprint, incorporating feedback from prior sprints and retro insights.
  • Architecture evolves: Solution Architect is auto-triggered when story text contains architecture signals (new entity, new service, new integration, security requirement). No upfront architecture lock.
  • Architecture health checks: Every 3 sprints (configurable), the Solution Architect reviews the architecture for drift.

The result: early sprints focus on building. Later sprints benefit from accumulated learning. Architecture adapts to what the code actually needs, not what was guessed upfront.


What's next?

  • Scrum Delivery -- Step-by-step walkthrough of the complete Scrum lifecycle
  • Kanban Delivery -- Continuous ticket-based delivery for existing codebases
  • Engagement Modes -- How to control agent autonomy vs. visibility
  • Modes -- All operation modes and how the orchestrator classifies your requests
Concepts · 09

Operation Modes

The orchestrator classifies every request automatically into an operation mode. You do not need to specify a mode -- just describe what you want. Classification uses keyword matching, intent patterns, and project context to route your request to the right agents with the right scope.

Modes are organized into three operation layers: lifecycle modes that drive structured delivery, and standalone utilities for focused tasks. For the full machine-readable rules and tiebreakers, see Routing Reference.

Layer 1: Scrum Lifecycle

ModeTrigger SignalsWhat Happens
Build"build a SaaS", "production grade", "from scratch", "full stack", greenfield intentInception -> Sprint ceremony loop -> Release. Full adaptive delivery lifecycle.
Sprint"build sprint", "sprint N", "next sprint", "continue sprint", "resume sprint"Loads sprint state, routes to the correct ceremony (Planning, Execution, Review, Retro, Close).

Build is the most comprehensive mode. Describe what you want to build in plain language, and synaptory runs the complete Scrum lifecycle: Inception establishes the foundation, then sprint ceremonies iterate until you decide to release. See Scrum Delivery for the full walkthrough.

Sprint resumes an active Scrum project. The orchestrator reads the sprint state machine and routes to whichever ceremony is next -- no need to specify "planning" or "review" explicitly.

Layer 2: Kanban Lifecycle

ModeTrigger SignalsWhat Happens
Kanban"fix ticket", "work on TICKET-xxx", "pull next ticket", "maintenance mode"Discover -> Ready -> Execute ticket -> Review -> loop. Continuous ticket-based flow for brownfield projects.

Kanban mode is for post-launch maintenance and evolution. It runs the same per-story SE->QE->CR pipeline as Scrum, but without sprint ceremonies -- tickets flow continuously. See Kanban Delivery for details.

Layer 3: Standalone Modes

These modes work independently of any lifecycle. They group naturally into five families.

Diagnostics & Setup

Doctor -- Configuration Diagnostic

Trigger SignalsAgent
"doctor", "diagnose", "check config", "validate config", "is this correctly configured", "synaptory doctor"Orchestrator (read-only)

Read-only configuration validator. Checks .synaptory.yaml correctness, plugin settings, CLI auth, control-plane project membership, and v2.1 cruft. Produces a clear pass/warn/fail report with remediation guidance for every finding. Never modifies files without asking. Run it whenever a project is being migrated, after manual edits to .synaptory.yaml or .claude/settings.json, when a new team member sets up the plugin, or when something looks wrong. See Troubleshooting → Run Doctor first for the typical recipe.

Init -- Project Setup

Trigger SignalsAgent
"initialize", "configure project", "set up synaptory", "reconfigure"Orchestrator (init)

Scans the project, auto-detects language, framework, infrastructure, and architecture, then generates .synaptory.yaml and scaffolds tracker description templates into docs/templates/. Use Doctor to check a config; use Init to generate or replace one.

Status -- State Dashboard

Trigger SignalsAgent
"status", "progress", "dashboard", "where are we"Orchestrator (status)

Displays the current lifecycle state: sprint number, ceremony position, story pipeline status, agent backends, DoD compliance, and velocity metrics.

Help -- Quick Reference

Trigger SignalsAgent
"help", "commands", "what can you do"Orchestrator (help)

Prints a quick reference card with available modes and example prompts. Mostly useful during onboarding.

Report -- File a Plugin Issue

Trigger SignalsAgent
"report a bug", "report an issue", "synaptory bug"Orchestrator (report)

Gathers context (versions, config, state, recent errors) and files a GitHub issue against the synaptory repository. Use this when something is wrong with the plugin itself, not with your project's code.

Update -- Auto-Update Check

TriggerBehaviour
Runs silently before any other modeOrchestrator (Step 0)

Not user-invocable — it's a Step 0 that runs ahead of every other mode. Compares your installed plugin version against the latest in the marketplace. Stays silent if you're current; surfaces a single one-question prompt if a newer version is available; never blocks the pipeline if the version check fails (offline, timeout). Skip the update once and the rest of the request runs on your current version.

Per-Story Assistance (Story Buddy)

Trigger SignalsAgent
"analyze US-xxx", "implement story", "refine requirements", "help plan sprint", "test story"Role-specific (PO, SE, QE, or Orchestrator)

Focused assistance for a single story or ticket, integrated with the tracker. Story IDs in the request (e.g., US-042, TICKET-123) automatically route to Story Buddy. Four sub-roles:

  • Requirements -- Project Owner analyzes and refines a story's acceptance criteria
  • Implement -- Software Engineer implements a specific story
  • Test -- Quality Engineer writes tests for a specific story (diff-aware)
  • Sprint Plan -- Project Owner advisor: suggests story selection and capacity estimate. Does NOT create or modify stories unless asked.

Lightweight Single-Agent Modes

These modes run a single agent (occasionally two) with minimal orchestration overhead. Useful when you know exactly what you want and don't need a full pipeline.

Test -- Standalone Test Generation

Trigger SignalsAgent
"write tests", "test coverage", "test this", "add tests" (with no story ID)Quality Engineer

Generates tests for code that already works. Coverage-focused. With a story ID present, routes to Story Buddy — Test instead.

Review -- Standalone Code Review

Trigger SignalsAgent
"review my code", "code review", "code quality", "check my code"Code Reviewer

Read-only adversarial code quality analysis. Architecture conformance, SOLID/DRY/KISS, performance anti-patterns, test quality. Does NOT perform security review (that's Compliance Engineer). For security audit, use Verify or trigger Release readiness.

Architect -- Design and ADRs

Trigger SignalsAgent
"design", "architecture", "API design", "data model", "tech stack", "how should I structure"Solution Architect

Single-agent architecture work outside a sprint cycle. Produces ADRs, API contracts, ERDs, or migration plans. The Solution Architect's modernize mode also dispatches here when migration intent is detected (see Modernize below).

Document -- Documentation Generation

Trigger SignalsAgent
"document", "write docs", "API docs", "README"Technical Writer

Generates API references, developer guides, READMEs, or Docusaurus sites. Traces every statement back to a source artifact -- never invents.

Explore -- Thinking Partner

Trigger SignalsAgent
"explain", "understand", "help me think", "what should I", "I'm not sure"Research Advisor

The Research Advisor acts as a thinking partner for ideation, domain research, and decision-making. It does not write code -- it helps you think through problems.

Optimize -- Performance and Scale

Trigger SignalsAgents
"performance", "slow", "optimize", "scale" (without operational framing)Platform Engineer + Code Reviewer

Performance and scale work on existing code. Profiling, hotspot analysis, caching, query plans. If the request mentions SLOs, error budgets, chaos, runbooks, incidents, or on-call, the orchestrator routes to a reliability path on the Platform Engineer instead -- see the routing tiebreaker in Routing Reference.

Stabilize -- Pre-Refactor Safety Net

Trigger SignalsAgents
"add safety net", "characterization tests", "before refactoring", "establish baseline", "coverage ratchet"Quality Engineer + Code Reviewer

Adds characterization tests around code you're about to change. Establishes a coverage baseline that subsequent work cannot decrease (the coverage ratchet). Run this before a Modernize pass.

Modernize -- Migration Planning

Trigger SignalsAgents
"modernize", "migrate", "upgrade architecture", "strangler fig", "migration plan", "rewrite plan"Solution Architect + Compliance Engineer

Brownfield migration planning. The Solution Architect produces a phased migration plan (strangler fig patterns, quarterly roadmaps, ADRs); Compliance reviews the security/regulatory impact of the migration path. Pair with Stabilize first.

Custom -- Manual Skill Selection

Trigger SignalsAgent
Doesn't fit any pattern aboveUser selects from menu

Catch-all. The orchestrator presents a skill menu and lets you pick the agent and scope.

Brownfield Analysis

Discover -- Codebase Reverse-Engineering

Trigger SignalsAgent
"understand this codebase", "map the system", "reverse engineer", "what does this code do"Orchestrator (analysis)

Reverse-engineers an existing codebase and produces 7 context packages: dependency map, interface contracts, business rules inventory, data dictionary, risk register, health assessment, and UI contracts. These packages are loaded by all agents in subsequent work. Re-runnable -- detects what changed since the last run.

Context Refresh -- Incremental Re-Analysis

Trigger SignalsAgent
"update context", "refresh context", "re-analyze"Orchestrator (incremental)

Re-runs Discover incrementally, updating context packages for files that changed since the last analysis. Use after major code changes to keep context packages current.

Workflow Utilities

Debug -- Structured Root-Cause Analysis

Trigger SignalsAgents
"debug", "fix this bug", "not working", "broken", "error", "crash", "failing", "investigate", "root cause"Code Reviewer (diagnose) -> SE (fix) -> QE (regression test)

Debug mode uses a structured 4-phase protocol rather than ad-hoc troubleshooting:

  1. Reproduce -- Confirm the failure reliably. If the bug cannot be reproduced, the diagnosis is unreliable.
  2. Isolate -- git bisect strategy to pinpoint the regression. Binary search through the call chain to find the minimal reproducer.
  3. Understand -- 5 Whys root cause analysis. The causal chain is documented in .synaptory/debug/diagnosis.md.
  4. Fix & Verify -- SE applies the fix. QE writes a regression test. Both the original failure and the fix are verified with running code.

Preview -- Dev Server Launch

Trigger SignalsAgent
"preview", "run it", "start server", "launch", "dev server"Orchestrator (preview)

Launches the dev server, runs smoke tests against the running application, and reports the result. Auto-detects the correct start command for your framework.

Branch Finish -- Verification and Merge

Trigger SignalsAgent
"finish this branch", "merge", "create PR", "done with this branch", "ship this branch"Verify -> merge/PR/keep/discard

Runs per-branch verification (tests, lint, type check), then offers options: create a PR, merge directly, keep the branch, or discard.

Retro -- Engineering Retrospective

Trigger SignalsAgent
"retro", "retrospective", "what did we ship", "team metrics", "how are we doing"Orchestrator (analysis)

Standalone retrospective that analyzes git history, receipt data, and pipeline artifacts. In Scrum, integrated retros run automatically within the ceremony flow -- this mode is for on-demand analysis or Kanban projects.

Routing Conflicts

When a request matches multiple modes, the orchestrator applies tiebreakers. The complete list lives in Routing Reference; the most common ones:

ConflictResolutionWhy
"review" -> Code Review vs ReleaseCode Review if "my code / this code". Release if "before launch / audit / harden"Release implies full verification; Code Review is single-agent
"add tests" + "bug" -> Test vs DebugDebug if error/failure described. Story Buddy Test if code works and coverage is the goalDebug = active failure; Test = proactive quality
"implement" + story ID presentStory Buddy ImplementStory ID pattern = [A-Z]+-\d+ or US-\d+
"implement" + no story IDBuild (Inception -> Scrum lifecycle)No story ID = new feature from scratch
Story ID anywhere in requestStory Buddy (choose role from context)Story ID overrides other modes
"doctor" vs "init"Doctor if "check / validate / diagnose / is it configured correctly". Init if "initialize / set up / generate config"Doctor is read-only; Init writes
"optimize" vs "reliability"Reliability if SLO / error budget / chaos / runbook / incident / on-call. Optimize otherwiseReliability = operational; Optimize = code/infra perf
Multiple modes matchPick the most specific: Debug > Story Buddy, Release > Code Review, Sprint > BuildSpecificity beats generality

What's next?

Concepts · 10

The 9 Delivery Agents

synaptory orchestrates 9 specialized agents, each owning a distinct domain. The Orchestrator (always Claude) classifies your request and dispatches the right agents. All agents in this build run on Claude — Opus for strategic roles, Sonnet for execution roles.

Why Separate Roles?

A single AI doing everything is like one person writing the code, reviewing their own code, and auditing their own security. It cannot work: the builder has too much context invested in their choices to question them adversarially.

Each role in synaptory is architecturally separate because each role requires a distinct stance:

  • The Code Reviewer must assume the code is wrong and look for proof it works. It cannot be the same agent that built the code — the builder cannot review their own output.
  • The Compliance Engineer owns OWASP and STRIDE and never defers to the SE's judgment on security. Domain authority cannot be shared.
  • The Project Owner defines what to build. The Solution Architect decides how. When a requirement is technically infeasible, the Architect flags the contradiction — the PO cannot override it.

Role separation also enables parallelism: the orchestrator can dispatch up to parallelism.max_concurrent_subagents (default: 3) agent tasks concurrently.

Role Short Codes

The Control Plane UI and audit trail render agents with these two-letter codes (source of truth: web/src/lib/v3-vocab.ts):

CodeRole
POProject Owner
SASolution Architect
SESoftware Engineer
QEQuality Engineer
CRCode Reviewer
CECompliance Engineer
PEPlatform Engineer
TWTechnical Writer
RAResearch Advisor

Note on rename: Project Owner was called Product Manager in v2.x. The short code moved from PM to PO and the agent slug from product-manager to project-owner. The control plane still accepts product-manager as a server-side alias for in-flight receipts, but new code, docs, and tooling use the new names.

Agent Classification

Agents are classified by how and when they are invoked:

Core Crew (active every delivery cycle)

AgentDomainModes
Project OwnerBacklog refinement, Sprint Planning, story decompositionfeature, refinement
Software EngineerCode implementation -- one story at a timebackend (default), frontend, ai-ml, mobile
Quality EngineerPer-story testing -- unit, integration, e2e, performancedefault, diff-aware, browser-qa, exploratory, testability-review
Technical WriterSprint reports at Review, documentation at Releasedocs (default), report

On-Demand Specialists (auto-triggered)

AgentTriggerModes
Solution ArchitectStory text contains architecture signals (new entity, service, integration, security requirement)default, modernize
Compliance EngineerPer-story DoD security check, intensity scales with maturitydefault, healthcare (HIPAA/PHI), pentest (PTES 7-phase)
Code ReviewerPer-story DoD review check -- adaptive (skip Sprint 1, enable Sprint 2+)--

User-Invoked

AgentTriggerModes
Research AdvisorUser request or knowledge gapresearch, advise, ideate, synthesize, translate, onboard

Conditional Per Cycle

AgentTriggerModes
Platform EngineerInception bootstrap + infrastructure stories--

Claude Model Tiers

The Orchestrator selects a model tier for each agent based on task complexity. The active tier depends on engagement_mode:

AgentModelRationale
Project OwnerOpusMakes strategic decisions: story scope, sprint content, requirements
Solution ArchitectOpusMakes irreversible decisions: tech stack, ADRs, architecture patterns
Compliance EngineerOpusMakes risk-acceptance decisions: severity, OWASP findings, threat model
Research AdvisorOpusSynthesizes options and recommends direction
Software EngineerSonnetExecutes implementation contracts — follows ADRs and acceptance criteria
Quality EngineerSonnetExecutes test strategy against known acceptance criteria
Platform EngineerSonnetExecutes infrastructure specs — follows IaC patterns and ADRs
Technical WriterSonnetTraces artifacts to documentation — no invention, pure traceability
Code ReviewerSonnetAdversarial analysis requires judgment and reasoning — not mechanical pattern-matching

These tiers apply in both Structured and Interactive modes. The modes are identical in model cost. The difference is behavioral: in Interactive mode, strategic roles (PO, SA, CE, RA) surface major decisions for human review instead of deciding autonomously. Executor roles (SE, QE, PE, TW, CR) follow orchestrator direction in both modes and don't make autonomous decisions, so their tier doesn't change.

You cannot configure individual model tiers per role. The only lever is engagement_mode: structured | interactive in .synaptory.yaml.

Software Engineer Modes

The Software Engineer runs in one of four modes, selected automatically based on project signals:

  • Backend (default) -- Services, APIs, business logic. Builds shared foundations (libs/shared/) before spawning parallel service agents. In microservices, one SE instance runs per service.
  • Frontend -- React/Next.js components, design system, pages. Builds UI primitives first (Button, Input, Modal, etc.), then pages. Enforces the Dead Element Rule: any button, link, or form that renders but does nothing is a Critical bug, not a TODO.
  • AI/ML -- LLM optimization, agent framework design, data pipelines, cost modeling. Auto-detected from project signals. Skipped if not applicable.
  • Mobile -- React Native, Flutter, Swift, Kotlin. Auto-detected from project signals.

Multiple SE instances can run in parallel with different modes via worktree isolation.

Code Reviewer

Read-only adversarial code quality analysis. Architecturally separate from the Software Engineer -- the builder and the reviewer are distinct roles by design.

  • Tools restricted to Read, Grep, Glob only -- never modifies source code
  • Two-stage review: Stage 1 (Spec Compliance) verifies the code meets requirements. Stage 2 (Code Quality) runs architecture conformance, SOLID/DRY/KISS, performance anti-patterns, and test quality analysis
  • Adversarial stance -- assumes the code is wrong and looks for proof it works
  • Does NOT perform security review -- defers entirely to the Compliance Engineer
  • Adaptive invocation -- skips Sprint 1 (too little code to review), enables Sprint 2+ as the codebase grows
  • Per-story scope -- reviews each story as it completes the SE->QE pipeline, not all code at once

Software Engineer Tech Packs

After mode dispatch, the SE auto-loads technology-specific guidance based on project signals. Tech packs are additive -- a Next.js project with Tailwind and PostgreSQL loads three packs simultaneously.

Detection signalTech pack loaded
next.config.* or "next" in package.jsonnextjs.md
"react" in package.json (no Next.js)react.md
pyproject.toml with fastapipython-fastapi.md
go.modgo.md
tailwind.config.*tailwind.md
PostgreSQL in dependencies or docker-composepostgresql.md
@modelcontextprotocol/sdk in package.jsonmcp.md
Web app detectedperformance.md -- Core Web Vitals, bundle analysis, caching
Marketing/public-facing contentseo-geo.md -- SEO + GEO (Generative Engine Optimization)

Tech pack loading is automatic. No user configuration required.

Technical Writer Modes

  • Docs mode (default) -- API reference (from OpenAPI specs), developer guides, operational guides, architecture guides, contributing guides, Docusaurus sites. Invoked at Release. Every statement traces to a source artifact -- never invents information.
  • Report mode -- Sprint summary reports (PDF) generated at Sprint Review. Technical documentation PDFs from architecture markdown. Closed sprint reports are immutable -- only new reports can be generated for new sprints.

Project Owner Behavior

The Project Owner is active every sprint cycle, not just at project start:

  • At Inception: Defines project vision, decomposes Sprint 1 stories (foundation mode) or Sprint 1-2 (blueprint mode)
  • At Sprint Planning: Reads prior feedback and retro insights, refines stories for this sprint, updates acceptance criteria
  • Feature mode: Scoped requirements for adding a feature -- produces a focused BRD section rather than a full document
  • Refinement mode: Reworks requirements based on specific feedback from the Inception Gate (max 2 rework cycles)

Quality Engineer Modes

  • Default -- Full test strategy: unit, integration, e2e, performance, contract tests. Per-story testing as each story completes the SE pipeline.
  • Diff-aware -- Tests only changed files. Activated automatically on feature branches to minimize scope and cost.
  • Browser QA -- Visual testing, accessibility checks (WCAG), responsive layout verification. Activated for web frontend projects in Controlled mode.
  • Exploratory -- Session-based, charter-driven testing. Finds bugs that scripted tests miss.
  • Testability Review -- Identifies test gaps BEFORE the SE starts coding. Flags untestable designs early.

Compliance Engineer Modes

Default mode runs the standard compliance audit: OWASP Top 10, STRIDE threat modeling, dependency vulnerability scanning, regulatory compliance. Intensity scales with project maturity -- minimal at Sprint 1, full audit at Sprint 4+ and Release.

Healthcare mode activates when the task mentions HIPAA, PHI, healthcare, ePHI, or BAA. Adds PHI data flow analysis, BAA verification, HIPAA access controls, encryption verification, breach notification review, HITRUST CSF mapping.

Pentest mode activates in Controlled mode or when explicitly requested. Applies the PTES 7-phase methodology: Pre-Engagement, Intelligence Gathering, Threat Modeling, Vulnerability Analysis, Exploitation (PoC), Post-Exploitation Analysis, Reporting.

Solution Architect

The Solution Architect is auto-triggered -- the Orchestrator analyzes story text for architecture signals:

  • New database entity -> ERD update + migration ADR
  • New service or bounded context -> system design + ADR
  • New external API integration -> API contract + integration ADR
  • Auth/security requirement -> security architecture ADR
  • Performance-critical story -> NFR alignment review

No triggers detected -> SA is skipped for this sprint (most sprints).

Architecture health checks run every 3 sprints (configurable) to detect drift. The SA reviews the codebase against ADRs and flags divergence.

Modernize mode activates for brownfield codebases. Instead of designing from scratch, the Architect evaluates existing architecture and plans a migration path with strangler fig patterns and quarterly roadmaps.

Authority Boundaries

Each agent owns its domain completely. When two agents' domains touch, the conflict-resolution protocol defines who has authority:

  • Compliance Engineer vs. Code Reviewer: Compliance owns OWASP, STRIDE, PII, encryption. Code Reviewer owns architecture conformance, code quality, performance. The Code Reviewer does NOT do security review -- this boundary is absolute.
  • Platform Engineer: Sole authority on infrastructure AND reliability -- Docker, CI/CD, IaC, K8s, monitoring, SLOs, runbooks, chaos engineering.
  • Software Engineer vs. Code Reviewer: The SE builds. The Code Reviewer reviews. They are never the same agent instance. The SE cannot review its own code.
  • Project Owner vs. Solution Architect: The PO defines what to build. The Architect decides how to build it. When a requirement is technically infeasible, the Architect flags the contradiction.

What's next?

  • Delivery Lifecycle -- How agents coordinate through the adaptive delivery lifecycle
  • Engagement Modes -- How agent model routing and question depth vary by mode
  • Enforcement -- How receipts, DoD, and safety nets enforce agent quality
Concepts · 11

Engagement Modes

At the start of any multi-agent run, the orchestrator asks you to choose an engagement mode. This single choice propagates to all 9 agents and controls two things: how much agents surface to you versus decide autonomously, and which AI model tier each agent uses.

The 2 Modes

ModeModel RoutingAgent QuestionsUse When
StructuredOpus for strategic roles, Sonnet for executor rolesMinimal -- auto-resolve, report decisionsMost work -- speed and cost efficiency
InteractiveSame tiers as StructuredMajor decisions from PO, SA, CE, RA surfaced for reviewCompliance-sensitive, complex systems, full control

Important distinction: The Inception Gate (approve project direction) is always present regardless of mode. Engagement mode controls agent-level decision visibility and model quality, not lifecycle gates.

Aliases: autonomous and hands-off are accepted as aliases for structured. controlled and hands-on are accepted as aliases for interactive. New config should use the canonical names.

Structured Mode

Agents decide and report. The Project Owner derives requirements from your request with minimal questions. The Solution Architect auto-selects the tech stack and documents the rationale. Agents report what they decided rather than asking.

Model routing: Two tiers based on role type:

  • Opus for strategic/decision roles: Project Owner, Solution Architect, Compliance Engineer, Research Advisor
  • Sonnet for executor roles: Software Engineer, Quality Engineer, Platform Engineer, Technical Writer, Code Reviewer

Structured is ideal for most production work, prototypes, and domains where you trust the agents' defaults.

Interactive Mode

Maximum visibility and quality. The Project Owner asks more questions. The Solution Architect walks through ADRs. All major decisions are surfaced for your review.

Model routing: Same tiers as Structured — Opus for strategic roles, Sonnet for executor roles. No model cost premium over Structured.

Interactive is for production systems in regulated industries, compliance-sensitive builds, or situations where you need an audit trail of every decision. The cost difference vs. Structured is minimal — the distinction is visibility and human gate behavior, not model quality.

How Engagement Mode Affects Enforcement

The same quality checks run in both modes. The difference is what happens when a check fails:

BehaviorStructuredInteractive
Missing receiptHook exits 1 -- execution BLOCKEDWarning shown, execution proceeds for human review
Invalid receiptHook exits 1 -- execution BLOCKEDValidation report shown, user decides
Lifecycle state violationHook exits 1 -- execution BLOCKEDWarning shown, execution proceeds
Verification commands failHook exits 1 -- execution BLOCKEDAll results shown to user for review
PhilosophyTrust the automated safety netsTrust the human operator

Structured is ambitious: it assumes the system will produce correct work, and blocks hard when it doesn't. The safety nets are invisible when passing, painful when failing.

Interactive is honest: it acknowledges limitations and surfaces everything for human review. Nothing blocks silently. Everything is visible.

When to Use Which

SituationRecommended modeWhy
Prototype or early-stage greenfield buildStructuredSpeed and cost matter more than exhaustive visibility
Standard sprint executionStructuredAgents build and test reliably; audit trail not required
Regulated industry or compliance-sensitive buildInteractiveEvery decision surfaced and reviewable; nothing silently blocked
HIPAA / PHI projectInteractiveCompliance Engineer activates pentest mode; all Opus for maximum analysis depth
Release verification for productionInteractiveMaximum reasoning quality at the final gate matters
Small team on tight token budgetStructuredNo difference in model tiers vs Interactive — both modes use the same Opus/Sonnet split
You need an audit trail of every architectural decisionInteractiveSA walks through ADRs; PO asks questions; all choices recorded
Debugging a complex production issueInteractiveMaximum model quality for hypothesis generation and root-cause reasoning

Token Cost Awareness

Engagement mode is the single biggest lever on token consumption:

  • Structured: standard cost. Opus for strategic roles, Sonnet for executor roles. Agents decide and report without surfacing every choice.
  • Interactive: same model tiers — no cost premium over Structured. The difference is decision visibility: strategic roles (PO, SA, CE, RA) surface major choices for human review before proceeding.

A practical strategy: use Structured for sprint execution (where agents build and test stories reliably without needing to surface every decision), then switch to Interactive for Release mode or regulated-environment builds where every architectural and security decision needs a human sign-off.

Configuration

Set in .synaptory.yaml:

engagement_mode: "structured"   # structured | interactive

Or let the orchestrator ask at the start of each run.


What's next?

  • Enforcement -- The safety nets that implement Structured vs. Interactive behavior
  • Scrum Delivery -- See engagement modes in action during sprint delivery
  • Configuration -- All config options that affect delivery behavior
Concepts · 12

Enforcement and Safety Nets

synaptory's quality mechanisms are not instructions that the LLM may or may not follow. They are enforced by shell hooks and Python scripts that can block execution. This distinction -- between "the model is told to do X" and "the system stops if X isn't done" -- is what makes the system reliable.

v3 vocabulary: the per-story Definition of Done described here is the signal behind the Evidence / DoD gate that the Console renders (one of four v3 spec gates: Inception, Spec Ready, Evidence/DoD, Release). The receipt + verification machinery on this page is unchanged — it's what produces the evidence that lights the gate green.

The difference between a system that says "tests must pass" and one that stops if they don't is the difference between guidance and a guarantee. For you as the operator, this means you do not need to audit every story to make sure the agents did the right thing. The hooks do it automatically, and they do not lie.

Code-Enforced Safety Nets

In Autonomous mode: missing receipts, invalid receipts, lifecycle state violations, and verification command failures all trigger exit 1 from their respective hooks. Execution stops. No work continues until the problem is resolved.

In Controlled mode: the same checks run, but failures are surfaced as warnings rather than blocks. The human operator reviews and decides whether to proceed.

This is the Autonomous/Controlled split described in Engagement Modes. The enforcement is identical; only the consequence differs.

Receipt Protocol

Every agent writes a JSON receipt when it completes work on a story. The receipt is the agent's proof of work -- not a summary, but a verifiable claim.

Story-Scoped Receipts

Receipts are scoped to individual stories, not phases or sprints:

US-001-se.json          # SE implementation of story US-001
US-001-qe.json          # QE testing of story US-001
US-001-cr.json          # CR review of story US-001
US-001-ce.json          # CE security audit of story US-001
TICKET-042-se.json      # Kanban ticket implementation

Receipt Format

A receipt contains:

{
  "story_id": "US-001",
  "role": "quality-engineer",
  "backend": "codex",
  "model": "gpt-5.4",
  "story_dod": {
    "tests_pass": true,
    "code_reviewed": true,
    "no_critical_findings": true,
    "build_succeeds": true,
    "coverage_no_decrease": true
  },
  "artifacts": [
    "tests/unit/user-service.test.ts",
    "tests/integration/user-api.test.ts"
  ],
  "verification_commands": [
    "npm test -- --testPathPattern=user-service",
    "npm run test:integration -- --testPathPattern=user-api"
  ],
  "metrics": {
    "tests_written": 12,
    "tests_passing": 12,
    "coverage_delta": "+3.2%",
    "findings_count": 0
  },
  "completed_at": "2026-04-12T14:30:00Z"
}

Key fields:

  • backend and model -- which AI backend and model produced this work (traceability)
  • story_dod -- per-story Definition of Done evaluation, inline with the receipt
  • artifacts -- file paths to everything the agent produced (must exist on disk)
  • verification_commands -- shell commands that prove the work is correct

Receipt Validation

After each agent completes, synaptory-verify-receipt.sh runs a validation pass:

  1. Schema validation -- required fields present, correct types
  2. Artifact verification -- every file path in the artifacts list exists on disk
  3. Banned phrase check -- rejects vague verification claims
  4. Command re-execution -- verification commands are re-run to confirm they still pass

Receipts without verification_commands block execution in Autonomous mode. There is no "I finished" without verified artifacts and passing commands.

Definition of Done Evaluation

Quality is verified continuously through a two-layer DoD model, replacing traditional phase gates.

Per-Story DoD (both Scrum and Kanban)

Evaluated as each story completes the SE->QE->CR pipeline:

CheckSeverityAgentAdaptive?
tests-passCriticalQuality EngineerNo -- always checked
build-succeedsCritical(auto)No -- always checked
no-critical-findingsCriticalCompliance EngineerYes -- intensity scales with maturity
code-reviewedNon-criticalCode ReviewerYes -- skip Sprint 1, enable Sprint 2+
coverage-no-decreaseNon-critical(auto)No -- always checked

Critical checks must pass for a story to move to done. Non-critical checks are advisory -- they warn but don't block.

Sprint-Level Overlay (Scrum only)

Evaluated at Sprint Review, after all sprint stories have been executed:

CheckTypeWhat it verifies
Sprint Goal metHumanDid the sprint deliver on its stated goal?
Feedback addressedHumanWas stakeholder feedback from prior sprints incorporated?
No regressionAuto (Critical)No regression across all sprint stories
Documentation updatedHumanWere docs updated for changed features?

Adaptive Intensity

DoD depth scales with project maturity:

MaturityWhat's ActiveWhy
Early (Sprint 1 / first 5 tickets)Critical only: tests, build, no critical findingsMinimal code to review or audit
Growing (Sprint 2-3 / tickets 6-15)+ Code review enabledGrowing codebase needs review
Mature (Sprint 4+ / tickets 16+)+ Full security auditEnough surface area
ReleaseAll checks at maximum depthProduction readiness

Story Pipeline Enforcement

The story pipeline enforces state transitions. Stories cannot skip states or go backward:

queued --> in_progress (SE) --> testing (QE) --> reviewing (CR) --> done
  • A story cannot move to testing until the SE receipt is validated
  • A story cannot move to reviewing until the QE receipt is validated
  • A story cannot move to done until all per-story DoD checks pass
  • A story moves to blocked if any Critical DoD check fails -- the SE is notified for rework

Story state transitions auto-sync to the configured tracker backend (local, GitHub, Jira, Teamwork).

Backend Traceability

Every receipt records which AI backend and model produced the work. This provides a complete audit trail:

  • Which AI built each story (SE receipt: backend: "codex", model: "gpt-5.4")
  • Which AI tested each story (QE receipt: backend: "codex", model: "gpt-5.4")
  • Which AI reviewed each story (CR receipt: backend: "claude", model: "claude-opus-4-6")

This traceability is valuable for debugging quality issues (which backend produced the problematic code?) and for cost analysis (which backend configuration gives the best cost/quality ratio?).

Re-Anchoring

At ceremony transitions and before context compaction, the orchestrator re-reads key artifacts directly from disk: the BRD, ADRs, API contracts, current receipt chain, and brownfield context packages. The synaptory-reanchor.sh hook handles this automatically at the PreCompact lifecycle event.

Re-anchoring prevents silent degradation. Over a long delivery run, the model's in-context memory of early architecture decisions can drift. By re-reading source-of-truth files from disk, agents in later sprints work from the same foundation as agents in Sprint 1.

Freshness Protocol

Before implementing anything involving external dependencies -- package versions, model IDs, API endpoints, cloud service names -- agents run a web search to verify the information is current. This catches outdated information before it lands in the codebase.

Particularly important for:

  • NPM/PyPI package versions (agents may "remember" versions that are months old)
  • Cloud service API endpoints and parameters
  • LLM model identifiers (model names change frequently)
  • Framework configuration syntax (breaking changes between versions)

Self-Healing

When you reject the Inception Gate or a DoD evaluation, the system feeds your specific concerns back to the relevant agent, the agent reworks its output, and the check is re-presented. Maximum 2 rework cycles.

The quality of the rework depends on feedback specificity. "The multi-tenancy model should be schema-per-tenant, not row-level" produces a targeted fix. "Make it better" produces a vague rework.

Dead Element Rule

Any button, link, or form that renders in the UI but does nothing is classified as a Critical bug, not a TODO. The SE [frontend mode] verification checks that every interactive element has a working handler, every link resolves, every form submits, and every navigation item reaches a page that renders.

Cross-Session Persistence

Context packages, lifecycle state, and receipts survive across sessions. Three hooks handle the lifecycle:

  • synaptory-session-start.sh (SessionStart) -- detects the .synaptory/ workspace, loads lifecycle state (Scrum or Kanban), injects context packages and story pipeline state
  • synaptory-pipeline-snapshot.sh (Stop) -- writes a state snapshot with enough context to resume
  • synaptory-session-end.sh (SessionEnd) -- async cleanup of temporary resources

Long multi-session builds resume where they left off. Sprint state, ceremony position, story pipeline status, receipt chains, and context packages are all persistent.

Constraint-Driven Architecture

The Solution Architect derives architecture from actual constraints: expected scale, budget, team size, compliance requirements, and operational complexity.

100 concurrent users gets a monolith. 10 million users gets microservices. A two-person team gets simpler infrastructure than a platform team of twenty. HIPAA compliance gets encryption-at-rest and audit logging as architectural requirements, not bolt-on features.

This prevents the most common AI architecture failure: recommending microservices for every project regardless of scale.


What's next?

Concepts · 13

v3.0 Roadmap

What's coming, why, and what's already visible in the v2.5 product today.

The current product is v2.5 — that's the version reflected in the rest of this guide. v3.0 is the next major milestone. Some pieces are already live in the UI ahead of the backend; this page tells you which signals you'll see, what's coming, and how the runtime story plays out.

For the full design specification (the source of truth) see docs/v3.0/v3-spec.md. The vocabulary mapping is in glossary.


The product reframe

VersionProduct frameWhat the user gets
v2.5 (today)Multi-agent adaptive delivery inside Claude CodeAgents run Scrum, Kanban, and focused workflows with receipts, hooks, telemetry, skills, control-plane-backed auth
v3.0Claude Code harness governed by an agentic delivery control planeThe same workflows, but bound to specs, tasks, gates, evidence, policy, audit, domain packs, and Delivery Owner / global-admin cockpit views
v3.1+Runtime-neutral control plane with pluggable harness adaptersClaude Code remains supported, but selected workflows can run through additional agent runtimes

The clearest mental model:

synaptory = Delivery Control Plane + Agent Runtime Harness.

In v2.5 those two layers are entangled inside the plugin. In v3.0 the control plane becomes the durable product layer and Claude Code becomes the (still-only) production runtime adapter.

The v2.5 delivery model is not discarded. Scrum, Kanban, Story Buddy, Branch Finish, Debug, Discover, Preview, Retro, Init, Status, and Help all remain. v3.0 makes them more accountable by binding them to specs, tasks, gates, and evidence.


Four concrete additions in v3.0

1. Spec graph

In v2.5 a "story" is a tracker ticket plus some markdown that lives in receipts. In v3.0 it becomes a Spec — a versioned object in the control plane with kind (story, feature, bugfix, task, release), a hash chain back to its parent spec versions, and explicit task children.

The spec_versions and tasks tables become the source of truth. The tracker adapter (GitHub Issues / Jira / Teamwork) syncs from them, not the other way around.

2. Four-gate model

Today the user-facing checkpoints are the Inception Gate (one human review at Sprint 0) and per-story DoD (automated, every story). v3.0 generalises this into four gates:

GateWhen it firesWhat it gates
InceptionProject startProject direction is signed off (vision, epics, Sprint 1, architecture foundations)
Spec ReadyBefore code-modifying workThe spec is complete, has tasks, and has explicit validation commands
Evidence / DoDBefore marking a spec doneReceipts present, verification commands rerun cleanly, no critical findings
ReleaseBefore shippingRelease evidence pack assembled across the contributing specs

The the Overview page already renders the Gate Queue card with all four — only Evidence/DoD has a wired backend signal in v2.5; the other three light up in place when v3.0 ships. See Using the Control Plane.

3. Evidence ledger with hash chain

Receipts stay (the protocol you know from enforcement) but become entries in a ledger — each receipt's hash chains to the prior receipt for the same spec. A break in the chain is detectable; the Control Plane gets chain-break alerts.

Receipts also gain three v3 fields: spec_version_id, task_id, and per-stage token usage tagged to one of the 11 v3 stages.

4. Policy and domain packs

Today, healthcare compliance is enforced via .synaptory.yaml flags. v3.0 generalises this into a policy registry + domain packs: a project can declare e.g. domain: healthcare-hc0 and inherit BAA-only backends, model pinning, AI-BOM emission, and signed-commit requirements as a unit.

Healthcare is the first pack. Others (financial-services, gov, default-strict) are sketched in the spec but not committed.


What's already visible in v2.5

The Control Plane UI runs ahead of the backend in places, so you'll see v3 vocabulary today even though the underlying signals are partial. Specifically:

Where you see itWhat it means todayWhat it'll mean in v3.0
Control Plane label "Spec" instead of "Story"Renaming only — same DB tableBacked by spec_versions with hash chain
Control Plane "Project Owner" instead of "Product Manager"Agent rename completeNo change
Control Plane "Delivery Owner" for human roleUI-only termUsed in evidence and gate-event ownership
Overview "Gate Queue" card with 4 gatesThree are placeholdersAll four wired
Cost panel "11 stages" breakdownAggregated from existing receipt fieldsCleaner per-stage tagging in the receipt
Quality panel "Evidence/DoD" headerSame as v2.5 DoD evaluationTied to the ledger and gate_events table

This is intentional — the v3 cut-over should be a backend swap, not a UI rewrite.


What does not change

The v3.0 spec is explicit about what stays:

  • Entra OAuth + PKCE for staff and admin auth.
  • SYNAPTORY1 user-scoped session tokens — same format, same per-request project_members check.
  • Standalone CLI distribution — still installed once per laptop (ADR-012).
  • Build-time control-plane URL stamping — no runtime redirection.
  • CP-delivered, watermarked skill bodiesADR-016.
  • Durable local outbox — offline-capable telemetry.
  • Claude-only user-facing plugin — until v3.2 introduces a second runtime as a narrow pilot.
  • The 9-agent delivery team — the orchestration model remains.

If you're worried about a v3 migration breaking your laptop install: it won't. The plugin and CLI flow stays the same; the new objects (specs, gates, ledger) live behind the API.


Beyond v3.0

v3.0 makes the core delivery objects runtime-neutral but ships only Claude Code as a production adapter. The breakout from Claude-Code dependency is staged:

MilestoneFrameWhat changes
v3.1Runtime adapter boundaryClaude Code becomes the first named adapter (runtime: claude-code). A formal runtime-adapter interface is defined. A fake/local runtime passes conformance tests. No second production runtime yet.
v3.2Second runtime pilotOne narrow workflow (likely Branch Finish, Code Review, or sandboxed spec implementation) runs through a second runtime — probably an open-source runner or a Cursor/IDE harness. Claude Code stays default for full Scrum/Kanban.
v3.3+Multi-runtime deliveryRuntime selection by project / workflow / risk tier / domain pack. Cost and quality comparison in the Console. Runtime failover where safe.

Spec, gate, evidence, and policy are designed in v3.0 to not encode Claude-Code-specific assumptions, so v3.1+ is a refactor at the runtime boundary, not a re-architecture of the control plane.


v2.5 prerequisites before v3.0 ships

Five v2.5 items are explicit prerequisites:

  • CLI verifies signed config payloads before caching.
  • CLI does real Entra auth-code exchange (no fixture assumptions in prod).
  • Device-code flow mints the same user-scoped SYNAPTORY1 session as browser login.
  • Production skill KEK is bound to Azure Key Vault, not the filesystem fallback.
  • Standalone CLI install/version flow is confirmed in pilot.

These don't add features — they close gaps from the v2.5 substrate. Operators tracking v3 readiness should watch these.


What's next

Guides · 14

Scrum Delivery

You type a description of what you want to build. The orchestrator runs Inception — the Project Owner defines the vision and Sprint 1 stories, the Solution Architect lays down the foundational ADRs, the Platform Engineer bootstraps CI/CD. You review the Inception Gate output (vision, epics, Sprint 1 stories, architecture) and approve. Then you watch stories flow through the SE → QE → CR pipeline, sprint by sprint, until you decide to release. Your role is to approve direction at the gate and provide feedback at Sprint Review. The agents handle everything in between.

End-to-end guide for running structured, sprint-based delivery with synaptory. The Scrum lifecycle takes a project from inception to release through iterative sprints with adaptive ceremonies.

Prerequisites

  1. Initialize your project -- say "initialize my project" to scan your codebase and generate .synaptory.yaml. Without it, agents use defaults that may not match your project structure.
  1. Review .synaptory.yaml -- check build_mode: "scrum" (default), sprint.inception (foundation or blueprint), agents.* for backend configuration, and paths.* for directory mapping.
  1. Choose your engagement mode -- structured (agents decide and report, minimal questions) or interactive (major decisions surfaced for review, same model cost). See Engagement Modes.

Starting a Scrum Project

Describe what you want to build in plain language. The orchestrator classifies your request automatically.

Example prompts that trigger the Scrum lifecycle:

Build me a multi-tenant SaaS for managing restaurant reservations
Create a real-time collaborative document editor with WebSocket support
Build a full-stack e-commerce platform with React and Node.js

Trigger signals: "build a SaaS", "from scratch", "full stack", "production grade", any greenfield intent.

For brownfield projects, the orchestrator runs Discover first (reverse-engineers the codebase), then offers a choice between Scrum (with adaptive Inception) or Kanban. See Kanban Delivery.

The Scrum Lifecycle

Inception --> Sprint Planning --> Sprint Execution --> Sprint Review
                                                          |
                Sprint Close <-- Sprint Retro (adaptive) <-+
                    |
                    +--> Next Sprint (loop) or Release

Inception (Sprint 0)

Purpose: Establish just enough foundation to start Sprint 1. Not a complete upfront design -- just enough direction.

Two modes (configured via sprint.inception):

ModeWhen to UseWhat's Produced
Foundation (default)Direction is clear, details will emergeMini-BRD (1-2 pages), 3-5 epics, Sprint 1 stories decomposed, foundation ADRs, CI/CD bootstrap, test framework
BlueprintComplex domain, regulatory requirements, fixed-scope contractsFull BRD + NFRs, all epics to feature level, Sprint 1-2 stories decomposed, complete SAD + all ADRs, full infrastructure + staging

Agents involved:

  • Project Owner -- defines vision, decomposes Sprint 1 stories (foundation) or Sprint 1-2 (blueprint)
  • Solution Architect -- creates foundation ADRs, API skeleton, ERD
  • Platform Engineer -- bootstraps CI/CD, Docker, dev environment
  • Quality Engineer -- sets up test framework, Sprint 1 test spec

Inception Gate:

Vision ✓ | Epics {N} | Sprint 1 {N} stories ready | Architecture {N} ADRs | CI/CD ✓ | Tests ✓

Options: Approve | Show details | I have concerns | Chat

This is the only human approval gate. Approve the direction, then sprints begin. If you have concerns, the orchestrator feeds them back for rework (max 2 cycles).

Brownfield Inception: For existing codebases choosing Scrum after Discover, Inception is adaptive. The orchestrator detects what already exists (CI/CD, tests, architecture docs, tracker data) and only runs the missing steps:

  • All detected -> Skip Inception, start at Sprint Planning
  • Some detected -> Targeted Inception (run only missing steps)
  • None detected -> Full Inception (same as greenfield)

Sprint Planning

When: Every sprint start.

Agents: Project Owner, Solution Architect (conditional), Quality Engineer, Orchestrator.

What happens:

  1. PO reads context -- prior sprint feedback, retro insights, backlog priorities
  2. PO refines stories for this sprint -- updates acceptance criteria, creates new stories if needed
  3. SA architecture review (conditional) -- the Orchestrator analyzes story text for architecture signals:
  • New database entity -> ERD update + migration ADR
  • New service/bounded context -> system design + ADR
  • New external API integration -> API contract + integration ADR
  • Auth/security requirement -> security architecture ADR
  • Performance-critical story -> NFR alignment review
  • No triggers -> SA is skipped (most sprints)
  1. Team selects stories -- velocity-based capacity, user can override scope
  2. Sprint Goal confirmed
  3. QE generates test spec for sprint stories

Adaptive intensity:

  • Lightweight -- stable backlog, no new feedback -> PO confirms pre-refined stories, minimal ceremony
  • Full -- new feedback, scope changes, retro improvements -> full refinement cycle

Sprint Execution

The per-story pipeline:

Story US-001: SE implements → QE tests → CR reviews → DoD ✓ Done
Story US-002: SE implements → QE tests → CR reviews → DoD ✓ Done
Story US-003: SE implements → QE tests → (in progress)
Infra-001:    PE implements → (parallel)

How it works:

  1. SE picks the highest-priority story and implements it (code + unit tests)
  2. Hands off to QE immediately -- no waiting for all stories to finish
  3. QE tests -- acceptance criteria tests, integration tests
  4. CR reviews if DoD requires (adaptive: skip Sprint 1, enable Sprint 2+)
  5. Per-story DoD evaluated: tests pass, build succeeds, no critical findings
  6. SE moves to the next story

Story sub-states:

queued --> in_progress (SE) --> testing (QE) --> reviewing (CR) --> done

The orchestrator can dispatch up to parallelism.max_concurrent_subagents (default: 3) agent tasks concurrently. QE can test one story while SE implements the next.

Infrastructure stories: The Platform Engineer handles infra stories (CI/CD updates, IaC changes) in parallel with the story pipeline.

Sprint Review

When: After all sprint stories have been executed (or time-box ends).

Agents: Orchestrator, Technical Writer, Project Owner.

What happens:

  1. Deploy increment to preview -- auto-detected for web apps (Next.js, React, etc.)
  2. TW generates reports -- quality and progress reports for the sprint
  3. Demo working software -- organized by Sprint Goal and completed stories
  4. Sprint-level DoD overlay evaluated:
  • Sprint Goal met (human)
  • Stakeholder feedback addressed (human)
  • No regression across sprint stories (auto)
  • Documentation updated (human)
  1. Capture stakeholder feedback -- feeds forward to next Sprint Planning
  2. PO updates product backlog based on feedback

What you see:

Sprint 2 -- Review & Demo

  Stories: 8/9 completed
  Tests: 142/145 passing (98%)
  Coverage: 82% (+3.2%)
  Findings: 0 Critical, 1 High (fixed)
  Sprint Goal: "Ship user management module" ✓

  Sprint reports: reports/sprint-2/

Options:
  [Approve -- continue to Sprint 3]
  [I have feedback]
  [View sprint reports]
  [Release]

Sprint Retro (Adaptive)

When: After Sprint Review. Skipped if the sprint went smoothly (high completion, no blocks, no regressions).

What happens when it runs:

  1. Data collection -- git metrics, receipt data, velocity trends, cycle time
  2. Analysis -- what went well, what needs improvement
  3. Process suggestions:
  • Adjust verification intensity (e.g., enable code review earlier)
  • Add/remove DoD items
  • Adjust concurrency settings (parallelism.max_concurrent_subagents)
  • Modify sprint capacity
  1. User selects improvements -- accept all, select specific, or skip
  2. Configuration updated for next sprint
  3. Feed-forward -- insights passed to PO for next Sprint Planning

Sprint Close

Always runs -- bookkeeping that cannot be skipped.

What happens:

  1. Carry-over policy applied to incomplete stories:
  • move_to_next (default) -- move to next sprint backlog
  • keep_in_sprint -- archive in closed sprint (reporting only)
  • ask -- prompt user at close time
  1. Sprint metrics recorded -- planned/completed stories, velocity, DoD compliance
  2. Next decision:
  • Continue to Sprint N+1
  • Release (ship to production)
  • Stop

Running Sprints

How to start a sprint

Use natural language:

build sprint 1          # Start a specific sprint
next sprint             # Continue to the next pending sprint
continue sprint         # Same as "next sprint"
resume sprint 3         # Pick up where you left off on sprint 3
start sprint            # Start the current pending sprint

If no sprint number is specified, the orchestrator reads sprint state and targets the current pending sprint.

Sprint routing guards

Ambiguous requests -- when you say "build this" in a Scrum project, the orchestrator asks:

  • Build Sprint N (recommended) -- continue with the next pending sprint
  • Choose a different sprint
  • Override sprint mode

Out-of-order requests -- requesting Sprint 3 when Sprint 2 isn't complete shows the prerequisite gap and offers to build Sprint 2 instead.

Re-building approved sprints -- requesting an already-approved sprint warns that re-building is destructive and offers alternatives.

Cross-Session Persistence

Sprint state persists automatically across Claude Code sessions:

  1. On session end: synaptory-pipeline-snapshot.sh writes a state snapshot including full sprint and story pipeline state
  2. On session start: synaptory-session-start.sh loads lifecycle state, sprint position, story pipeline, and context packages

Resuming after a break:

  1. Open the project in Claude Code (session start hook loads state automatically)
  2. Say "show status" to see: which sprint, which ceremony, story pipeline status
  3. Say "continue sprint" or "next sprint" to resume

No manual state restoration needed. See Resuming Sessions for details.

Configuration

Essential settings

build_mode: "scrum"                    # Default -- Scrum lifecycle

sprint:
  inception: "foundation"              # foundation | blueprint
  carry_over_policy: "move_to_next"    # move_to_next | keep_in_sprint | ask
  velocity: null                       # Story points per sprint (null = uncapped)
  protected_modules: []                # Paths SE must confirm before touching
  constraints: []                      # Architectural rules for every story

agents:
  default_backend: "claude"

engagement_mode: "structured"          # structured | interactive

Full config example

version: "3.0"
build_mode: "scrum"
engagement_mode: "structured"

project:
  name: "reservation-saas"
  language: "typescript"
  framework: "nextjs"
  cloud: "aws"
  architecture: "modular-monolith"
  type: "greenfield"
  template: "nextjs-fullstack"

agents:
  default_backend: "claude"

sprint:
  inception: "foundation"
  carry_over_policy: "move_to_next"
  velocity: 21

tracker:
  backend: "github"
  github:
    repo: "myorg/reservation-saas"

preferences:
  test_framework: "vitest"
  orm: "prisma"
  package_manager: "pnpm"
  frontend_framework: "nextjs"
  styling: "tailwind"

features:
  frontend: true
  multi_tenancy: true
  payment_integration: true
  real_time: true

See Configuration Reference for the complete schema.


What's next?

Guides · 15

Kanban Delivery and Brownfield Workflows

You point synaptory at an existing codebase. Discover runs — the orchestrator reverse-engineers the system and builds context packages so every agent understands what exists before touching it. Then you say "work on TICKET-142" or "pull the next ticket." The SE implements, the QE tests, the CR reviews — same per-story pipeline as Scrum, without the sprint ceremonies. When you're ready to ship, you trigger Release on-demand. No ceremonies, no sprint planning overhead: just continuous flow from ticket to verified increment.

Guide for continuous ticket-based delivery on existing codebases. Kanban mode provides a lightweight flow for post-launch maintenance and evolution -- no sprint ceremonies, just pull a ticket, build it, verify it, ship it.

When to Use Kanban

Kanban is designed for brownfield projects -- codebases that already have working code, tests, and infrastructure:

  • Post-launch maintenance and bug fixes
  • Continuous feature evolution on a live product
  • Projects that have completed their Scrum sprints and transitioned to maintenance
  • Teams that prefer continuous flow over time-boxed sprints

Entry Point: Discover Always Runs First

Every brownfield project starts with Discover -- reverse-engineering the codebase to build understanding before making changes.

Run /synaptory in your project or describe what you want:

understand this codebase
map the system

What Discover Produces

Discover analyzes your codebase through five phases:

  1. Architecture Reconstruction -- module inventory, dependency graph, hidden coupling, interface contracts, architecture pattern classification
  2. Business Rule Extraction -- domain logic with confidence scores (HIGH/MEDIUM/LOW/INFERRED), implicit assumptions, dead code candidates
  3. Risk and Hotspot Analysis -- git-based churn analysis, risk scoring per module, bus factor identification
  4. Coverage Baseline -- test framework detection, current coverage measurement, characterization tests for critical untested paths
  5. Assembly -- verifies all artifacts, writes completion receipt

Context Packages

Discover produces seven context packages stored in .synaptory/.orchestrator/context-packages/:

PackageContents
dependency-map.mdModule boundaries, import graph, hidden coupling
interface-contracts.mdInter-module contracts, protocols, endpoint specs
business-rules-inventory.mdDomain logic with confidence scores
data-dictionary.mdDomain terms, entity definitions, magic numbers
risk-register.mdModule risk scores, hotspot files, bus factor risks
health-assessment.mdProject health, test density, coverage baseline, tech debt
ui-contracts.mdUI component interfaces, design tokens, page-level contracts

These packages are auto-loaded into every agent's context via the synaptory-session-start.sh hook. Agents read relevant packages before making decisions:

  • Project Owner reads business-rules-inventory.md before refining requirements
  • Solution Architect reads dependency-map.md and interface-contracts.md before designing
  • Software Engineer reads risk-register.md before modifying high-risk modules
  • Compliance Engineer reads health-assessment.md to calibrate audit depth
  • Code Reviewer reads interface-contracts.md to verify modifications respect contracts

Choosing Your Path

After Discover, the orchestrator presents a choice:

  • Scrum (with adaptive Inception) -- for structured iteration with ceremonies. See Scrum Delivery.
  • Kanban -- for continuous ticket-based flow without sprint ceremonies.

Set in .synaptory.yaml:

build_mode: "kanban"

Adaptive Inception Detection (Scrum path)

If you choose Scrum for a brownfield project, Inception is adaptive -- the orchestrator detects what already exists:

SignalDetectionIf PresentIf Missing
CI/CD pipeline.github/workflows/*, .gitlab-ci.yml, JenkinsfileSkip PE bootstrapRun PE bootstrap
Test frameworkjest.config.*, pytest.ini, test patternsSkip QE setupInitialize tests
Architecture docsdocs/architecture/, ADRsSkip SA foundationRun foundation ADRs
Project config.synaptory.yamlSkip configRun Init
Tracker dataTracker CLI health check OKSkip tracker initInitialize tracker
  • All detected -> Skip Inception entirely, start at Sprint Planning
  • Some detected -> Targeted Inception (run only missing steps)
  • None detected -> Full Inception (same as greenfield)

The Kanban Flow

READY --> Pull ticket --> SA triggers (if needed) --> SE implements
                                                          |
REVIEW <-- CR reviews (if DoD) <-- QE tests <-------------+
   |
   +--> READY (next ticket)
   +--> RELEASE (on-demand)

Ready

The system waits for the next ticket. Two work source modes:

User-specified:

fix TICKET-123
work on US-042
implement the login bug fix

Auto-pull:

pull next ticket
what's next

The orchestrator queries the tracker for the highest-priority ready ticket and asks for confirmation before starting.

Execute

The same per-story SE->QE->CR pipeline used in Scrum:

  1. SE implements the ticket (code + unit tests)
  2. QE tests -- acceptance criteria, integration tests
  3. CR reviews (if DoD requires -- adaptive, based on ticket count maturity)
  4. Per-ticket DoD evaluated -- same story-level checks as Scrum (tests pass, build succeeds, no critical findings)

SA auto-trigger: If the ticket text contains architecture signals (new entity, new service, integration, security requirement), the Solution Architect is invoked before the SE starts.

Review

After the ticket completes the pipeline:

  1. Demo the completed work -- preview deployment for web changes
  2. Capture feedback -- the Project Owner updates the backlog
  3. Return to Ready for the next ticket

Per-Ticket DoD

Kanban uses the same per-story DoD as Scrum, but without the sprint-level overlay:

CheckSeverityWhat it verifies
Tests passCriticalAll acceptance criteria tests pass
Build succeedsCriticalBuild completes and dev server starts
No critical findingsCriticalZero Critical security findings
Code reviewedAdaptiveTicket code reviewed (after first 5 tickets)
Coverage no decreaseNon-criticalTest coverage maintained

No Sprint Goal, no sprint-level regression check, no documentation overlay. Quality is verified per ticket.

Kanban Retro

Retro is not part of the default Kanban flow. You can trigger it on-demand anytime:

retro
how are we doing
show metrics

The orchestrator analyzes recent tickets for trends: cycle time, throughput, recurring issue patterns, DoD compliance rate, backend performance comparison.

Release in Kanban

Release is available on-demand -- there are no sprint boundaries to wait for:

release
ship it
go live

The Release flow is identical to Scrum Release: full regression testing, security audit, production infrastructure, documentation, release readiness check. See Release.

Scrum-to-Kanban Transition

Projects that have completed their Scrum lifecycle can transition to Kanban for ongoing maintenance:

  1. Complete the current sprint or Release
  2. Change configuration: build_mode: kanban
  3. The Kanban state machine starts from READY
  4. Remaining backlog stories become Kanban tickets
  5. Context packages, ADRs, and architecture are carried over
  6. Sprint history and metrics are archived
  7. Agent backend configuration is preserved
# Before transition
build_mode: "scrum"

# After transition
build_mode: "kanban"

Coverage Ratchet

When enabled, code-modifying agents check for existing tests before modifying any file:

SituationAgent behavior
File has existing testsModify freely
File is untestedWrite a characterization test first, then modify
Coverage decreasesBlocked -- agent must add tests to restore coverage

Configure in .synaptory.yaml:

brownfield:
  coverage_ratchet: true
  context_packages: true
  characterization_tests: true

Brownfield Protections

Additional safety mechanisms for existing codebases:

  • Protected modules (sprint.protected_modules) -- paths the SE must confirm before touching
  • Read-before-write (sprint.read_before_write) -- SE must Read() every file before modifying it
  • Characterization tests first (sprint.characterization_tests_first) -- QE writes behavior-capturing tests before SE modifies legacy code
  • Context injection (sprint.require_context_injection) -- SE must read existing module code before generating new code

Refreshing Context Packages

Context packages can become stale after significant changes. Re-run Discover incrementally:

refresh context
update context
re-analyze codebase

This runs Context Refresh mode -- an incremental update that only re-analyzes changed files.

Common triggers for refresh:

  • After a major refactoring
  • After adding a new module or service
  • When agents make decisions that ignore recent changes
  • After unshallowing a shallow git clone (enables better hotspot analysis)

Configuration

build_mode: "kanban"
engagement_mode: "structured"

project:
  type: "brownfield"                   # or evolved_brownfield, mixed

agents:
  default_backend: "claude"

tracker:
  backend: "github"
  github:
    repo: "myorg/my-project"

brownfield:
  coverage_ratchet: true
  context_packages: true
  characterization_tests: true

What's next?

Guides · 16

Multi-Spec Delivery (multiple parallel specs in one repo)

When to use this: your team runs more than one independent spec out of a single codebase and a single tracker project (Jira / GitHub Issues / Teamwork), and you need the parallel teams to keep their own backlogs, sprints, and retros without trampling each other's state. Available since Synaptory v2.7 (Jira) and v2.8 (GitHub Issues + Teamwork).

By default Synaptory assumes one tracker project + one sprint counter + one receipt stream per codebase. That breaks when two or three teams are working concurrently in the same repo:

  • One team's /sprint-advance overwrites another's current_sprint.
  • Concurrent agents flip the last_agent field mid-session.
  • The tracker-id-map.json cache gets clobbered by parallel syncs.

Multi-spec adds a thin spec abstraction that lives entirely inside one tracker project. Each spec maps to a partition discriminator native to the backend — a Jira label / GitHub label / Teamwork tag — and the state, caches, receipts, and CLI flags namespace cleanly under the spec id.

BackendDefault discriminatorOther optionsRead filterWrite side-effect
Jiralabelcomponent / epic / jqlJQL fragment labels = "<v>"append label
GitHub Issueslabelmilestonesearch query label:"<v>"append label (or set milestone)
TeamworktagtasklisttagIds=<id> query paramappend tag (or override tasklist)
Localnot supported

This guide walks through migrating an existing single-spec project to multi-spec, the day-to-day commands once you're there, and the operational details. The full design is in docs/multi-spec-design.md.


Mental model

ConceptSingle-spec (default)Multi-spec
Tracker project11 (same project hosts all specs — Jira project, GitHub repo, or Teamwork project)
Boards / views1N — one per spec, each filtered by the discriminator
pipeline-state.json lifecycleOne lifecycle_state + current_sprintPer-spec under state.specs.<id>
Receipts directory.synaptory/.orchestrator/receipts/.synaptory/.orchestrator/specs/<id>/receipts/
Tracker cachesFlatPer-spec under specs/<id>/
CLAUDE.md guidanceOne bodyShared top + ### Spec: <name> sub-sections
Active specn/apipeline-state.json.active_spec (/switch-spec to change)

Specs are a logical grouping, not an organizational boundary. Cross-spec dependencies stay in the tracker via "is blocked by" / "depends on" links; humans coordinate, agents stay isolated per spec.


Tracker-side setup (do this first)

Multi-spec is opt-in. Pick a discriminator on the tracker side per spec, apply it to existing tickets, and (where applicable) create a filtered view. ~5 minutes per spec once you've decided on names.

Jira

  1. Pick a kebab-case label. Examples: platform, contract-mastery. No prefix; no spaces.
  2. Apply the label to every existing ticket that belongs to that spec (bulk-edit in Jira).
  3. Create a saved filter via POST /rest/api/3/filter (Jira REST). acli cannot do this; the API call is one shot.
  4. Create a Scrum board backed by the filter: acli jira board create --filter-id <id>.

Alternative discriminators: component, epic, or raw jql (read-only). The Hano dogfood used labels: boards 136/137/138, filters 10269/10270/10271, labels platform / contract-mastery / ehr-integration.

GitHub Issues

  1. Pick a kebab-case label. GitHub labels are repo-wide and case-sensitive — pick something distinctive (e.g. spec:platform, spec:ehr-integration) so the label doesn't collide with other repo labels.
  2. Create the label on the repo: gh label create platform --description 'Spec: Multi-tenant Platform' --color FFA500 (one per spec).
  3. Apply the label to every existing issue that belongs to that spec: gh issue edit <number> --add-label platform or bulk-edit in the GitHub UI.
  4. Optional: saved searches / projects. GitHub Projects (v2) board with the label filter is the natural multi-spec view, but not required — the adapter constructs the filter from .synaptory.yaml at query time.

Alternative discriminator: milestone. Use this if each spec maps to a long-lived release/quarter rather than a label (e.g. CM-2026Q1). Note that the GitHub adapter also uses milestones for sprints — when both spec and sprint are milestone-bound, the sprint scope wins for read queries.

Teamwork

  1. Pick a kebab-case tag name. Teamwork tags are scoped per Teamwork installation (not per project) — verify your name isn't already taken: https://<site>.teamwork.com/app/people/tags.
  2. Create the tag via the Teamwork UI (Add → Tags) or let the adapter auto-create on first write — it calls get_or_create_tag() on the transport.
  3. Apply the tag to every existing task that belongs to that spec (bulk-tag in Teamwork UI).
  4. Optional: saved filters. Teamwork's "Saved Filters" on the Tasks page give your team the per-spec board view without leaving the project.

Alternative discriminator: tasklist. Use this if each spec already owns a dedicated tasklist in the Teamwork project (strict partitioning — a task can only live in one tasklist). Filter value is the numeric tasklist id.


Migration: collapse single-spec into multi-spec

If you have an existing Synaptory project, run the migration script before touching .synaptory.yaml by hand:

python3 ${CLAUDE_PLUGIN_ROOT}/skills/_shared/scripts/migrate_to_multispec.py \
    --primary-spec=platform \
    --new-specs=contract-mastery,ehr-integration

What it does (in order):

  1. Snapshots .synaptory/.orchestrator/ to .synaptory/.migrations/<timestamp>-pre-multispec.tar.gz so you can roll back.
  2. Upgrades pipeline-state.json from v2.0 (flat) to v3.0 (nested under specs:). The existing flat state (lifecycle/sprint/stories/etc.) collapses under state.specs.<primary>. New specs are initialized at INCEPTION, current_sprint=0, empty caches.
  3. Moves tracker caches and receipts from .synaptory/.orchestrator/{tracker-id-map,tracker-data,backlog-order}.json + receipts/* to specs/<primary>/. Empty specs/<new-spec>/receipts/ directories are created for the new specs.
  4. Appends a stub specs: block to .synaptory.yaml (you fill in board_id and filter.value from your Jira side).
  5. Regenerates the CLAUDE.md sentinel as a multi-spec rollup.

The script is idempotent — re-running it on an already-migrated project is a no-op:

$ python3 .../migrate_to_multispec.py --primary-spec=platform --yes
[migrate-to-multispec] state is already multi-spec — nothing to do.

Post-migration: fill in .synaptory.yaml

The script writes a stub specs: block. Edit it with your actual tracker values per spec. Every spec must bind to the same backend as tracker.backend (mixed bindings are rejected at config-load time).

Jira

tracker:
  backend: jira

specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    jira:
      url: "https://hano.atlassian.net"
      project_key: "HT"
      board_id: 136
      filter:
        type: "label"
        value: "platform"
  - id: "contract-mastery"
    name: "Contract Mastery"
    jira:
      url: "https://hano.atlassian.net"
      project_key: "HT"
      board_id: 137
      filter:
        type: "label"
        value: "contract-mastery"
Jira filter.typeRead JQL fragmentWrite side-effect
label (recommended)labels = "<value>"Append <value> to the new issue's labels
componentcomponent = "<value>"Set the issue's component
epic"Epic Link" = <value>Set the issue's parent/epic-link
jql(verbatim user-provided JQL fragment)Refuse to auto-create — read-only spec

GitHub Issues

tracker:
  backend: github
  github:
    repo: "h3tco/hiro-app"

specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    github:
      repo: "h3tco/hiro-app"
      # Optional per-spec sprint milestone prefix override:
      # sprint_milestone_prefix: "Platform Sprint "
      filter:
        type: "label"
        value: "platform"
  - id: "contract-mastery"
    name: "Contract Mastery"
    github:
      repo: "h3tco/hiro-app"
      filter:
        type: "label"
        value: "contract-mastery"
GitHub filter.typeRead search fragmentWrite side-effect
label (recommended)label:"<value>"Append <value> to the new issue's labels (creates the repo label if missing)
milestonemilestone:"<value>"Set the new issue's milestone — only when the caller didn't already pin one (sprint > spec)

Teamwork

tracker:
  backend: teamwork
  teamwork:
    site_name: "hano"
    project_id: 999

specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    teamwork:
      site_name: "hano"
      project_id: 999
      filter:
        type: "tag"
        value: "platform"
  - id: "contract-mastery"
    name: "Contract Mastery"
    teamwork:
      site_name: "hano"
      project_id: 999
      filter:
        type: "tasklist"
        value: "12345"   # numeric Teamwork tasklist id
Teamwork filter.typeRead list_tasks filterWrite side-effect
tag (recommended)tagIds=<resolved-id> (auto-looked-up by name via get_or_create_tag())Append the tag id to the new task's tagIds
tasklisttasklistIds=<id>Place new aux tasks (Tasks/Bugs/Enhancements) in this tasklist; sprint tasklists still win when a story has a sprint assignment

Per-spec workflow_stages (when specs target different Teamwork projects). Teamwork assigns workflow stage IDs per project — a single top-level tracker.teamwork.workflow_stages map only resolves in one project, so writes against the other spec's project land in the wrong stage. When each spec sets its own teamwork.project_id, also give each spec its own workflow_stages map; per-spec values take precedence over the top-level map and fall back to it when empty. Per-spec sprint_milestone_prefix keeps milestone names from colliding across specs.

tracker:
  backend: teamwork
  teamwork:
    site_name: "lmhealthcarecommunications"
    # No top-level project_id or workflow_stages — each spec carries its own.

specs:
  - id: "venue-agent"
    name: "Venue Agent"
    teamwork:
      project_id: 1519491
      sprint_milestone_prefix: "Venue Sprint "
      workflow_stages:
        TO_DO: 25086
        IN_PROGRESS: 25087
        DONE: 25091
      filter: { type: "tag", value: "venue-agent" }
  - id: "stars-assistant"
    name: "STARS Assistant"
    teamwork:
      project_id: 1598948
      sprint_milestone_prefix: "STARS Sprint "
      workflow_stages:
        TO_DO: 385922
        IN_PROGRESS: 385923
        IN_REVIEW: 385924
        DONE: 385929
      filter: { type: "tag", value: "stars-assistant" }

Post-migration: edit CLAUDE.md

The migration script does not rewrite the body of CLAUDE.md beyond the state sentinel. You should add ### Spec: <name> headings yourself and move spec-specific guidance under them:

# Shared Agent Instructions

(shared top block — monorepo layout, commands, git rules, generic patterns)

### Spec: Multi-tenant Platform

(platform-specific guidance: schema isolation rules, tenant boundary discipline, etc.)

### Spec: Contract Mastery

(CM domain glossary, payer-contract authoring rules, etc.)

### Spec: EHR Integration

(EI vendor abstraction rules, PHI audit, simulator profiles, etc.)

<!-- synaptory-state ... -->

Each agent invocation reads the shared top block + only its active spec's section.


Day-to-day usage

Two ways to inspect or switch the active spec

The currently-active spec lives in pipeline-state.json.active_spec. You have two equivalent paths to read or change it:

SurfaceInspectSwitch
CLI (terminal)synaptory status · synaptory specs list · synaptory specs show [id]synaptory specs switch <id>
Inside an agent sessionask the orchestrator: "show specs", "what's the active spec?" — routes via /synaptory to the status mode/switch-spec <id> (natural-language phrase routed through /synaptory — see routing-rules.json)

Both paths write to the same file atomically. The CLI is fastest from a terminal; the orchestrator routing is fastest while you're already in an agent session.

Picking the active spec

The currently-active spec is also displayed in the CLAUDE.md sentinel rollup:

<!-- synaptory-state
last_updated: 2026-05-25T12:34:00Z
active_spec: platform
specs:
  platform: SPRINT_EXECUTION sprint=9 last_agent=ht-415-retrospective
  contract-mastery: INCEPTION sprint=0 last_agent=<none>
  ehr-integration: INCEPTION sprint=0 last_agent=<none>
-->

Switch the active spec from inside an agent session:

/switch-spec contract-mastery

Or naturally: "make platform the active spec", "switch to the EHR one". The orchestrator routes to the /switch-spec mode, which:

  1. Validates the id against .synaptory.yaml.
  2. Writes active_spec: <id> to pipeline-state.json (atomic).
  3. Re-renders the CLAUDE.md sentinel.
  4. Echoes the new spec's lifecycle + sprint.

Running scheduled commands per spec

Every tracker-side CLI accepts a --spec=<id> flag that overrides active_spec:

# Advance only the platform sprint, leaving CM and EI untouched
python3 .../scrum_state_machine.py transition <project_dir> SPRINT_PLANNING --spec=platform

# Query the CM backlog without touching active_spec
python3 .../tracker_cli.py get-backlog --spec=contract-mastery

# Update a story under EI's board
python3 .../tracker_cli.py update-status US-EI-3 IN_PROGRESS --spec=ehr-integration

This lets you wire up one scheduled routine per spec (e.g. via the control-plane's scheduled tasks), each carrying its own --spec flag. Routines never need to switch the persisted active_spec.

Scoped agent dispatches

When the orchestrator dispatches a subagent, it sets SYNAPTORY_ACTIVE_SPEC=<id> in the subagent's environment so:

  • Every internal tracker call routes to the spec's board (right project + right filter).
  • The state machine writes to state.specs.<id> only.
  • The receipt is filed under specs/<id>/receipts/{story_id}-{role}.json.

Agents read the spec context from $SYNAPTORY_ACTIVE_SPEC first, falling back to pipeline-state.json.active_spec. The CLAUDE.md ### Spec: <name> section corresponding to the active spec is loaded; other specs' sections are not.


Concurrency model

Three concurrent sessions, each running /sprint-advance --spec=<X> on a different spec, will all succeed and leave their respective current_sprint counters correct.

Under the hood: spec_state.write_state() wraps the multi-spec read-modify-write window in an fcntl advisory exclusive lock on pipeline-state.json.lock. This prevents lost updates when two writers target different spec slots in the same file. Same-spec concurrent writes still rely on last-writer-wins — if you genuinely need to advance the same spec from two places at once, you need a higher-level coordinator.

The lock is a no-op on platforms without fcntl (Windows); current production targets (macOS + Linux) are unaffected.


Rollback

If something goes wrong:

# Restore the pre-migration state from the backup tar
cd <project_root>
ls -la .synaptory/.migrations/
tar -xzf .synaptory/.migrations/<timestamp>-pre-multispec.tar.gz -C .synaptory/

The backup snapshots the entire .synaptory/.orchestrator/ directory, so restoring it reverts the schema, the cache layout, and the receipts. After restoring, remove the specs: block from .synaptory.yaml to disable multi-spec opt-in.


Out of scope (v1)

The first cut intentionally avoids these:

  • Cross-spec reads from agents. A CM agent cannot list platform stories. Humans link in Jira; agents stay isolated.
  • Cross-spec sprint coordination. Two specs sprinting on overlapping work need a human coordinator.
  • N Jira projects per codebase. This design assumes one project. Customers with hard org boundaries between specs (different BAAs, different access policies) need a separate enhancement.
  • Cross-spec receipt rollup. Per-spec streams only.
  • Spec auto-detection from git branch. Explicit /switch-spec is the only way to change active_spec.

If you need any of these, file a request via /synaptory report.


Reference

TopicWhere
Full design + decision rationaledocs/multi-spec-design.md
.synaptory.yaml schemareference/config.mdspecs: block
/switch-spec modeplugin/skills/synaptory/modes/switch-spec.md
Migration scriptplugin/skills/_shared/scripts/migrate_to_multispec.py
State helpersplugin/hooks/lib/spec_state.py
Layer-1 testsplugin/tests/lib/test_multi_spec.py (13 tests)
Layer-2 hook testsplugin/tests/hooks/test_multi_spec_hooks.py (4 tests)
Guides · 17

Release

Guide for shipping code to production. Release is a first-class lifecycle event -- available on-demand from both Scrum and Kanban, with full verification at maximum depth.

When to Release

Manual Trigger

Say "release", "ship it", or "go live" at any point:

release
ship it
go to production
production ready

Orchestrator Suggestion

At Sprint Close, if all epics are marked Done, the orchestrator notes:

All epics completed. Consider releasing.
Options: [Start Release] [Continue to Sprint N+1] [Stop]

Release is never auto-triggered. You always decide.

Mid-Project Release

You can release after any sprint or anytime in Kanban. Not every feature needs to be complete -- release what's ready.

What Happens During Release

Release runs all agents at maximum verification depth:

ActivityAgentWhat Happens
Full regression testingQuality EngineerUnit, integration, e2e, performance tests across ALL sprints/tickets. Not just the latest -- everything.
Full security auditCompliance EngineerSTRIDE threat model, OWASP Top 10, dependency vulnerability scan, full depth. In Controlled mode, includes PTES penetration testing.
Production infrastructurePlatform EngineerIaC modules, production CI/CD pipelines, monitoring, alerting, runbooks, capacity planning.
Complete documentationTechnical WriterAPI reference, developer guides, operational guide, architecture guide.
Final code reviewCode ReviewerFull codebase review -- architecture conformance, performance, code quality across the entire project.
Skill extractionOrchestratorExtracts recurring patterns into reusable Claude Code skills.

Release Readiness Check

After all agents complete, the orchestrator presents a readiness dashboard:

Release Readiness

  Sprints: {completed}/{total} completed
  Stories: {done}/{total} done
  Tests: {passed}/{total} passing ({coverage}% coverage)
  Security: {critical} Critical, {high} High remaining
  Infrastructure: ✓ Production-ready
  Documentation: ✓ Complete
  Rollback: ✓ Plan documented

Options:
  [Approve Release]
  [I have concerns]
  [View details]

All DoD checks run at Release intensity -- the highest depth level:

CheckRelease Behavior
Tests passFull regression across all code, not just latest sprint
Build succeedsProduction build, not dev build
No critical findingsFull STRIDE + OWASP + dependency scan
Code reviewedComplete codebase review
Coverage no decreaseFinal coverage baseline established

Release from Scrum vs Kanban

AspectScrum ReleaseKanban Release
TriggerAfter Sprint Close, manual or suggestedAnytime, manual only
ScopeAll completed sprintsAll completed tickets
Sprint overlayFinal sprint DoD overlay evaluatedNo sprint overlay
HistorySprint metrics archivedTicket throughput archived
What's nextCOMPLETE (terminal) or transition to KanbanCOMPLETE (terminal)

After Release

The lifecycle reaches the COMPLETE terminal state. From here:

  • Transition to Kanban for ongoing maintenance (build_mode: kanban)
  • Start a new Scrum cycle for major new features (Inception again)
  • Stop -- the project is shipped

What's next?

Guides · 18

Resuming Sessions and Tracking Progress

Guide for resuming interrupted delivery runs, understanding lifecycle state, and using the visualization tools that synaptory provides.

Cross-Session Persistence

How it works

synaptory saves and restores lifecycle state automatically across Claude Code sessions. Two hooks handle this:

HookEventWhat it does
synaptory-pipeline-snapshot.shStop (session end)Writes a state snapshot to .synaptory/.orchestrator/last-session.md -- current ceremony, completed stories, sprint state, pending work
synaptory-session-start.shSessionStartDetects .synaptory/ workspace, reads pipeline-state.json, injects lifecycle state, story pipeline status, and context packages into the session

Everything that matters for resumption is persisted to disk:

  • Lifecycle state (pipeline-state.json) -- current ceremony (e.g., SPRINT_EXECUTION), lifecycle history, Inception Gate decisions
  • Sprint state (inside pipeline-state.json) -- current sprint number, completed sprints, sprint metrics, carry-over stories
  • Story pipeline (inside pipeline-state.json) -- per-story sub-states (queued, in_progress, testing, reviewing, done, blocked)
  • Receipts (.synaptory/.orchestrator/receipts/) -- story-scoped receipts with backend traceability
  • Context packages (.synaptory/.orchestrator/context-packages/) -- brownfield analysis artifacts
  • Session snapshot (.synaptory/.orchestrator/last-session.md) -- human-readable summary of where the run stopped

No manual export or import is needed. Close Claude Code, reopen it tomorrow, and the delivery run picks up where it left off.

Checking Status

Say "status" (or "show progress", "where are we") at any time:

show status

The status display includes:

  • Lifecycle position -- current ceremony (e.g., Sprint 2 / Execution) with story pipeline progress
  • Story pipeline -- per-story status (queued, in_progress, testing, reviewing, done)
  • Agent metrics -- which backend produced each story, files read/written, key outputs
  • DoD compliance -- per-story and sprint-level DoD check results
  • Sprint metrics -- velocity, stories planned vs completed, carry-over count
  • Context packages (if Discover was run)
  • Next-action suggestion -- what to do next based on current state

Check status when:

  • Resuming after a break -- to orient yourself before continuing
  • Mid-sprint -- to check story pipeline progress
  • After Sprint Review -- to see the full sprint metrics
  • Debugging state issues -- to verify lifecycle state is correct

Visualization

Three complementary views are auto-generated after ceremony completions and session end.

1. Terminal dashboard -- "show status"

The live view described above. Always current, always available. Say "status" or "show progress" in your Claude Code session.

2. Markdown journal -- .synaptory/PIPELINE.md

Auto-generated at ceremony completions and session end. A persistent record that tracks:

  • Lifecycle timeline with ceremony timestamps and durations
  • Story receipts: which agent and backend produced each story, verification results
  • DoD evaluation results per story and per sprint
  • Inception Gate decisions and rework cycles
  • Sprint metrics (velocity, completion rate, carry-over)
  • Context packages

3. HTML dashboard -- .synaptory/PIPELINE.html

A dark-theme, self-contained HTML file. Contains:

  • Summary cards (sprints completed, stories done, tests written, findings)
  • Story pipeline visualization
  • Agent/backend performance comparison
  • Sprint metrics over time
  • DoD compliance trends

Open in any browser -- fully self-contained with inline CSS and data.

Re-Anchoring

What it is

Re-anchoring is the process of re-reading key artifacts (BRD, ADRs, API contracts, receipts, context packages) directly from disk before spawning agents or continuing work. It prevents silent context degradation where the model's memory of architecture decisions drifts over long runs.

When it triggers automatically

  1. Before context compaction -- the synaptory-reanchor.sh hook fires on the PreCompact event. Before Claude Code compresses the context window, the hook re-injects critical artifacts so they survive compaction intact.
  1. At ceremony transitions -- the orchestrator re-reads key artifacts from disk before starting each ceremony. For example, before Sprint Planning, the orchestrator re-reads ADRs, prior sprint feedback, and the current backlog.

What gets re-anchored

  • docs/requirements/BRD.md -- the approved Business Requirements Document
  • docs/architecture/adr/*.md -- Architecture Decision Records
  • api/openapi/*.yaml -- API contracts
  • .synaptory/.orchestrator/receipts/*.json -- story-scoped receipts
  • .synaptory/.orchestrator/context-packages/*.md -- brownfield context packages
  • Sprint state and story pipeline state

Manual trigger

If you suspect context degradation (agents seem to forget architecture decisions):

/synaptory -- re-anchor context

Symptoms of degradation:

  • An agent produces output that contradicts an ADR
  • An agent asks a question already answered in the BRD
  • Tests target the wrong API endpoints or data model

Resuming After a Break

Step-by-step

  1. Open the project in Claude Code. The synaptory-session-start.sh hook fires automatically, loading lifecycle state and context packages.
  1. Check where you are:

`` show status `` This shows the current ceremony, story pipeline status, and pending work.

  1. Continue:

`` continue sprint next sprint resume sprint 3 ` Or for Kanban projects: ` pull next ticket what's next `` The orchestrator reads state and picks up where it left off.

  1. If a gate was pending, the orchestrator re-presents it.
  1. If an agent had failed, check the escalation report and decide how to proceed.

What if the state seems wrong?

If "show status" reveals incorrect state:

  1. Check the raw state:

``bash cat .synaptory/.orchestrator/pipeline-state.json ``

  1. For Scrum state issues:

``bash python3 /path/to/plugin/hooks/lib/scrum_state_machine.py read "$(pwd)" ``

  1. For Kanban state issues:

``bash python3 /path/to/plugin/hooks/lib/kanban_state_machine.py read "$(pwd)" ``

  1. Manual state correction (use with caution):

``bash python3 /path/to/plugin/hooks/lib/state_machine.py transition "$(pwd)" SPRINT_REVIEW ``

Long multi-session builds

For projects that span multiple sessions (days or weeks):

  • Lifecycle state, receipts, and context packages all persist on disk
  • The session start hook re-injects everything on each new session
  • The re-anchor hook protects against context degradation within long sessions
  • Sprint boundaries are natural session boundaries: complete a sprint, stop, come back tomorrow, start the next sprint
  • Kanban tickets are natural units too: finish a ticket, stop, resume with the next one

What's next?

Guides · 19

Using the Control Plane

Single browser app for every signed-in synaptory-users member. Lives at https://synaptory.h3t.co/. Pages are role-aware — what you see is auto-scoped to what your Entra group membership and project_members rows grant.

Per ADR-019 the legacy /console/* (admin) and /portal/* (member) URL trees were collapsed into one tree at root URLs. There is no longer a separate "Console" or "Portal" — admins, project admins, project members, and unaffiliated users all use the same pages; the data they see differs.

If you've never signed in: open https://synaptory.h3t.co/ in a browser. You'll be redirected to Entra, then back to the root page, which redirects you to /overview (if you're a global admin) or /home (everyone else). Same Entra app, same redirect URI as the CLI uses — see Auth flows.


Page reference

The Control Plane mounts a single AppChrome (collapsible sidebar, theme toggle, user-menu) with the brand subtitle "CONTROL PLANE". Sidebar entries are filtered by your role — admin-only pages (Overview, Policy, System, Grafana, Settings, Access review) only render in the sidebar for callers in synaptory-admins.

PathPurposeVisible toBacked by
/Role-aware redirect (admin → /overview, else → /home)everyoneserver redirect, no API call
/homeIdentity card + quick linkseveryonesession cookie, no API call
/overviewKPI band, gate queue (4 v3 gates), recent activityglobal admin/v1/analytics/overview, /v1/analytics/evidence-gates
/projectsProjects you can see (admins can pass ?all=true)everyone/v1/projects
/projects/<slug>Project detail + Members tabeveryone with a role on the project/v1/projects/<slug>
/projects/<slug>/overviewProject cockpit (per-project KPIs)project admin + global adminscope-aware analytics
/auditAudit log with detail drawereveryone (scope-aware)/v1/analytics/audit, /v1/analytics/audit/<id>
/sessionsSessions list with two-step revokeeveryone (scope-aware)/v1/sessions, DELETE /v1/sessions/<id>, POST /v1/sessions/revoke-all
/skillsManifest + your usage statseveryone/v1/skills/manifest, /v1/analytics/skill-distribution
/qualityEvidence/DoD scoreboard, per-spec gate matrix, per-role pass-rateeveryone (scope-aware)/v1/analytics/evidence-gates, /v1/analytics/specs/quality
/costUSD compute, per-stage spend, per-model rollup, fallback wasteeveryone (scope-aware)/v1/analytics/cost/*
/reliabilityOTLP latency p50/p95/p99, top errors, fallback waste, outbox healtheveryone (scope-aware)/v1/analytics/reliability/*
/peoplePer-Delivery-Owner activity, time-of-day heatmap, new-vs-returning cohorteveryone (scope-aware)/v1/analytics/people/*
/policyRead-only signed-config viewerglobal admin/v1/config/*
/systemProbes + versions + security mode + last backupglobal admin/v1/admin/system/health
/settingsOperator settingsglobal admin/v1/admin/*
/grafanaGrafana iframeglobal adminGrafana via Caddy reverse-proxy
/access-reviewPeriodic access reviewglobal adminscope-aware /v1/analytics/people/access-review
/profileIdentity / groups / sign-out / sign-out-everywhereeveryonesession cookie + POST /v1/sessions/revoke-all

How role gating works

The same page renders for every viewer; the data and controls differ:

  • Global admin (synaptory-admins): sees everything. Cross-UPN visibility on /audit, /sessions. All projects on /projects. Project create / archive controls visible on /projects.
  • Project admin (project_members.role = 'admin'): sees their admin projects' analytics with cross-UPN visibility within those projects. Members tab shows invite / revoke / promote.
  • Project member (project_members.role = 'member'): sees their member projects' analytics filtered to their own UPN. Members tab is read-only.
  • Unaffiliated: sees identity, sessions, skills (manifest only), and (Phase 2b) the access-request workflow. Analytics return empty.

Anti-leak: every endpoint that takes ?project=<slug> returns 404 (not 403) when the caller can't see the project. Status codes never confirm existence of projects you don't have a role on.


Project filtering

Most analytics pages accept ?project=<slug> to scope every chart and table to one project. The explicit ?project=all sentinel restores the caller's full visible scope. Two pages are intrinsically global and ignore the param: /projects (the project list itself) and /grafana (Grafana has its own filtering UI).

When you select a project from the project picker in the header, every page link in the sidebar carries the ?project=<slug> param forward.


Overview: the gate queue

The Overview page's headline component is the Gate Queue card, which renders all four v3 gates:

  1. Inception — has the project's Sprint 0 produced a signed-off vision?
  2. Spec Ready — for the active sprint, are the stories spec-complete?
  3. Evidence / DoD — for stories in reviewing, are receipts + verification commands present? (This is the only gate with a wired backend signal in v2.5 — the others are placeholders that light up in place when v3.0 ships.)
  4. Release — are sprint outcomes shippable?

The Evidence/DoD gate maps to the enforcement model you already know from the plugin guide.


Quality: per-spec gate matrix

The Quality page is the operator's view of the Evidence/DoD gate. Three sections:

  • Scoreboard — pass-rate over time, broken out by gate sub-signal (tests-pass, build-succeeds, no-critical-findings, code-reviewed, coverage-no-decrease).
  • Per-spec gate matrix — a grid of stories (specs in v3) × gates. Hover for the receipt link.
  • Per-role pass-rate — which roles produce the most failing receipts. Use this to spot a flaky agent.

In v2.5 vocabulary: "spec" = "story" with kind=story; the spec model expands in v3 to include feature, bugfix, task, release. The current grid only contains stories.


Cost: USD compute breakdown

Cost endpoints aggregate Receipt.payload.token_usage against pinned per-model rates in MODEL_PRICING_USD_PER_M (api/synaptoryapi/routers/analytics.py). Four panels:

  • Summary — total spend window-over-window, with cache-hit ratio.
  • By stage — 11 v3 stages (pro-discovery, pro-brd, pro-ux-spec, sa-architecture, se-implementation, qe-verification, cr-review, ce-compliance, pe-infra, tw-docs, orchestrator).
  • By model — per Claude model, USD spent and tokens used.
  • Fallbacks — when a higher tier failed and the orchestrator dropped to a lower one. "Waste" = tokens spent on the failed call.

Pricing changes are reviewable diffs alongside model-pins.json for AI-BOM provenance.


Reliability: latency and errors

Driven by OTLP spans the CLI emits via synaptory otel. Stored in OtelEvent.payload; aggregated inline today, with an otel_rollup materialized table queued for when span volume crosses ~10k/window.

Three panels:

  • Latency — p50/p95/p99 over time. Per-stage and per-role breakouts.
  • Errors — top error messages by frequency. Click for the receipts that produced them.
  • Outbox health — telemetry queue depth on the CLI side, derived from when batches arrive late.

People: who's delivering

  • Staff activity — receipts per UPN over the window (scope-aware: project members see only their own UPN).
  • Heatmap — 7×24 grid of activity (day of week × hour). Useful for spotting after-hours work patterns.
  • Cohorts — new vs returning Delivery Owners over the window.

In v3.0 vocabulary, "staff" → "Delivery Owner" — the human counterpart to the Project Owner agent.


Projects: provisioning and members

/projects lists every project the caller can see. By default that's the caller's active memberships; global admins can pass ?all=true. Per-slug pages cover:

  • Project Overview — slug, created at, archive status, KPI strip scoped to the project.
  • Members tab — invite / revoke / promote. Visible to project admins (or global admins) on projects where they hold that role; read-only for plain members.
  • Settings — project-level config overrides (admin-only).

Provisioning a new project is currently CLI-side: ./synaptory api projects create <slug> on the prod VM. Members can be added via the Control Plane afterward.


Audit: who did what

Receipts + admin actions in one timeline. Filter by UPN (admin only), project, action, time window. Click a row → drawer with the full receipt or audit-event payload.

The audit log includes admin writes (revoke, invite, archive) — not just delivery receipts. Use this as the forensics surface.

Project members see only their own UPN's rows on /audit. Project admins see cross-UPN rows for their admin projects. Global admins see everything.


Sessions: server-side revoke

/sessions lists scope-aware sessions. Project members see only their own; project admins see all UPNs active in their admin projects; global admins see all. Each row has a two-step revoke button.

The two-step revoke is deliberate friction. Click once → confirm. The component is <ConfirmDestructiveAction>; same primitive used in any destructive action. There's no "are you sure?" modal — the button text changes to "Confirm revoke" and you click again.

Sign-out everywhere: there's a single button on /profile that hits POST /v1/sessions/revoke-all. Use this if you've lost a laptop or suspect token compromise.

A revoked session is rejected on the next API call from that session — there's no push to the laptop. The plugin's CLI will surface a re-run synaptory login prompt within a hook lifecycle.


Skills: manifest and per-skill usage

Two tabs:

  • Manifest — every skill name + tier + description. The same payload /v1/skills/manifest returns to the CLI on session start. Shared across all users.
  • Distribution / Usage — usage histograms per skill (admin); your own usage stats (non-admin). The page reads the scope-aware /v1/analytics/skill-distribution endpoint, which auto-filters non-admins to their own UPN.

The Distribution view reads from Receipt.payload aggregations.


Policy: read-only signed-config

/policy is a read-only viewer of the current signed configuration that the CLI fetches via /v1/config/*. Useful for verifying what policy is live without round-tripping through a CLI call.

The signature is verified server-side on render; if it doesn't verify, the page shows an error and the Audit log carries a warning.

Global admin only.


System: health and versions

Probes, container versions, Postgres replication state, last backup timestamp, current security mode (baa_enforced flag and friends).

Use this as the first stop when you suspect platform-wide trouble. Global admin only.


Profile: sign-out everywhere

/profile shows:

  • Identity card — UPN, display name (from Entra), groups (synaptory-users plus any others), platform access badge.
  • Groups list — every group on your session.
  • Sign-out button (just this session).
  • Sign-out-everywhere button — revokes every active session under your UPN.

In Phase 2b: full current-session card + plugin/CLI install-verification card.


What's next

Guides · 20

Inviting Members to a Project

The end-to-end flow for granting and revoking project access.

Project membership is one piece of state with multiple write paths. This guide covers all of them so you can pick the right tool for the role you're playing.


What "membership" actually means

A row in the project_members table. Schema (simplified):

ColumnMeaning
project_idForeign key into projects
upnThe Entra UPN (user@h3t.co)
rolemember or admin (project-level role, not platform-level)
added_atTimestamp
revoked_atNull while active; set when revoked

The check at api/synaptoryapi/security.py check_project_membership reads this table on every project-scoped API call. There's no caching layer — revoke takes effect on the user's next request.


Three ways to grant access

1. Project admin via the Control Plane

You are: a signed-in user with role=admin on the target project (i.e. you hold the project-admin grant on project_members).

You go to: /projects/<slug> → Members tab → "Invite member" button.

You enter: a UPN. The user must already be a member of synaptory-users (you can't invite people who haven't been provisioned in Entra). The form rejects unknown UPNs with a 404.

The new member is active immediately. They'll see the project on /projects the next time they refresh.

2. Global admin via the Control Plane

You are: a member of synaptory-admins.

You go to: /projects/<slug> → Members tab.

The UI is identical to what project admins use — same <ConfirmDestructiveAction> primitive, same invite form, same backend endpoint (POST /v1/projects/<slug>/members). The only difference is that you can do this on any project, not just ones where you hold a project-admin role.

3. Operator via CLI

You are: an operator with shell access to the prod VM.

You run: ./synaptory api projects add-member <slug> <upn>.

Use this when the Control Plane is down, when you're seeding a fresh project, or in CI for test fixtures.


Revoke

Same three paths, mirrored:

SurfaceAction
Members tab (/projects/<slug>)Two-step revoke button per row. Visible to project admins on their projects, to global admins on any project.
CLI./synaptory api projects revoke <slug> <upn>

A revoked member's revoked_at is set; the row stays in the table for audit. To re-add, an admin re-invites — a new row is created.


Promote / demote

A project admin can promote a member to admin and demote back, but only on projects they admin. Global admins can do it anywhere.

The CLI doesn't currently expose a promote command directly — use the Control Plane Members tab for promotion, or write the SQL by hand if the web app is unavailable.


What a new member sees

Within seconds of being added:

  • /projects lists the new project.
  • /projects/<slug> opens (Overview tab).
  • synaptory status on their CLI lists the project under their memberships.
  • cd into a directory configured for that project's slug; the plugin works.

If they were a member before, were revoked, and are now re-added: the new row is treated as a new membership. The old revoked_at row stays for audit; the new row has revoked_at=null.


What gets logged

Every grant / revoke / promote produces an audit row. View at /audit (filter by action=member.grant etc.) or query the audit_events table directly.

The audit row carries: who did it, who was affected, the project, the resulting role, and a free-text reason (if the form prompted for one — the Control Plane Members tab does; the CLI doesn't).


Common gotchas

  • "User not found" — the UPN isn't in the local Entra group. Add to synaptory-users in Entra first, then invite to the project.
  • "Already a member" — there's an active row already. The form deduplicates; nothing's wrong.
  • Plugin still 404s after invite — the user's CLI is using a cached SYNAPTORY1 token that pre-dates the invite, but membership is checked per-request, so this shouldn't matter. If it persists, ask the user to run synaptory status to force a fresh API hit.
  • Project archived — archived projects return 403 on every member-write. Unarchive via the Control Plane (/projects/<slug> → settings) first; this is global-admin only.

What's next

Reference · 21

Configuration Reference

Diataxis category: Reference -- information-oriented, for lookup.

synaptory reads its project configuration from .synaptory.yaml at the project root. This file controls delivery lifecycle, agent backends, project identity, directory mapping, tooling preferences, feature toggles, brownfield behavior, Definition of Done, and architecture settings.

The canonical schema with all supported keys, types, defaults, and valid values is maintained in: plugin/skills/_shared/templates/synaptory.yaml.tmpl


Session authentication

synaptory authenticates via your organisation's Entra ID. No token files needed.

On first session start a browser tab opens to complete sign-in. The session is cached in the OS keychain and refreshed silently until it expires (typically 24 hours).

Run synaptory whoami to inspect the cached session at any time. For headless environments, run synaptory login --device once from a terminal and follow the on-screen instructions.

All skill access is scoped to your session identity. Usage is watermarked and auditable by your H3Tech operator.


Auto-configure your project

The recommended way to create .synaptory.yaml is to say "initialize my project". The orchestrator scans the project and generates a tailored config.

initialize my project

What initialization auto-detects

SignalDetection source
Languagepackage.json, go.mod, pyproject.toml, Cargo.toml, pom.xml
Frameworknext.config.*, nest-cli.json, fastapi, gin, actix
InfrastructureDockerfile*, terraform/, k8s/, .github/workflows/
Architecturemonolith, modular-monolith, microservices, monorepo
Project healthtest density, TODO/HACK density, git depth, coverage config, documentation level

The orchestrator shows a detection summary and asks before writing. Review the output before approving -- particularly paths.* for non-standard directory names.


Config keys

project_id

Control-plane project scope. The CLI uses this to scope auth, telemetry, and skill fetch.

Precedence: SYNAPTORY_PROJECT_ID env > this value > the single cached keychain session.

project_id: "my-project"   # slug assigned by your H3Tech operator

build_mode

Delivery lifecycle for the project.

ValueBehavior
"scrum"(Default) Time-boxed sprint delivery. Inception -> Sprint loop -> Release. For greenfield or brownfield projects.
"kanban"Continuous ticket-based flow. Discover -> Ready -> Execute -> Review -> loop. For brownfield/post-launch maintenance.
build_mode: "scrum"   # or "kanban"

engagement_mode

Controls decision visibility and model routing strategy for agents.

ValueBehavior
"structured"(Default) Opus for strategic/decision roles (PO, SA, CE, RA). Sonnet for executor roles (SE, QE, PE, TW, CR). Agents decide and report without surfacing every choice.
"interactive"Same model tiers as structured — no cost premium. Strategic roles surface all major decisions for human review before proceeding. Use for compliance-sensitive builds or when you need an audit trail of every decision.

Aliases: autonomous and hands-off are accepted as aliases for structured. controlled and hands-on are accepted as aliases for interactive. New config should use the canonical names.

engagement_mode: "structured"   # structured | interactive

agents.*

Agent backend configuration. All agents in this build run on Claude.

KeyTypeDefaultDescription
agents.default_backendstring"claude"Backend for all agents. Only claude is supported in this build.

The Orchestrator always runs on Claude. Model tier (Opus vs Sonnet) is determined by engagement_mode and role type — not configurable per role.

agents:
  default_backend: "claude"

tracker.*

Ticket tracker backend for story, epic, sprint, and backlog management.

KeyTypeDefaultDescription
tracker.backendstring"local"Backend provider: local, github, jira, teamwork.
tracker.github.repostring""GitHub repo (owner/repo). Auto-detected from git remote if empty.
tracker.github.points_label_prefixstring"points:"Label prefix for story points.
tracker.github.sprint_milestone_prefixstring"Sprint "Milestone naming prefix.
tracker.jira.urlstring""Jira Cloud URL (e.g., https://team.atlassian.net).
tracker.jira.project_keystring""Jira project key (e.g., ANC).
tracker.jira.board_idintnullScrum board ID. Auto-detected if null.
tracker.teamwork.site_namestring""Teamwork subdomain.
tracker.teamwork.project_idint0Numeric project ID.
tracker.teamwork.sprint_milestone_prefixstring"Sprint "Milestone naming prefix.
tracker.teamwork.workflow_stagesobjectMaps synaptory statuses to Teamwork board column IDs.

The local backend works in any build_mode. Remote backends (github, jira, teamwork) require build_mode: scrum.

tracker:
  backend: github
  github:
    repo: myorg/my-project

specs[] — multi-spec (opt-in, since v2.7 / v2.8)

When a top-level specs: block is present, one tracker project (Jira / GitHub repo / Teamwork project) hosts N partitioned backlogs. See the Multi-Spec Delivery guide for the full workflow, runbook, and migration script.

Every spec carries exactly one backend binding (jira: / github: / teamwork:), matching tracker.backend. Mixed bindings are rejected at config-load time. Multi-spec is not supported on tracker.backend: local.

KeyTypeDescription
specs[].idstringkebab-case spec id (used in --spec flags, directory names).
specs[].namestringHuman-readable label for the spec.
Jira binding
specs[].jira.urlstringJira Cloud URL. Must agree across specs (single project).
specs[].jira.project_keystringJira project key. Must agree across specs.
specs[].jira.board_idintSpec's Scrum board id (one per spec).
specs[].jira.filter.typeenumlabel \
specs[].jira.filter.valuestringLabel name, component name, epic key, or raw JQL fragment.
GitHub binding
specs[].github.repostringowner/repo. Must agree across specs.
specs[].github.sprint_milestone_prefixstringOptional per-spec milestone prefix override.
specs[].github.filter.typeenumlabel \
specs[].github.filter.valuestringLabel name or milestone title.
Teamwork binding
specs[].teamwork.site_namestringTeamwork subdomain. Must agree across specs.
specs[].teamwork.project_idintNumeric Teamwork project id. Must agree across specs.
specs[].teamwork.filter.typeenumtag \
specs[].teamwork.filter.valuestringTag name (auto-resolved to tag id) or numeric tasklist id (as string).

When specs: is absent (default), single-spec behavior is unchanged. When specs: is present, the legacy top-level tracker.<backend> block is ignored if it agrees with every spec, and rejected if it disagrees.

# Jira example
tracker:
  backend: jira
specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    jira:
      url: "https://hano.atlassian.net"
      project_key: "HT"
      board_id: 136
      filter:
        type: "label"
        value: "platform"

# GitHub Issues example
tracker:
  backend: github
  github:
    repo: "h3tco/hiro-app"
specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    github:
      repo: "h3tco/hiro-app"
      filter:
        type: "label"
        value: "platform"

# Teamwork example
tracker:
  backend: teamwork
  teamwork:
    site_name: "hano"
    project_id: 999
specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    teamwork:
      site_name: "hano"
      project_id: 999
      filter:
        type: "tag"
        value: "platform"

To migrate an existing single-spec project, run migrate_to_multispec.py.


project.*

Project identity. Drives agent decisions for tech stack selection, scaffold structure, and execution patterns.

KeyTypeDefaultValid valuesDescription
project.namestring""anyProject name used in reports and docs.
project.languagestring""typescript, go, python, rust, javaPrimary language. Determines tech pack loading.
project.frameworkstring""nestjs, express, fastapi, gin, actix, springServer framework.
project.cloudstring""aws, gcp, azureCloud provider.
project.architecturestring""monolith, modular-monolith, microservicesArchitecture pattern.
project.typestring"greenfield"greenfield, brownfield, evolved_brownfield, mixedProject type.
project.templatestring""nextjs-fullstack, express-api, python-fastapi, react-native, flutter, cli-tool, monorepoGreenfield scaffold archetype.
project:
  name: "my-service"
  language: "typescript"
  framework: "nextjs"
  cloud: "aws"
  architecture: "modular-monolith"
  type: "greenfield"
  template: "nextjs-fullstack"

paths.*

Directory mapping. Critical for existing codebases with non-standard layouts.

KeyTypeDefaultDescription
paths.servicesstring"services/"Backend services directory.
paths.frontendstring"frontend/"Frontend application directory.
paths.testsstring"tests/"Test files directory.
paths.iacstring"infra/opentofu/"IaC root directory. Derived from preferences.iac_tool.
paths.ci_cdstring".github/workflows/"CI/CD pipeline definitions.
paths.docsstring"docs/"Documentation directory.
paths.roadmapstring"docs/requirements/ROADMAP.md"Product roadmap file.
paths.reportsstring"reports"Sprint and pipeline reports directory.
paths.workspacestring".synaptory/"synaptory internal workspace.
paths.brdstring"docs/requirements/"PO documentation output.

preferences.*

Tooling choices. Agents respect these instead of making their own selections.

KeyTypeValid valuesDescription
preferences.test_frameworkstringjest, vitest, pytest, go-test, junitTest runner.
preferences.ormstringprisma, drizzle, typeorm, sqlalchemy, gormORM / query builder.
preferences.ci_providerstringgithub-actions, gitlab-ci, circleciCI/CD provider.
preferences.package_managerstringnpm, pnpm, yarn, bunPackage manager.
preferences.linterstringeslint, biome, ruff, golangci-lintLinter.
preferences.formatterstringprettier, biome, black, gofmtFormatter.
preferences.frontend_frameworkstringnextjs, nuxt, sveltekit, remixFrontend meta-framework.
preferences.state_managementstringreact-query, redux, pinia, svelte-storesClient-side state management.
preferences.stylingstringtailwind, css-modules, styled-components, vanilla-extractCSS / styling.
preferences.iac_toolstringopentofu, terraform, pulumiInfrastructure as Code tool. Default: opentofu.

features.*

Feature toggles.

KeyTypeDefaultDescription
features.frontendbooltrueSet false for API-only projects.
features.ai_mlboolfalseActivates SE ai-ml mode.
features.multi_tenancyboolfalseEnables tenant isolation patterns.
features.documentation_siteboolfalseGenerates documentation site at Release.
features.real_timeboolfalseWebSocket/SSE support.
features.graphqlboolfalseGraphQL API alongside REST.
features.grpcboolfalsegRPC inter-service communication.
features.event_drivenboolfalseAsync messaging patterns.
features.payment_integrationboolfalsePayment service patterns.

brownfield.*

Settings for existing codebases.

KeyTypeDefaultDescription
brownfield.coverage_ratchetbooltrueEnforce coverage-ratchet: agents must write tests before modifying untested files.
brownfield.context_packagesbooltrueAuto-load Discover context packages into all agents.
brownfield.characterization_testsbooltrueGenerate behavior-capturing tests during Discover.

sprint.*

Scrum delivery settings. Active when build_mode: scrum.

KeyTypeDefaultDescription
sprint.inceptionstring"foundation"Inception mode: foundation (just enough for Sprint 1) or blueprint (comprehensive upfront plan).
sprint.protected_moduleslist[]Paths the SE must confirm before touching. Supports glob strings or objects with path + reason.
sprint.constraintslist[]Architectural rules prepended to every SE prompt.
sprint.velocityint or nullnullAverage story points per sprint. Used to cap sprint scope.
sprint.carry_over_policystring"move_to_next"Incomplete story handling: move_to_next, keep_in_sprint, ask.
sprint.require_context_injectionboolfalseSE must read existing module code before implementing.
sprint.read_before_writeboolfalseSE must Read() every file before modifying.
sprint.characterization_tests_firstboolfalseQE must write tests before SE touches legacy code.
sprint:
  inception: "foundation"
  protected_modules:
    - path: "src/modules/billing/"
      reason: "Financial regression risk"
  constraints:
    - "Every new endpoint MUST use @CurrentTenant()"
  velocity: 21
  carry_over_policy: "move_to_next"

dod

Definition of Done -- two-layer model. Per-story DoD is evaluated as each story completes the SE->QE->CR pipeline. Sprint-level overlay is evaluated at Sprint Review (Scrum only).

dod.story -- Per-story DoD (both Scrum and Kanban)

KeyTypeDescription
dod.story.auto_check[].idstringCheck identifier (e.g., tests-pass, build-succeeds).
dod.story.auto_check[].descriptionstringHuman-readable description.
dod.story.auto_check[].criticalboolIf true, story is blocked when check fails.
dod.story.auto_check[].agentstringAgent responsible (optional).
dod.story.auto_check[].adaptiveboolIf true, check scales with maturity (e.g., skip Sprint 1).

dod.sprint -- Sprint-level overlay (Scrum only)

KeyTypeDescription
dod.sprint.human_check[]stringItems requiring human verification at Sprint Review.
dod.sprint.auto_check[].idstringAutomated check identifier.
dod.sprint.auto_check[].criticalboolIf true, sprint review is blocked when check fails.
dod:
  story:
    auto_check:
      - id: tests-pass
        description: "All acceptance criteria tests passing"
        critical: true
      - id: build-succeeds
        description: "Build completes and dev server starts"
        critical: true
      - id: no-critical-findings
        description: "Zero Critical security findings"
        critical: true
        agent: compliance-engineer
      - id: code-reviewed
        description: "Story code reviewed"
        critical: false
        agent: code-reviewer
        adaptive: true
      - id: coverage-no-decrease
        description: "Test coverage did not decrease"
        critical: false
  sprint:
    human_check:
      - "Sprint Goal met"
      - "Stakeholder feedback addressed"
      - "Documentation updated"
    auto_check:
      - id: no-regression
        description: "No regression across sprint stories"
        critical: true

dor

Definition of Ready. Used to validate stories before sprint commitment.

KeyTypeDefaultDescription
dor.filestring""Path to a DoR markdown file. Parser reads bullet lines.
dor.inlinelist[]Inline DoR criteria when file is empty.

architecture

Solution Architect settings.

KeyTypeDefaultDescription
architecture.health_check_intervalint3Run SA health check every N sprints (0 = disabled).
architecture.triggerslist[new_entity, new_service, new_integration, security_requirement, performance_story]Auto-detect triggers for SA invocation.

story_buddy

Story Buddy settings.

KeyTypeDefaultDescription
story_buddy.issue_templateslist[]Paths to issue template files for story structural validation.

Complete examples

Greenfield SaaS (Scrum)

version: "3.0"
build_mode: "scrum"
engagement_mode: "structured"

project:
  name: "reservation-saas"
  language: "typescript"
  framework: "nextjs"
  cloud: "aws"
  architecture: "modular-monolith"
  type: "greenfield"
  template: "nextjs-fullstack"

agents:
  default_backend: "claude"

sprint:
  inception: "foundation"
  carry_over_policy: "move_to_next"
  velocity: 21

tracker:
  backend: "github"
  github:
    repo: "myorg/reservation-saas"

preferences:
  test_framework: "vitest"
  orm: "prisma"
  package_manager: "pnpm"
  frontend_framework: "nextjs"
  styling: "tailwind"

features:
  frontend: true
  multi_tenancy: true
  payment_integration: true
  real_time: true

Brownfield API (Kanban, maintenance)

version: "3.0"
build_mode: "kanban"
engagement_mode: "structured"

project:
  name: "payments-api"
  language: "typescript"
  framework: "express"
  cloud: "aws"
  architecture: "monolith"
  type: "brownfield"

agents:
  default_backend: "claude"

tracker:
  backend: "jira"
  jira:
    url: "https://myteam.atlassian.net"
    project_key: "PAY"

paths:
  services: "src/"
  tests: "test/"

preferences:
  test_framework: "jest"
  orm: "typeorm"

features:
  frontend: false

brownfield:
  coverage_ratchet: true
  context_packages: true
  characterization_tests: true

What's next?

Reference · 22

Commands Reference

Diataxis category: Reference -- information-oriented, for lookup.

All commands available in synaptory: slash commands (user-facing skills), the synaptory Go CLI, state machine CLIs (lifecycle internals), and admin scripts.


Slash commands

CommandWhat it doesWhen to use
/synaptoryStarts or continues the adaptive delivery lifecycle. Classifies the request into an operation mode and routes to the appropriate agents. Also handles init, status, help, and reporting via natural language.Any build, sprint, kanban, debug, review, story buddy, init, status, help, or other task.

Modes within /synaptory

The following capabilities are triggered by natural language. See Modes for behavioural detail and Routing for the full trigger table and tiebreakers.

ModeTrigger phrasesWhat it does
Build"build a SaaS", "from scratch", greenfield intentFull Scrum lifecycle: Inception -> Sprint loop -> Release
Sprint"sprint N", "next sprint", "continue sprint"Routes to current ceremony in an active Scrum project
Kanban"fix ticket", "work on TICKET-xxx", "maintenance"Continuous ticket flow for brownfield projects
Doctor"doctor", "diagnose", "check config", "validate config"Read-only configuration diagnostic. Pass/warn/fail report with remediation guidance.
Init"initialize", "configure project", "set up synaptory"Project detection + .synaptory.yaml generation
Status"status", "progress", "where are we"Lifecycle state dashboard
Help"help", "what can you do"Quick reference card
Report"report a bug", "report an issue"Gather context + file GitHub issue against the synaptory repo
Story Buddy"analyze US-037", "implement story", "test story", "help plan sprint"Per-story assistance (Requirements / Implement / Test / Sprint Plan)
Debug"debug", "fix this bug", "not working", "error"4-phase root-cause analysis: Reproduce -> Isolate -> Understand -> Fix
Explore"help me think", "what should I", "I'm not sure"Research Advisor thinking partner
Discover"understand this codebase", "map the system"Reverse-engineer codebase, build context packages
Context Refresh"update context", "refresh context"Incremental re-analysis of changed files
Preview"preview", "run it", "start server", "launch"Dev server launch and smoke test
Branch Finish"finish this branch", "merge", "create PR"Per-branch verification and merge
Retro"retro", "what did we ship", "metrics"Standalone engineering retrospective
Test"write tests", "test coverage", "add tests" (no story ID)Quality Engineer generates tests for working code
Review"review my code", "code review", "code quality"Code Reviewer adversarial read-only analysis
Architect"design", "API design", "data model", "tech stack"Solution Architect: ADRs, contracts, ERDs
Document"document", "write docs", "API docs", "README"Technical Writer documentation generation
Optimize"performance", "slow", "optimize", "scale"Platform Engineer + Code Reviewer perf work
Stabilize"characterization tests", "before refactoring", "coverage ratchet"Quality Engineer + Code Reviewer pre-refactor safety net
Modernize"modernize", "migrate", "strangler fig", "migration plan"Solution Architect + Compliance Engineer migration plan
Custom(no other mode matches)Skill menu — pick the agent and scope
Release"release", "ship it", "go live"Full verification + production prep
Update(auto, before every other mode)Silent plugin version check; one-question prompt if newer version available

Automatic invocation

You do not need to prefix every request with /synaptory. The orchestrator is invoked automatically when you type a natural language request. Activation rules define keyword and intent patterns that route to the appropriate mode.

Examples:

Build me a SaaS for managing restaurant reservations
Add Stripe payment integration
Review my code
Debug -- login endpoint returns 500
Finish this branch
initialize my project
show status

CLI commands

The synaptory Go CLI is shipped separately from the plugin and installed once per laptop via https://synaptory.h3t.co/cli/install.{sh,ps1} — see Install the CLI. It handles authentication, skill delivery, telemetry, and policy sync. Plugin hooks shell out to the synaptory binary on $PATH; you can also run it directly from a terminal.

CommandWhat it does
synaptory login [--device]Sign in via Entra ID. --device for headless environments.
synaptory logoutRevoke cached session and clear keychain entry.
synaptory whoamiPrint cached UPN, project, token expiry and time remaining.
synaptory statusFull diagnostic: auth state, skill cache size, outbox depth.
synaptory skills syncFetch manifest and pull missing/stale skills into cache.
synaptory skills listList cached skills.
synaptory skills get <name>Print cached body for a skill; live fetch on cache miss.
synaptory config fetch [--if-stale]Pull policy from control-plane; update local cache.
synaptory config envPrint cached policy summary (version, backends, roster).
synaptory projects listList control-plane projects the current user has access to.
synaptory projects currentShow the active project for this directory.
synaptory outbox listInspect queued telemetry events.
synaptory outbox flushManually force outbox flush to control-plane.
synaptory versionPrint CLI version.

State machine CLIs

synaptory uses separate state machines for Scrum and Kanban lifecycles, plus a shared story pipeline. All are in plugin/hooks/lib/.

Scrum state machine

python3 scrum_state_machine.py <action> <project_dir> [args]
ActionDescription
readPrint the full Scrum lifecycle state JSON
initInitialize a new Scrum lifecycle
transitionTransition to the next ceremony state
start_sprintStart Sprint Execution from Sprint Planning with sprint goal and story list
complete_sprintClose Sprint Execution and move to Sprint Review
close_sprintClose the sprint and continue to the next sprint or Release
add_storyAdd a story to the active sprint backlog
transition_storyMove a story through the shared story pipeline
evaluate_dodEvaluate per-story Definition of Done
velocityCalculate sprint velocity metrics
summaryBuild sprint summary data
retro_checkEvaluate whether Sprint Retro is needed
transition_to_kanbanConvert a completed Scrum project to Kanban mode

Scrum lifecycle states:

INCEPTION -> SPRINT_PLANNING -> SPRINT_EXECUTION -> SPRINT_REVIEW
          -> SPRINT_RETRO (adaptive) -> SPRINT_CLOSE -> (loop) -> RELEASE -> COMPLETE

Kanban state machine

python3 kanban_state_machine.py <action> <project_dir> [args]
ActionDescription
readPrint the full Kanban lifecycle state JSON
initInitialize a new Kanban lifecycle
transitionTransition to the next state
pull_ticketPull a ticket into the active Kanban board
complete_ticketMove a completed ticket into history
transition_storyMove a ticket through the shared story pipeline
evaluate_dodEvaluate per-ticket Definition of Done
throughputCalculate throughput metrics over a time window
summaryBuild Kanban summary data

Kanban lifecycle states:

DISCOVER -> READY -> EXECUTION -> REVIEW -> (loop to READY) -> RELEASE -> COMPLETE

Shared state dispatcher

python3 state_machine.py <action> <project_dir> [args]

Thin dispatcher for lifecycle bootstrap and state reads. It does not proxy the full Scrum or Kanban command surface.

ActionDescription
readPrint the full lifecycle state (routes to Scrum or Kanban)
init_scrumInitialize a new Scrum lifecycle
init_kanbanInitialize a new Kanban lifecycle

Story pipeline CLI

python3 story_pipeline.py <action> <project_dir> [args]

The story pipeline is shared by Scrum stories and Kanban tickets.

ActionDescription
create_storyCreate a new queued story or ticket
transitionMove a story or ticket to the next pipeline sub-state
unblockReturn a blocked item to its prior active state
get_storyPrint one story or ticket record
list_storiesList stories or tickets filtered by state
evaluate_dodEvaluate per-story or per-ticket DoD
aggregate_dodAggregate DoD results across the active set
cycle_timeCalculate cycle time for one story or ticket

Story pipeline sub-states

Stories move through these sub-states within any lifecycle:

queued -> in_progress (SE) -> testing (QE) -> reviewing (CR) -> done (or blocked)

Story state transitions auto-sync to the configured tracker backend.

Examples

# Initialize a new Scrum project
python3 state_machine.py init_scrum "$(pwd)"

# Read Scrum lifecycle state
python3 scrum_state_machine.py read "$(pwd)"

# Read Kanban lifecycle state
python3 kanban_state_machine.py read "$(pwd)"

# Read whichever lifecycle is active
python3 state_machine.py read "$(pwd)"

# Start Sprint 1 with two stories
python3 scrum_state_machine.py start_sprint "$(pwd)" 1 \
  --goal "Ship the first booking flow" \
  --stories '[{"id":"US-001","title":"Guest can create reservation"},{"id":"US-002","title":"Owner can view bookings"}]'

# Transition Scrum to Sprint Review
python3 scrum_state_machine.py transition "$(pwd)" SPRINT_REVIEW

# Move a story through the shared pipeline
python3 story_pipeline.py transition "$(pwd)" US-001 testing

# Pull a Kanban ticket and evaluate DoD
python3 kanban_state_machine.py pull_ticket "$(pwd)" TICKET-042 --title "Fix checkout timeout"
python3 kanban_state_machine.py evaluate_dod "$(pwd)" TICKET-042

# Transition a completed Scrum project to Kanban
python3 scrum_state_machine.py transition_to_kanban "$(pwd)"

Admin CLI (./synaptory)

All operator tasks are accessed via the ./synaptory script at the repo root (a thin shim onto plugin/synaptory).

./synaptory <command> [arguments]

The plugin no longer ships encrypted blobs (per ADR-016) and there are no per-user access tokens. Identity is Entra OAuth via the user-installed synaptory CLI; project membership is managed in the control plane.

Build & release

CommandDescription
`./synaptory build [--minor\--major\
./synaptory build cli [os/arch ...]Cross-compile the Go CLI into cli/dist/ for distribution. Output is not yet published — chain release cli to ship.
./synaptory release cli [--publish]Stage CLI binaries + sha256sums.txt + install scripts into web/dist/cli/. With --publish, also rsync to SYNAPTORY_PROD_HOST so /cli/* serves the new version.
`./synaptory version [patch\minor\

Required environment variables for build / release:

  • SYNAPTORY_CP_URL — control-plane URL stamped into the plugin and CLI binary at build time.
  • SYNAPTORY_CP_ENTRA_TENANT_ID, SYNAPTORY_CP_ENTRA_CLIENT_ID — stamped so synaptory login works with no local setup.
  • SYNAPTORY_PROD_HOST=user@host — required for --publish.

Identity & projects (control-plane)

CommandDescription
./synaptory api projects create <slug>Provision a project on the control plane.
./synaptory api projects add-member <slug> <upn>Grant a user access to the project.
./synaptory api projects revoke <slug> <upn>Revoke a user's access.

There is no separate "issue access token" step — staff sign in once with synaptory login and project access is checked per-request against project_members.

Local stack & dev

CommandDescription
`./synaptory api up\down\
./synaptory dev pluginLaunch claude --plugin-dir plugin for live source-tree testing.
./synaptory dev cliRun the CLI against a local control-plane (go run ./cmd/synaptory).
`./synaptory cli {test\smoke\
./synaptory testPlugin syntax validation + pytest (Layer 1 + Layer 2).
`./synaptory test --syntax\--pytest`
./synaptory e2e [--keep-stack] [--scenario test_NN_name.py]Cross-module Layer-3 scenarios against a fresh local stack.
./synaptory statusShow source/dist status, current version, and live-marketplace version.

Examples

# Build and publish the plugin (test against the local marketplace first)
./synaptory build --publish-local                  # auto-bump patch; push to infra/git/marketplace.git
./synaptory build --minor --publish                # bump minor + SSH-push to prod

# Release the standalone CLI
./synaptory release cli --publish                  # rsync binaries to SYNAPTORY_PROD_HOST

# Provision a new project
./synaptory api projects create taskflow-pilot
./synaptory api projects add-member taskflow-pilot alice@h3tech.io

# Local stack
./synaptory api up
./synaptory api smoke
./synaptory e2e --scenario test_03_kanban_loop.py

Mode reader CLI

The mode reader (plugin/hooks/lib/mode_reader.py) reads the engagement mode. Used internally by hooks.

python3 mode_reader.py <project_dir>
FieldValuesDescription
modestructured, interactiveCurrent engagement mode
block_on_failureTrue / FalseWhether hooks block on validation failure. True for Structured, False for Interactive.

What's next?

Reference · 23

Routing Reference

Diataxis category: Reference — information-oriented, for lookup.

How the orchestrator decides which mode to dispatch. The full machine-readable source of truth is plugin/skills/synaptory/routing-rules.json — this page is its human projection.


Three-layer dispatch

Every request is classified into one of three layers:

  1. Scrum lifecycle modesBuild, Sprint. Drive the full Inception → Sprint loop → Release flow.
  2. Kanban lifecycle modeKanban. Continuous ticket flow on a brownfield codebase.
  3. Standalone modes — everything else. Single- or dual-agent scoped tasks that don't depend on a lifecycle.

Standalone modes group naturally:

  • Diagnostics & setup: Doctor, Init, Status, Help, Report. Plus the silent Update check that runs before every other mode.
  • Per-story assistance (Story Buddy): Story Buddy — Requirements, Story Buddy — Implement, Story Buddy — Test, Story Buddy — Sprint Plan.
  • Lightweight single-agent: Test, Review, Architect, Document, Explore, Optimize, Stabilize, Modernize, Custom.
  • Brownfield analysis: Discover, Context Refresh.
  • Workflow utilities: Debug, Preview, Branch Finish, Retro.

For a behavioural description of each mode see Modes. This page is for predicting routing.


Trigger signals and patterns

Each mode declares both keyword signals and regex patterns. A request matches if any signal substring appears, or if any pattern matches.

ModeLayerSignals (sample)Patterns (regex)
BuildScrum"build a SaaS", "production grade", "from scratch", "full stack", "greenfield"`build.*(?:saas\
SprintScrum"build sprint", "sprint N", "next sprint", "continue sprint", "resume sprint", "run sprint", "start sprint"`(?:build\
KanbanKanban"fix ticket", "work on TICKET-xxx", "pull next ticket", "maintenance mode", "kanban"fix\s+ticket, work on\s+TICKET-\d+, pull next ticket, maintenance mode, kanban
TestStandalone"write tests", "test coverage", "test this", "add tests"`(?:write\
ReviewStandalone"review my code", "code review", "code quality", "check my code"`(?:review\
ArchitectStandalone"design", "architecture", "API design", "data model", "tech stack", "how should I structure"`(?:design\
DocumentStandalone"document", "write docs", "API docs", "README"`(?:write\
ExploreStandalone"explain", "understand", "help me think", "what should I", "I'm not sure"explain\s+\w+, help me think, what should I, I'm not sure
OptimizeStandalone"performance", "slow", "optimize", "scale", "reliability"(?:too\s+)?slow, optimize\s+\w+, `performance\s+(?:issue\
DiscoverStandalone"understand this codebase", "map the system", "reverse engineer", "what does this code do", "map dependencies"reverse.?engineer, `map.*(?:system\
StabilizeStandalone"add safety net", "characterization tests", "before refactoring", "establish baseline", "coverage ratchet"characterization tests?, before refactor, safety net, coverage ratchet
ModernizeStandalone"modernize", "migrate", "upgrade architecture", "strangler fig", "migration plan", "rewrite plan"modernize, migration plan, strangler fig, rewrite plan
DebugStandalone"debug", "fix this bug", "not working", "broken", "error", "crash", "failing", "investigate", "root cause"`(?:fix\
PreviewStandalone"preview", "run it", "start server", "launch", "see it running", "dev server"preview, run it, start.*server, `launch.*(?:app\
RetroStandalone"retro", "retrospective", "what did we ship", "team metrics", "weekly summary", "sprint review", "shipping velocity"retro(?:spective)?, what did we ship, team metrics, shipping velocity
Branch FinishStandalone"finish this branch", "merge", "create PR", "done with this branch", "ship this branch", "ready to merge"finish.*branch, create.*pr, ready to merge, ship.*branch
DoctorStandalone"doctor", "diagnose", "check config", "validate config", "is this correctly configured", "synaptory doctor"\bdoctor\b, \bdiagnose\b, `(?:run\
InitStandalone"initialize", "configure project", "set up synaptory", "reconfigure", "generate config"`(?:initialize\
StatusStandalone"status", "progress", "dashboard", "where are we", "show pipeline", "check progress"`(?:show\
HelpStandalone"help", "commands", "what can you do", "reference", "how does synaptory work"`(?:help\
ReportStandalone"report a bug", "report an issue", "synaptory bug", "plugin issue"`report.*(?:bug\
Context RefreshStandalone"update context", "refresh context", "re-analyze codebase", "update codebase knowledge"`(?:update\
Story Buddy — RequirementsStandalone"analyze [story]", "refine requirements", "AC review", "PM help with [story]", "BA help with [story]"`analyze\s+(?:[A-Z]+-\d+\
Story Buddy — ImplementStandalone"implement [US-xxx]", "build [story ID]", "code [story]"`(?:implement\
Story Buddy — TestStandalone"test cases for [US-xxx]", "test [story]", "automate [story]", "QA help with [story]"`(?:test cases?\
Story Buddy — Sprint PlanStandalone"sprint planning", "help plan sprint", "prioritize backlog", "backlog grooming"sprint planning, help.*plan.*sprint, prioritize.*backlog, backlog grooming
CustomStandalone(catch-all when no other mode matches)

Update is not a routing-rules entry — it runs silently before any mode and prompts only if a newer plugin version is available. See plugin/skills/synaptory/modes/update.md.


Tiebreakers

When multiple modes match, the orchestrator applies these rules in order. They are reproduced verbatim from routing-rules.json so they stay in sync with the routing engine.

ConflictRuleWhy
review vs verifyReview if "my code / this code". Verify if "before launch / audit / harden / production ready"Verify implies multi-agent parallel audit; Review is single-agent read-only
test vs debugDebug if error/failure/crash/not working is described. Test if the code works and coverage is the goalDebug = active failure; Test = proactive quality
build vs debugDebug if there is a specific error description. Build if it is a new behaviour requestDebug requires root-cause analysis; Build is additive
multiple modes matchPick the most specific: Debug > Story Buddy, Release > Code Review, Sprint > BuildSpecificity beats generality
reliability vs optimizeReliability if SLO, error budget, chaos, runbook, incident, or on-call is mentioned. Optimize if performance or scale is the goal without operational framingReliability = operational engineering; Optimize = code/infra performance tuning
implement + story ID vs BuildStory Buddy — Implement if a story ID pattern ([A-Z]+-\d+ or US-\d+) is present. Build (Scrum lifecycle) if no story IDStory ID = story already in tracker. No story ID = new project requiring Inception
write tests + story ID vs TestStory Buddy — Test if a story ID is present. Test (standalone) if no story IDStory ID enables AC-to-test traceability; standalone Test is general coverage work
story ID anywhere in requestStory Buddy mode (role inferred from request context). Story ID overrides Build/Test/ReviewPresence of a story ID signals per-story assistance intent, not a new feature request
doctor vs initDoctor if "check", "validate", "diagnose", "is it configured correctly", or "doctor" is mentioned. Init if "initialize", "set up", or "generate config" is the goalDoctor is read-only diagnostic; Init generates/overwrites configuration

Forcing a specific mode

Two ways to force routing:

  1. Use the trigger phrase explicitly. "doctor" → Doctor. "initialize" → Init. "modernize the architecture" → Modernize. The signals are loose enough that natural English usually lands the right mode.
  2. Address the orchestrator directly. /synaptory run doctor or /synaptory start sprint 3 bypasses ambiguity by pinning the mode in the request.

If a mode keeps misclassifying, run Doctor first — .synaptory.yaml mismatches account for most surprising routes.


What's next

  • Modes — what each mode does and when to reach for it.
  • Commands — the slash-command surface and the synaptory CLI.
  • Hooks — what fires before, during, and after every dispatched mode.
Reference · 24

Rules Reference

Diataxis category: Reference — information-oriented, for lookup.

The plugin ships ten behavioural rules in plugin/rules/. They are auto-injected at every SessionStart by synaptory-load-rules.sh (delivered watermarked from the control plane like all IP-sensitive bodies — see The Synaptory Platform). They define the structural patterns and protocols every agent must follow.

Some rules are scoped via a paths: frontmatter list; those fire only when the agent touches matching files.


Rules at a glance

RuleScopeSummary
synaptory-boundary-safetyalwaysSix structural patterns that cause silent failures at system boundaries (framework abstractions vs. platform primitives).
synaptory-conflict-resolutionalwaysAuthority hierarchy when two agents' outputs overlap. Single-owner-per-artifact, contributors flag but don't override.
synaptory-flaky-teststests/**, **/__tests__/**, .github/workflows/**Defines and bans flaky tests. ≥1 failure in 20 runs is a pipeline correctness issue, not a minor inconvenience.
synaptory-freshness.synaptory/**Volatility tiers for verifying external facts before using them — model IDs, pricing, security advisories, framework breaking changes.
synaptory-guard.synaptory/**Fallback when the SessionStart hook is not active. Detects an existing .synaptory/ workspace and offers options.
synaptory-receipt-protocol.synaptory/**Receipt schema and the proof-of-completion contract. Every completing agent MUST write .synaptory/.orchestrator/receipts/<story>-<role>.json.
synaptory-secrets-scan.env*, **/*.{key,pem,p12,pfx}, secrets/**, infra/**, terraform/**Forbids secrets in tracked files. Triggers on env files, key material, infra configs, and CI workflows.
synaptory-uxalwaysUX interaction rules. Always use AskUserQuestion with explicit options; "Chat about this" always last; recommended option first.
synaptory-visual-identityalwaysVisual language for agent output. Information density over decoration; earned elevation; concrete over vague.
synaptory-welcomefirst-message-after-installOnboarding rule for new users. Fires once when no .synaptory/ exists and the user makes a development request.

Rule detail

synaptory-boundary-safety

Six framework-agnostic patterns that produce silent failures when crossing system boundaries. Pattern 1 — framework abstractions break at system boundaries — is the canonical example: Next.js <Link> to an API route, React Router navigate() to an external OAuth URL. Before using a framework abstraction, agents must verify the target stays within the framework's domain; otherwise fall back to the platform primitive (raw <a href>, raw fetch, raw redirect).

synaptory-conflict-resolution

The authority hierarchy. Each artifact type has a single owning skill; contributors may flag issues but never overwrite. Examples: BRD → project-owner. ADRs and API contracts → solution-architect. Implementation code → software-engineer (reviewers produce findings only). Tests → quality-engineer. Security findings → compliance-engineer (Code Reviewer does NOT perform OWASP review). SLOs and monitoring → platform-engineer.

synaptory-flaky-tests

Path-scoped to test and CI files. Defines flaky as ≥1 failure in 20 runs without code change (≥5% failure rate). Establishes that flaky tests are a pipeline correctness issue: they erode trust, mask real regressions, and make synaptory-verify-receipt.sh re-runs unreliable.

synaptory-freshness

Path-scoped to .synaptory/**. Defines volatility tiers for things you should never trust training data on:

  • Tier 1 (days to weeks): LLM model IDs and capabilities, API pricing, security advisories, compliance requirements, framework breaking changes — MUST WebSearch before use.
  • Lower tiers cover slower-changing facts.

The Freshness Protocol is what catches "package version X has been deprecated" mistakes before code lands.

synaptory-guard

Path-scoped to .synaptory/**. A fallback for environments where the SessionStart hook didn't fire. When .synaptory/ is detected and no pipeline session is active, presents the user with the choice to use the pipeline or work directly. Prevents accidental ad-hoc edits to a repo that has an active synaptory workspace.

synaptory-receipt-protocol

Path-scoped to .synaptory/**. Defines the receipt JSON schema every agent writes on completion (task, agent, backend, model, artifacts, verification_commands, plus optional story_dod, confidence, fallback_from). Receipts are the authoritative record of what was built; they're what synaptory-verify-receipt.sh validates and re-runs.

synaptory-secrets-scan

Path-scoped to env files, key material, secrets directories, CI workflows, docker-compose, and infra/**/terraform/**. Fires when an agent touches any of those paths and forbids commits that include secret-shaped content. Aligned with the project-wide pre-commit gitleaks hook.

synaptory-ux

Always-on. Rules for how agents talk to the user:

  1. Every decision point uses AskUserQuestion with explicit options — never open-ended "what do you think?"
  2. Every AskUserQuestion has Chat about this as the last option (escape hatch).
  3. First option is the recommended default with (Recommended) suffix; the user should accept it ~80% of the time.

synaptory-visual-identity

Always-on. Defines synaptory's visual language for chat output:

  1. Information is the aesthetic — never print a line that doesn't carry information.
  2. Earned elevation — heavy formatting is reserved for genuinely important moments.
  3. State must be visible — the user should always know where they are, what's happening now, and what's next.
  4. Concrete over vague — never "analysis complete"; always "analyzed 247 files across 3 services, 12 endpoints."

Also defines the icon vocabulary used across agent output.

synaptory-welcome

Fires when all of these are true: the plugin is loaded, no .synaptory/ directory exists, the user's first message is development-related, and the welcome hasn't been shown this session. Walks new users through initialize my project and the recommended starting prompts. Suppressed once dismissed for the session.


Behavioural protocols (separate from rules)

In addition to rules, every SubagentStart injects ~26 shared protocols (receipt-protocol, input-validation, tool-efficiency, freshness-protocol, iron-laws, verification-discipline, socratic-gate, anti-safe-harbor, script-output-handling, clean-code-self-check, boundary-safety, conflict-resolution, coverage-ratchet, finding-memory, local-deploy-verification, open-decision-registry, scope-challenge, source-attribution, subagent-isolation, tdd-discipline, ux-protocol, visual-identity, code-review-response, story-pipeline, backend-dispatch, sa-triggers). Protocols live in plugin/skills/_shared/protocols/ and are delivered via the same watermarked-fetch path as rules. See Hooks for the full list.


What's next

Reference · 25

Hooks Reference

Diataxis category: Reference -- information-oriented, for lookup.

synaptory uses Claude Code's native Hooks system for lifecycle automation. Hooks run automatically at defined lifecycle events -- you do not invoke them manually. Hook definitions live in plugin/hooks/hooks.json.


Hook events in execution order

Hooks fire at six lifecycle points in this order:

SessionStart -> SubagentStart -> SubagentStop -> PreCompact -> Stop -> SessionEnd

Complete hooks table

EventScriptTimeoutAsyncDescription
SessionStartsynaptory-access-token-check.sh20snoValidate session, resolve control-plane URL, and authenticate CLI.
SessionStartsynaptory-skills-fetch.sh15snoSync skill manifest and pull missing/stale skills into local cache.
SessionStartsynaptory-config-fetch.sh10snoPull policy from control-plane; update local cache. Non-fatal on network failure.
SessionStartsynaptory-load-rules.sh10snoInject behavioral rules into session.
SessionStartsynaptory-session-start.sh10snoDetect workspace and inject lifecycle state, story pipeline, context packages.
SessionStartsession-guard.sh10snoDetect existing project and offer options.
SubagentStartsynaptory-inject-protocols.sh5snoInject shared behavioral protocols into subagent.
SubagentStopsynaptory-verify-receipt.sh30snoValidate agent receipt and re-run verification commands.
PreCompactsynaptory-reanchor.sh10snoRe-inject critical context before compaction.
Stopsynaptory-pipeline-snapshot.sh10syesSave lifecycle state snapshot for cross-session resume.
Stopsynaptory-access-token-cleanup.sh5syesAsync cleanup of in-memory token material at end of turn.
SessionEndsynaptory-session-end.sh5syesAsync cleanup of temporary resources.
SessionEndsynaptory-access-token-cleanup.sh5syesFinal async cleanup of cached token material on session close.
user-invocablesynaptory-doctor.sh----Configuration diagnostic. Not bound to a lifecycle event — invoked by the Doctor mode and surfaced from SessionStart errors. Delegates to hooks/lib/doctor.py.
internalsynaptory-decrypt-skill.sh----Helper invoked by other hooks when a cached skill body needs to be decoded before use. Not user-invocable.
internal_resolve-cli.sh----Locates the synaptory CLI binary on $PATH. Sourced by every other hook.
internal_plugin-env.sh----Bootstraps shared environment variables (CLAUDE_PLUGIN_ROOT, log paths) for every other hook. Sourced, not executed.

The SessionStart matcher is startup|resume|clear|compact, meaning these hooks fire on session start, on resume, after /clear, and after context compaction.


Hook details

synaptory-access-token-check.sh (SessionStart)

Resolves the control-plane URL from the bundled plugin/hooks/lib/cp-url file (stamped at build time) and exports SYNAPTORY_CONTROL_PLANE_URL for downstream hooks. In dev environments (SYNAPTORY_CP_ENV=dev), falls back to the SYNAPTORY_CONTROL_PLANE_URL env var if set. Hard-fails with a clear message if no URL is available.

  • Mode-aware behavior: None. Always runs.
  • Blocks vs warns: Exits 1 when the control-plane URL is missing or placeholder (build not stamped).

synaptory-skills-fetch.sh (SessionStart)

Invokes synaptory skills sync to fetch the skill manifest from the control-plane and pull any missing or stale skill bodies into the local cache. Skills are served live from the cache — never stored as plaintext files on disk.

  • Mode-aware behavior: None. Always runs.
  • Blocks vs warns: Non-fatal on network failure; logs a warning and continues.

synaptory-config-fetch.sh (SessionStart)

Invokes synaptory config fetch --if-stale to refresh the local policy cache (~/.synaptory/.cache/policy.json). Policy data controls receipt schema validation, allowed backends, and roster.

  • Mode-aware behavior: None. Always runs.
  • Blocks vs warns: Non-fatal on network failure; exits 0 always.

synaptory-load-rules.sh (SessionStart)

Injects behavioral rules (UX, guard, conflict resolution, etc.) into the session context. Rules live in plugin/rules/ and are loaded because plugins do not natively support rules/ directories.

  • Mode-aware behavior: None. Rules are always loaded.
  • Blocks vs warns: Never blocks. Adds context only.

synaptory-session-start.sh (SessionStart)

Detects the .synaptory/ workspace directory and injects:

  • Lifecycle state -- current ceremony position (Scrum or Kanban)
  • Story pipeline state -- per-story sub-states
  • Sprint state -- sprint number, Sprint Goal, completed sprints
  • Engagement mode -- structured or interactive
  • Context packages -- brownfield analysis artifacts (if present)

Eliminates the need to check status manually after opening a project.

  • Mode-aware behavior: None. Always runs if workspace exists.
  • Blocks vs warns: Never blocks. Adds context only.

session-guard.sh (SessionStart)

Detects an existing project (presence of .synaptory/ directory) and offers options: use /synaptory (recommended), work directly without the plugin, or chat about it.

  • Mode-aware behavior: None. Always runs if workspace exists.
  • Blocks vs warns: Never blocks. Presents options.

synaptory-inject-protocols.sh (SubagentStart)

Injects all shared behavioral protocols into every subagent context automatically. Reads protocol content from the local skill cache via the CLI.

Injected protocols:

ProtocolDomain
receipt-protocolReceipt writing and verification commands
input-validationInput sanitization patterns
tool-efficiencyTool call optimization
freshness-protocolExternal dependency version verification
iron-lawsInviolable delivery rules
verification-disciplineVerification command requirements
socratic-gateGate interview patterns
anti-safe-harborPrevents hedging language in deliverables
script-output-handlingScript execution and output parsing
clean-code-self-checkSelf-review before completion
boundary-safetyAgent authority boundaries
conflict-resolutionCross-agent conflict handling
coverage-ratchetCoverage cannot decrease
finding-memoryPersistent finding tracking
local-deploy-verificationLocal server health check requirements
open-decision-registryDecision tracking and justification
scope-challengeScope creep prevention
source-attributionSource citation requirements
subagent-isolationSubagent workspace isolation
tdd-disciplineTest-driven development patterns
ux-protocolUser experience standards
visual-identityProgress output formatting
code-review-responseCode review finding response format
story-pipelineStory state machine protocol
backend-dispatchBackend dispatch and routing protocol
sa-triggersSolution Architect auto-trigger signals
  • Mode-aware behavior: None. All protocols are always injected.
  • Blocks vs warns: Never blocks. Adds context only.

synaptory-verify-receipt.sh (SubagentStop)

Mode-aware receipt enforcement with a 30-second timeout. After each subagent completes, validates the story-scoped receipt JSON.

Validation checks:

  1. Receipt file exists in .synaptory/.orchestrator/receipts/
  2. Required fields present (story_id, role, backend, model, artifacts, verification_commands, metrics, completed_at)
  3. Listed artifacts exist on disk
  4. Verification phrases are not banned (rejects generic claims without evidence)
  5. verification_commands are re-run to confirm they still pass
  6. Optional enrichment fields such as story_dod, confidence, and fallback_from are validated when present
  • Mode-aware behavior:
  • Structured: Missing receipt, invalid receipt, or failing verification commands cause exit 1 -- execution BLOCKED.
  • Interactive: Same checks run, but failures are surfaced as warnings. Execution proceeds (exit 0).
  • Blocks vs warns: Structured blocks. Interactive warns.

synaptory-reanchor.sh (PreCompact)

Before Claude Code compacts the context window, re-injects BRD, ADRs, receipts, context packages, and other critical artifacts. Prevents context degradation during long runs.

  • Mode-aware behavior: None. Always runs before compaction.
  • Blocks vs warns: Never blocks. Adds context only.

synaptory-pipeline-snapshot.sh (Stop)

Writes a lifecycle state snapshot to .synaptory/.orchestrator/last-session.md. Captures current ceremony, completed stories, story pipeline status, sprint metrics, and engagement mode.

  • Mode-aware behavior: None. Always runs on stop.
  • Blocks vs warns: Never blocks. Runs asynchronously.

synaptory-session-end.sh (SessionEnd)

Async cleanup of temporary resources created during the session.

  • Mode-aware behavior: None. Always runs.
  • Blocks vs warns: Never blocks. Runs asynchronously.

synaptory-access-token-cleanup.sh (Stop, SessionEnd)

Asynchronous cleanup of in-memory token material at end of turn (Stop) and on session close (SessionEnd). Pairs with synaptory-access-token-check.sh at SessionStart. Never blocks.

  • Mode-aware behavior: None.
  • Blocks vs warns: Never blocks. Runs asynchronously.

synaptory-doctor.sh (user-invocable)

User-invocable self-service diagnostic. Prints a plain-text report covering token source and format, signature status, expiry, backend mode, and session directory. The Doctor mode dispatches here, and SessionStart errors funnel through it automatically so the user sees a remediation report instead of a raw stack trace. Delegates to ${CLAUDE_PLUGIN_ROOT}/hooks/lib/doctor.py.

  • Mode-aware behavior: Always read-only. Never modifies files.
  • Blocks vs warns: Surfaces findings; never blocks the pipeline by itself.

See Troubleshooting → Run Doctor first for typical recipes.


synaptory-decrypt-skill.sh (internal helper)

Helper used by other hooks when a cached skill body needs to be decoded before use. Not user-invocable; never registered against a lifecycle event directly.


_resolve-cli.sh (internal helper)

Locates the synaptory CLI binary on $PATH and exports it for downstream hooks. Sourced by every other hook script. Hard-fails with a clear message if the CLI is not installed (see Install the CLI).


The synaptory-guard rule fallback

The synaptory-guard rule (plugin/rules/synaptory-guard.md) is a fallback for environments where Hooks are not yet supported. It fires when a .synaptory/ directory is detected and offers options.


Hook lib modules

All hook library modules live in plugin/hooks/lib/.

ModuleLanguageDescription
state_machine.pyPythonThin dispatcher for lifecycle bootstrap and state reads. Initializes Scrum or Kanban and reads the current pipeline state.
scrum_state_machine.pyPythonScrum lifecycle state machine. Enforces ceremony transitions: INCEPTION -> SPRINTPLANNING -> SPRINTEXECUTION -> SPRINTREVIEW -> SPRINTRETRO -> SPRINT_CLOSE -> (loop) -> RELEASE -> COMPLETE.
kanban_state_machine.pyPythonKanban lifecycle state machine. Enforces: DISCOVER -> READY -> EXECUTION -> REVIEW -> (loop) -> RELEASE -> COMPLETE.
story_pipeline.pyPythonStory-level sub-state management. Tracks queued -> in_progress -> testing -> reviewing -> done/blocked. Evaluates per-story DoD. Syncs to tracker backend.
mode_reader.pyPythonReads engagement mode (structured, interactive) from settings. Provides should_block_on_failure() helper.
receipt_validator.pyPythonValidates receipt JSON: schema compliance, required fields, artifact existence, banned phrase detection. Schema loaded from policy cache (~/.synaptory/.cache/policy.json).
verification_runner.pyPythonRe-runs verification_commands from receipts and reports pass/fail.

What's next?

Reference · 26

URLs Reference

Diataxis category: Reference — information-oriented.

Every public URL on synaptory.h3t.co, what it does, and which container or static path serves it.

The host is fronted by Caddy; see infra/caddy/Caddyfile for the source of truth.

Per ADR-019 the /console/* and /portal/* URL trees are gone — every page in the Control Plane lives at root URLs.


User-facing URLs

URLPurposeAudience
https://synaptory.h3t.co/Role-aware redirect (admin → /overview, else → /home)Any signed-in user
https://synaptory.h3t.co/get-startedPublic landing — install instructions, links into the user guideProspective users
https://synaptory.h3t.co/home, /overview, /projects/*, /audit, /sessions, /skills, /cost, /quality, /reliability, /people, /policy, /system, /grafana, /access-review, /settings, /profileControl Plane pages (Next.js); each role-gated server-sidesynaptory-users (varying scope by role)
https://synaptory.h3t.co/auth/loginSign-in entry pointAnyone (redirected to Entra)
https://synaptory.h3t.co/auth/callbackOAuth callback for Web flowBrowser (round-trip from Entra)
https://synaptory.h3t.co/docs/user-guide.htmlThis guide, single-file HTMLAnyone signed in (gated by Caddy if needed)

The legacy /console/* and /portal/* URL trees return 404. There are no redirects — bookmarks pointing at the v2.5 surfaces must be updated.


Plugin distribution

URLPurpose
https://synaptory.h3t.co/marketplace.gitSmart-HTTP git endpoint. The actual transport for /plugin marketplace add.
https://synaptory.h3t.co/marketplace.git/info/refsGit protocol probe. Returned by git-http-backend
https://synaptory.h3t.co/marketplaceDiscoverability landing page. Not the marketplace transport.

/plugin marketplace add https://synaptory.h3t.co/marketplace.git is the supported install command.


CLI distribution

URLPurpose
https://synaptory.h3t.co/cli/install.shmacOS / Linux install script
https://synaptory.h3t.co/cli/install.ps1Windows install script
https://synaptory.h3t.co/cli/latest.jsonCurrent CLI version + per-platform binary URLs
https://synaptory.h3t.co/cli/<version>/<binary>Versioned binaries (e.g. synaptory_darwin_arm64)
https://synaptory.h3t.co/cli/<version>/sha256sums.txtSHA-256 manifest for offline verification
https://synaptory.h3t.co/downloadsHuman-readable download index

The install scripts resolve latest.json first, then download the binary. Override with SYNAPTORY_CLI_BASE_URL for staging.


API endpoints (/v1/*)

The complete authoritative list is in api/README.md. Highlights:

PatternAudiencePurpose
/v1/auth/*AnyoneOAuth exchange, local-auth fallback
/v1/projects/*Any signed-in userProject list (caller's by default; ?all=true for global admins). Project detail / members / archive (membership-gated)
/v1/projects/{ref}/access-requests*Any signed-in userSelf-service access requests; project admins approve/deny
/v1/access-requests/mineAny signed-in userCaller's outstanding access requests across projects
/v1/analytics/*Any signed-in user (scope-aware)Analytics with server-side filter by project_members. Anti-leak 404 on ?project=<slug> the caller can't see
/v1/sessions/*Any signed-in user (scope-aware)List, detail, revoke. Self-revoke always allowed
/v1/admin/*synaptory-admins onlyCross-tenant operations the role gating doesn't cover: system/*, projects/bulk-archive, config/{v}/export
/v1/skills/manifestAny signed-in userSkill list (no bodies)
/v1/skills/<name:path>Any signed-in userWatermarked body fetch
/v1/ingestCLITelemetry batch ingest
/v1/config/*CLISigned config delivery
/v1/healthz, /v1/readyzAnyoneLiveness / readiness
/v1/public-keyAnyoneEd25519 public key for offline signature verification

The /v1/me/* namespace was retired by ADR-019. Identity comes from the iron-session cookie's claims; member-scoped reads go through the scope-aware /v1/{projects,sessions,analytics} endpoints.


Operator URLs

URLPurpose
https://synaptory.h3t.co/grafanaGrafana embed (Caddy reverse-proxy, admin-only)
https://synaptory.h3t.co/systemProbes + versions + last backup
https://synaptory.h3t.co/auditAudit log (scope-aware: admins see everything; project admins see their projects)

Direct Grafana (without the iframe) is also available via SSH tunnel — see infra/README.md.


Local dev URLs

When you run ./synaptory api up, the same surface appears at localhost:

URLEquivalent
http://localhost:8080/Role-aware Control Plane root
http://localhost:8080/<page>Same page as on prod (e.g. /overview, /projects, /sessions)
http://localhost:8080/marketplace.gitThe local bare repo for --publish-local testing
http://localhost:8080/cli/*The local web/dist/cli/
http://localhost:8080/docs/user-guide.htmlThe local web/dist/docs/
http://localhost:8080/v1/*FastAPI
http://localhost:8080/dev/mintFixture-IDP token mint (local only)

http://localhost:3099 is the Next.js dev server when running npm run dev directly without Caddy.

Reference · 27

Authentication Flows

Diataxis category: Reference — information-oriented.

Three flows mint a SYNAPTORY1 token. Each has a different shape; all produce the same token format, indistinguishable downstream.

For the conceptual model and per-request enforcement, see Identity and access.


Flow 1: Web (Control Plane browser sign-in)

Used by every page in the Control Plane (synaptory.h3t.co/*) — single unified app per ADR-019.

sequenceDiagram
  participant U as User (browser)
  participant W as Next.js (web)
  participant E as Entra
  participant A as FastAPI (api)
  U->>W: GET /home (no cookie)
  W-->>U: 302 → /auth/login
  U->>W: GET /auth/login
  W-->>U: 302 → Entra authorize URL (with client_id + redirect_uri)
  U->>E: GET /authorize
  E-->>U: Sign-in UI; consent
  U->>E: POST credentials
  E-->>U: 302 → /auth/callback?code=...
  U->>W: GET /auth/callback?code=...
  W->>E: POST /token (code + client_secret)
  E-->>W: id_token (JWT)
  W->>A: POST /v1/auth/exchange (id_token)
  A->>A: Verify JWKS; extract upn, grp; mint SYNAPTORY1
  A-->>W: SYNAPTORY1 token
  W-->>U: Set-Cookie iron-session; 302 → role-aware home

Key facts:

  • The client_secret is held by the web container only — never exposed to the browser.
  • redirect_uri registered as a Web platform on the Entra app (not Mobile/desktop).
  • The browser carries an iron-session cookie; the SYNAPTORY1 token is held server-side by Next.js.
  • The role-aware redirect at the end inspects grp: admins → /overview, others → /home.

Flow 2: CLI (PKCE)

Used by: synaptory login (default).

sequenceDiagram
  participant CLI as synaptory CLI
  participant Browser
  participant E as Entra
  participant A as FastAPI (api)
  CLI->>CLI: Generate code_verifier + code_challenge
  CLI->>CLI: Bind random loopback port (e.g. 49321)
  CLI->>Browser: Open https://login.microsoftonline.com/.../authorize?...&redirect_uri=http://127.0.0.1:49321/auth/callback&code_challenge=...
  Browser->>E: GET /authorize
  E-->>Browser: Sign-in UI
  Browser->>E: POST credentials
  E-->>Browser: 302 → http://127.0.0.1:49321/auth/callback?code=...
  Browser->>CLI: GET /auth/callback?code=... (loopback HTTP)
  CLI->>E: POST /token (code + code_verifier; no client_secret)
  E-->>CLI: id_token
  CLI->>A: POST /v1/auth/exchange (id_token)
  A-->>CLI: SYNAPTORY1 token
  CLI->>CLI: Store token in OS keychain

Key facts:

  • No client_secret. PKCE is a public-client flow; code_verifier substitutes for the secret.
  • The loopback port is bound at runtime; Microsoft's loopback exception means http://127.0.0.1 (no port) is registered as the redirect URI on the Entra app's Mobile/desktop platform, and any port satisfies the match.
  • The CLI starts a local HTTP server on the bound port for exactly long enough to receive the callback, then shuts it down.
  • Same Entra app + same exchange endpoint as Flow 1. Only the front-end shape differs.

For headless servers: synaptory login --device uses Entra's device-code flow instead. The user opens a URL on a separate device, enters a short code, and the CLI polls until success.


Flow 3: Local-auth fallback

Used by: dev fixtures and on-prem deployments where Entra isn't available.

sequenceDiagram
  participant U as User
  participant W as Next.js (web) [or CLI]
  participant A as FastAPI (api)
  U->>W: POST /auth/login (UPN + password)
  W->>A: POST /v1/auth/local (UPN + password)
  A->>A: Compare against SYNAPTORY_CP_LOCAL_*_PASSWORD env vars
  A->>A: Mint SYNAPTORY1 with grp from the matched slot
  A-->>W: SYNAPTORY1 token
  W-->>U: Set-Cookie iron-session

Key facts:

  • SYNAPTORY_CP_LOCAL_AUTH_ENABLED=true on the API; SYNAPTORY_LOCAL_AUTH_ENABLED=true on the web container. Two different env-var prefixes because they live in different containers.
  • The admin slot grants [synaptory-users, synaptory-admins]; the user slot grants [synaptory-users] only.
  • Tokens minted via local-auth are indistinguishable from Entra-minted tokens once issued — the server treats them identically.
  • Never enable in deployments expected to use Entra.

The CLI also supports local-auth via synaptory login --local. Same flow, headless.


SYNAPTORY1 token format

SYNAPTORY1.<base64url(payload_json)>.<base64url(ed25519_sig)>

Payload:

FieldTypeMeaning
sidstringServer-side session id (used for revoke)
upnstringEntra UPN
grpstring[]Entra group names; e.g. ["synaptory-users", "synaptory-admins"]
iatintIssued-at (Unix seconds)
expintExpiry (typically iat + 86400)

There is no prj claim. Project access is per-request, server-side, against project_members.

The signing key is Ed25519 — file-backed in dev (settings.signing_key_path), Azure Key Vault in prod (kty OKP, curve Ed25519). Public key at GET /v1/public-key.


Refresh and revoke

  • Tokens expire (~24h). The CLI silently refreshes via POST /v1/auth/refresh if possible.
  • Sessions are revocable from /sessions (caller's own) or /sessions (any). Revoke flips revoked_at on the session row; the next API call returns 401, and the CLI surfaces a re-login prompt.
  • "Sign out everywhere" hits POST /v1/me/sessions/revoke-all and revokes every active session for the caller's UPN.

What's next

Reference · 28

Permissions Reference

Diataxis category: Reference — information-oriented.

Two axes determine what you can do: your Entra group membership (synaptory-users / synaptory-admins) and your project-level role on each project (member / admin). This page enumerates every cell in that grid.

For the conceptual model and where checks happen, see Identity and access.


Entra group → platform-level capabilities

Capabilitysynaptory-userssynaptory-admins
Sign in via Entra
Mint a SYNAPTORY1 token
Reach Control Plane workspace pages (/home, /projects, /sessions, /audit, /activity, /skills, /profile)
Reach admin sidebar entries (/overview, /access-review, /policy, /settings, /system, /grafana/*)
Read scope-aware endpoints (/v1/analytics/*, /v1/sessions, /v1/projects)✓ (server-side scope clamp)
Read /v1/skills/manifest
Fetch watermarked skill bodies
Read /v1/admin/*
Provision a new project (./synaptory api projects create)✓ (operator path)
Revoke any user's session
View any user's receipts
Read project membership for projects you're not on

synaptory-admins is a superset — Entra grants both groups when you're an admin, and the API treats admins as transitively having users.


Project role → project-level capabilities

These are checked per project, on top of group permissions, by check_project_membership.

CapabilityNon-membermemberadmin (project)
See the project on /projects
Read /v1/projects/<slug>✗ (404)
Read /projects/<slug> overview✗ (404)
Run /synaptory against the project's source tree✗ (CLI sees 404)
See receipts for this project on /audit(not shown)✓ (own receipts only)✓ (own receipts only)
Invite a member
Revoke a member
Promote a member to admin
Modify project settings

Important: synaptory-admins does not automatically get admin on every project. A global admin who wants to invite a member to a project they aren't on goes through the project's Members tab (allowed by the /v1/admin/* capability above) — not the project-admin self-serve path.


What synaptory-admins can do that project admin can't

Some operations are platform-wide and require the Entra group, not project role:

  • Create a new project (./synaptory api projects create <slug> — currently CLI-only).
  • Archive / unarchive a project.
  • Read /audit across all projects.
  • Read /cost and other analytics across all projects.
  • Read /v1/system/health.
  • Modify the signed config that the CLI fetches.
  • Revoke another user's session (members can revoke only their own; admins can revoke anyone's via /sessions).

What no one can do

Some properties are out of band — not granted by any role.

  • Read encrypted skill bodies at rest. They're envelope-encrypted with a KEK in Azure Key Vault. Even DB access doesn't help — you'd also need Key Vault access plus the deterministic UPN-watermark would still trace any leak.
  • Modify the immutable parts of receipts. Receipts are append-only; the receipts table has no UPDATE path in the API.
  • Forge an Entra group. The grp claim is set at sign-in from the Entra ID token. Tampering with the SYNAPTORY1 token breaks the Ed25519 signature.

Anti-enumeration patterns

A few permission checks return 404 (not 403) on purpose, to avoid leaking the existence of resources you can't see.

ScenarioStatus
You're not a project member, project exists404
You're a project member, project archived403 (you can see it but can't modify)
Project doesn't exist at all404

This is why "user reports they got 404 on a project they should have access to" is the #1 access-control debug signal — there are three possible causes (not a member, project archived, project missing), and they look identical from the client.


What's next

Reference · 29

Glossary

Diataxis category: Reference — information-oriented.

This guide is v2.5-primary in vocabulary, matching the rest of the codebase. The Console UI has already adopted v3.0 names for some surfaces (per docs/v3.0/v3-spec.md). When you see a v3 name in the Console, this table is your decoder ring.

For the broader v3 plan — what's coming beyond renames — see v3.0 Roadmap.

The single TS module mapping these names in the UI is web/src/lib/v3-vocab.ts.


v2.5 → v3.0 vocabulary map

v2.5 term (used in this guide)v3.0 term (in Console UI today)Notes
StorySpec (with kind=story)"Story" remains a spec kind alongside feature, bugfix, task, release in v3. Today the only spec kind in the system is story.
product-manager (PM) — agent roleproject-owner (PO)Codebase-wide rename. product-manager accepted as a server-side legacy alias for in-flight receipts; Alembic migration 20260428_0005 backfills.
Definition of Done (DoD)Evidence / DoD gate (one of four v3 gates)The four v3 gates are: Inception · Spec Ready · Evidence/DoD · Release. Only Evidence/DoD has a wired backend signal in v2.5; the others are placeholders.
Token usagePer-stage token usage11 v3 stages: pro-discovery, pro-brd, pro-ux-spec, sa-architecture, se-implementation, qe-verification, cr-review, ce-compliance, pe-infra, tw-docs, orchestrator. Drives /cost/by-stage.
CostUSD computeSplit into input / output / cache-read / cache-write. Pinned rates per model — see MODEL_PRICING_USD_PER_M in api/synaptoryapi/routers/analytics.py.
User (in admin context)Delivery OwnerHuman role; the agent counterpart is Project Owner. v3 §4.2.
Agent tier (every-sprint / on-demand / adaptive)(retired)Field still on the API for back-compat; UI no longer displays it.

Platform terminology

TermDefinition
PluginThe Claude Code plugin (plugin/ in this repo). Installs via /plugin marketplace add https://synaptory.h3t.co/marketplace.git.
CLIThe standalone synaptory Go binary. One install per laptop, used by the plugin's hooks.
Control-plane APIThe FastAPI service at synaptory.h3t.co/v1/*. Handles auth, project membership, skill delivery, telemetry.
Control PlaneThe Next.js web app at synaptory.h3t.co/. One role-aware app for every signed-in synaptory-users member (ADR-019). Per-page sidebar entries are gated by role; data is auto-scoped server-side. The legacy Console (/console/*, admin) and Portal (/portal/*, member) surfaces were collapsed into this one tree.
MarketplaceThe self-hosted git endpoint at synaptory.h3t.co/marketplace.git. The transport for /plugin marketplace add.
SYNAPTORY1 tokenThe session token format. SYNAPTORY1.<payload>.<sig> — Ed25519-signed by the control plane.
UPNUser Principal Name — the Entra identity (e.g. alice@h3t.co).
WatermarkPer-UPN visible HTML comment + steganographic zero-width pattern injected into every fetched skill body. See ADR-016.

Lifecycle terminology

TermDefinition
Build modeEither scrum or kanban. Set in .synaptory.yaml per project.
Engagement modeEither structured (autonomous) or interactive (user reviews major decisions). Set in .synaptory.yaml.
InceptionSprint 0 of a Scrum delivery. Produces vision, epics, Sprint 1 stories, architecture foundations.
Story pipelineThe per-story SE → QE → CR sequence. Sub-states: queued → in_progress → testing → reviewing → done (or blocked).
ReceiptStory-scoped JSON written by every agent on completion. {story_id}-{role_abbrev}.json. Validated by synaptory-verify-receipt.sh.
DoDDefinition of Done. Story-level (always) and sprint-level (Scrum only). See Enforcement.
Tracker adapterThe pluggable backend for stories / epics / sprints. local, github, jira, teamwork.

Agent role abbreviations

Used throughout this guide and in receipt filenames.

AbbrevRole
POProject Owner
SASolution Architect
SESoftware Engineer
QEQuality Engineer
CRCode Reviewer
CECompliance Engineer
PEPlatform Engineer
TWTechnical Writer
RAResearch Advisor

See Agents for the full descriptions and model-tier assignments.


Misc

TermDefinition
synaptory-usersThe Entra group every signed-in user belongs to.
synaptory-adminsThe Entra group Console admins belong to. Superset — implies synaptory-users.
project_membersThe DB table that grants per-project access. Checked per request.
AI-BOMAI Bill of Materials. The build-metadata.json shipped alongside each plugin build that pins model versions. See Healthcare Compliance.
Healthcare mode (HC0)Operating mode with healthcare.baa_enforced: true. Restricts to BAA-covered backends; pins model IDs explicitly.
Reference · 30

Troubleshooting

Common issues, error messages, and fixes for synaptory delivery runs.


Run Doctor first

When something looks wrong — auth misbehaving, a mode picking the wrong route, a .synaptory.yaml change that didn't take, a fresh laptop that has never run the plugin — run the Doctor mode before anything else:

doctor

(Or any of: "diagnose", "check config", "validate config", "is this correctly configured".)

What Doctor checks (read-only — never modifies files without asking):

  • .synaptory.yaml — presence, version, schema correctness.
  • Plugin settings in .claude/settings.json.
  • CLI authentication state (token source, format, signature, expiry).
  • Control-plane project membership for the current project_id.
  • Backend mode and session directory layout.
  • v2.1 cruft (legacy paths, retired keys) that should be cleaned up.

Doctor produces a pass/warn/fail report with a remediation pointer for every finding. SessionStart errors funnel through the same diagnostic automatically, so a failed login or stale config surfaces a Doctor report instead of a raw stack trace.

When to run it:

  • A project is being migrated from v2.1 to v2.5.
  • A /synaptory dispatch returns unexpected errors.
  • A new team member sets up the plugin.
  • After any manual edits to .synaptory.yaml or .claude/settings.json.
  • Before opening a Report — the Doctor output is exactly the context the bug report needs.

Authentication issues

"synaptory: Control Plane Not Configured"

The plugin build does not have a control-plane URL stamped into it. Re-download the plugin from the marketplace or contact your H3Tech operator.


Sign-in browser tab did not open

Run the device-code flow manually:

synaptory login --device

Visit the URL shown, enter the code, and approve. The session is cached once approved.


"Cached session expired" / session prompt on every start

The session token expired and silent refresh failed. Re-run:

synaptory login

synaptory login returns 401 or "project not found"

Your UPN may not be a member of the project declared in .synaptory.yaml. Contact your H3Tech operator to verify project membership. Run synaptory projects list to see projects you have access to.


Skills not loading after sign-in

Force a skill cache sync:

synaptory skills sync

Then restart your Claude Code session.


Verify your session at any time

synaptory whoami
synaptory status

whoami prints your UPN, project, and token expiry. status runs a full diagnostic including skill cache size and outbox depth.


Lifecycle and ceremony issues

"No active pipeline found"

No .synaptory/ workspace directory exists. Say "initialize my project" or describe what you want to build.


Execution blocked by receipt validation

In Structured mode, synaptory-verify-receipt.sh exits 1 if an agent completes without a valid receipt. The error identifies which fields are missing or which artifacts weren't found. Options:

  1. Re-run the agent -- the receipt may have been skipped on a failed attempt
  2. Switch to Interactive mode -- change engagement mode to inspect the output before deciding
  3. Check the receipt manually -- .synaptory/.orchestrator/receipts/ -- verify artifact paths

Lifecycle state seems wrong

If "show status" reveals incorrect state (e.g., stuck in SPRINT_EXECUTION when stories are done):

  1. Check raw state:

``bash cat .synaptory/.orchestrator/pipeline-state.json ``

  1. Manually transition if needed:

``bash python3 /path/to/plugin/hooks/lib/scrum_state_machine.py transition "$(pwd)" SPRINT_REVIEW ``


Inception Gate rework stuck

Gate rework is automatic -- the system feeds your concerns back to the relevant agent and re-presents the gate. Maximum 2 rework cycles. If it appears stuck after 2 cycles, check .synaptory/.orchestrator/rework-log.md.


Story stuck in testing/reviewing state

A story in testing or reviewing state means the QE or CR hasn't completed yet. Check:

  1. Receipt exists? Look for {story_id}-qe.json or {story_id}-cr.json in .synaptory/.orchestrator/receipts/
  2. DoD failure? Check the receipt's story_dod field -- a Critical check may have failed, moving the story to blocked.
  3. Agent timed out? Re-run the agent for the affected story.

Agent failed multiple times

Read .synaptory/<agent-name>/escalation.md. Common causes:

  • A dependency the agent needs doesn't exist yet (sequencing issue)
  • An external service is unreachable (network or credentials)
  • The problem requires a human decision

Context degraded mid-run -- agents forget the architecture

The synaptory-reanchor.sh hook handles this automatically before context compaction. If you suspect degradation mid-run, trigger manually:

/synaptory -- re-anchor context

Symptoms: agent output contradicts an ADR, agent re-asks an already-answered question, tests target wrong endpoints.


Config not being picked up

Verify .synaptory.yaml is at the project root:

ls .synaptory.yaml

Frontend renders but doesn't work

This is a Dead Element Rule violation -- a Critical bug. Run Debug mode or ask for verification:

Debug -- buttons on the login page don't work

Wrong package versions or deprecated APIs in generated code

The Freshness Protocol should have caught this. Ask for a targeted verification:

verify dependency versions and API compatibility

Delivery cost is higher than expected

Check the engagement mode -- Interactive surfaces more decisions but uses the same model tiers as Structured. Check rework cycles in .synaptory/.orchestrator/rework-log.md. Each rework adds 10-30K tokens.

Strategy: use Structured for sprint execution, switch to Interactive for Release verification.


Sprint issues

Sprint Review DoD not met

At Sprint Review, the sprint-level DoD overlay is evaluated. If blocked on the auto-check (no-regression), the regression test suite must pass. If blocked on human checks (Sprint Goal, feedback addressed, docs), these require your confirmation.


Cannot advance to next sprint

Sprint Close must complete before Sprint Planning for the next sprint. Check the lifecycle state -- if stuck in SPRINTREVIEW or SPRINTRETRO, complete those ceremonies first.


Sprint carry-over confusion

Incomplete stories at Sprint Close are handled by sprint.carry_over_policy in .synaptory.yaml:

  • move_to_next (default) -- stories move to next sprint
  • keep_in_sprint -- stories stay in closed sprint (reporting only)
  • ask -- you choose at close time

Tracker issues

"Jira API not configured" or "GitHub CLI not available"

Remote tracker backends require authentication:

  • GitHub: Run gh auth login or set GITHUB_TOKEN env var
  • Jira: Set JIRA_API_TOKEN and JIRA_USER_EMAIL env vars
  • Teamwork: Set TEAMWORK_API_KEY env var

"Could not create GitHub Issue Types: Epic, Story"

Creating custom Issue Types requires admin:org scope. Ask an org admin to create them. Synaptory only needs standard repo scope for ongoing use.


Switching tracker providers

Use the migrate command:

python3 path/to/tracker_cli.py --project-dir . migrate --from local --to github

Then update tracker.backend in .synaptory.yaml.


Tracker health check

python3 path/to/tracker_cli.py --project-dir . health-check

Expected: {"status": "ok", ...}. If offline, the error message includes setup instructions.


Discover and context package issues

/synaptory producing incomplete context packages

Some analysis phases require git history. If the repo is shallow-cloned, risk and hotspot analysis will be limited:

git fetch --unshallow

Then re-run Discover.


Context packages not being loaded

Verify brownfield.context_packages is true in .synaptory.yaml and that packages exist in .synaptory/.orchestrator/context-packages/. Re-run Discover if missing.


Control Plane issues

"I get a 404 when I try to open /console/* or /portal/*"

ADR-019 retired both URL trees. Drop the prefix and use the root URL: /console/overview/overview, /portal/home/home, etc. Bookmarks at the legacy URLs need to be updated; there are no redirects.

"An admin-only page (Overview, Policy, System) doesn't show in my sidebar"

You aren't a member of synaptory-admins. The unified Sidebar filters entries via requires(viewer); admin-only items are hidden for non-admins. Have an existing admin add you to the Entra group, then sign out and back in (the grp claim is set at token-mint time).

"I see /cost but with empty results"

You aren't a member of any project (or you're a member-only on projects that have no activity in the window). The page is scope-aware: project members see their member projects' costs filtered to their own UPN; project admins see cross-UPN; global admins see everything. Unaffiliated users get an empty result rather than a 403.

"Sign-in redirect loops between /auth/login and Entra"

Almost always one of:

  • The browser's iron-session cookie is stuck — clear synaptory.h3t.co cookies and try again.
  • The Entra app's Web platform redirect URI list doesn't include the host you're signing in from. Verify with az ad app show --id $SYNAPTORY_CP_ENTRA_CLIENT_ID --query "web.redirectUris".
  • The Entra client_secret is rotated but .env.prod wasn't updated; the web container is failing the code-for-token exchange silently. Check docker logs web for AADSTS7000215 or similar.

"I can see my project in /projects but the Members tab is empty"

You're a member, not a project admin. Only project admins see the invite/revoke controls. See permissions.

"I revoked my session but the plugin keeps working"

Session revoke takes effect on the next API call from that session. If the plugin hasn't fired a hook since the revoke, the cached token is still in the OS keychain and inert. Run synaptory status to force an API call — you'll see a 401 and the plugin will surface the re-login prompt.

"/cost shows $0.00 across the board"

Either no receipts have been ingested yet (check /audit for any rows) or the Receipt.payload.token_usage field is empty. The latter happens if the CLI's outbox was queued before the platform started recording token usage. Force-flush with synaptory outbox flush.

"OTLP latency panel is empty on /reliability"

The CLI emits OTLP spans only when synaptory otel is configured. Check synaptory config show for the otel exporter URL. With no exporter, the only signals come from receipts (no per-stage latency).

"Inviting a user returns 404 even though they're in Entra"

The invite endpoint validates that the UPN exists in synaptory-users first. Add to the Entra group, then retry. The 404 is anti-enumeration — same status whether the UPN doesn't exist at all or just isn't in the group.


What's next?