H3Tech · Single-File Guide

Synaptory User Guide

SPQ-first delivery guidance for Claude Code, Codex, and Cursor.

36 chapters
v1.3.5
built 2026-09-22T22:28:49Z
Start · 01

Synaptory User Guide

Governed multi-agent delivery on Claude Code, Codex, and Cursor.

Synaptory turns an AI coding host into a governed delivery system. Bounded delivery roles perform the work, capability profiles guide optional runtime selection, and advancement occurs only when the lifecycle kernel validates the required receipts, evidence, and human decisions.

Start here

New users should follow Getting Started. It covers all three hosts, CLI sign-in, SPQ initialization, and the first Cycle.

The forward delivery path is SPQ. Existing Scrum and Kanban projects remain available during their retirement period, but new projects should use explicit build_mode: spq.

Current compatibility detail: an omitted build_mode is still interpreted as Scrum by the current initializer. Until that product default changes, set build_mode: spq explicitly. Do not rely on inference.

The SPQ lifecycle

SPQ is a scope-driven lifecycle with an integration barrier. A Cycle admits a bounded set of Work Units, executes them through governed roles, integrates the admitted result to the shared trunk at its barrier, and then either opens another Cycle or moves to Acceptance.

Four stages. Commit, Sync and Checkpoint are recorded events, not stages and not gates.

flowchart LR
  discovery[DISCOVERY] --> baseline{Baseline approval}
  baseline --> cycle[CYCLE]
  cycle --> barrier{Barrier: all admitted work, or none}
  barrier --> decision{Continue or accept?}
  decision -->|Another Cycle| cycle
  decision -->|Go-live| acceptance[ACCEPTANCE]
  acceptance -->|Not the final one| cycle
  acceptance -->|Final| complete[COMPLETE]

The events sit alongside those stages rather than inside them: Commit seals the admitted set and opens the Cycle, Sync records that one Cycle waited on another's result and how it cleared, and Checkpoint records the demonstration, the barrier verdict and the integrated trunk revision. Sync has zero or more occurrences and blocks nothing -- what blocks a Work Unit is an unsatisfied dependency.

The kernel—not prompt memory—selects the next ceremony, role, and legal transition. A failed check, missing receipt, stale dispatch, or unresolved human gate stops advancement.

The delivery hierarchy

LevelPurpose
EngagementThe approved baseline, the shared trunk, and every Acceptance. Ended by the final Acceptance and nothing else.
CycleA scope-defined increment with its own admitted set, source region, barrier and Checkpoint. The only unit of parallelism.
Work UnitThe atomic implement-and-verify unit, governed by receipts and Definition of Done, carrying its own declared path scope.

Three levels, not five. An earlier revision of this page described a Coordination Cycle above child Cycles above Workstreams; SPD-194 retires both of those layers. Two Cycles run concurrently because their declared source regions do not overlap, not because something above them coordinates them -- see ADR-035.

Hosts and execution runtimes are different

A host is the application where you invoke Synaptory: Claude Code, Codex, or Cursor. An execution runtime profile is an eligible adapter and placement selected for a governed attempt. Installing the plugin on a host does not enable runtime federation by itself.

The nine delivery roles map onto four runtime capability profiles:

Capability profileDelivery roles
AnalystResearch Advisor
PlannerProject Owner, Solution Architect
ProducerSoftware Engineer, Platform Engineer, Technical Writer
ProverQuality Engineer, Code Reviewer, Compliance Engineer

Capability profiles compose skills; they grant no authority. See Hosts and Runtimes for the installation, certification, placement, compliance, and cross-host boundaries.

Human gates and evidence

SPQ deliberately has more than one human decision:

GateHuman responsibility
Baseline approvalConfirm the Discovery baseline before Commit.
Commit scopeApprove the non-empty set of ready Work Units admitted to the Cycle.
CutAuthorize withdrawing unfinished work, with a reason. The one valve.
Checkpoint closeAccept the demonstrated increment on its integrated trunk revision, and choose another Cycle or Acceptance.
Acceptance / complete releaseAccept the release evidence and authorize completion. Only the final Acceptance closes the engagement.

Sync is not a gate. It records a dependency having cleared and authorizes nothing, so there is no Sync entry to confirm and no Sync to clear.

Between gates, roles operate inside an exact execution envelope. Each governed stage writes a dispatch-bound receipt, and verification is replayed before the kernel advances. See Enforcement.

What Synaptory produces

  • Requirements, approved baselines, and architecture decisions
  • Working code and infrastructure
  • Unit, integration, end-to-end, security, and regression evidence
  • Per-stage receipts bound to the selected role, attempt, and dispatch, with runtime identity when applicable
  • Sealed Cycle declarations, recorded cuts, and barrier verdicts naming the integrated trunk revision
  • Acceptance evidence, release reports, and operational documentation
  • Tracker updates through the configured local, GitHub, Jira, Teamwork, or Linear adapter

Control Plane

The browser Control Plane complements repository-owned state:

  • Cycles (/cycles) shows SPQ Cycle telemetry.
  • Attempts (/attempts) shows runtime progress, directives, evidence, and outcomes.
  • Quality, Cost, Reliability, Audit, and Projects provide scoped operational views.

Git and the governed local state remain authoritative for lifecycle advancement. The Control Plane reports what was delivered to it; it is not a second scheduler.

Legacy lifecycles

Scrum and Kanban are maintained for existing projects while retirement is planned. They are not the recommended starting point, and host certification is not uniform:

  • Codex and Cursor certify SPQ; Scrum and Kanban are explicitly uncertified on those hosts.
  • Legacy Multi-Spec partitions Scrum/Kanban tracking. SPQ uses native Cycle identity instead and ignores SYNAPTORY_ACTIVE_SPEC.
  • Migration must use governed initialization/migration operations; never edit pipeline state by hand.

See Migrating to SPQ before changing an existing project.

Guide map

Start

SPQ concepts

Product and operation

What's next

plugin to platform, and what it does and does not change for this install

Guides

Legacy

Reference

Start · 02

Getting Started

This guide takes a new user from installation to the first governed SPQ Cycle on Claude Code, Codex, or Cursor.

What you will set up

Synaptory has two required components:

  1. A host plugin for Claude Code, Codex, or Cursor.
  2. The synaptory CLI, shared across hosts and projects on the same laptop.

Runtime federation is optional and comes later. First establish a working SPQ project on one host.

1. Choose a host

HostMinimum and scopeInvocationImportant boundary
Claude CodeClaude Code 2.1.196 or newer/synaptoryFull host-native hook surface. Reload after installation or update.
CodexCodex CLI 0.147.0 or newer; standard, non-regulated SPQ$synaptoryProject bootstrap is dry-run first, installs nine managed profiles, and requires a new task after apply.
Cursor IDEStaff Team marketplace or licensed local install/synaptorySPQ is certified. Reload the window after install.
Cursor CLI/headlesscursor-agent with project MCP preflight/synaptory in the agent promptThe IDE's local-plugin directory is not loaded by the CLI; preflight is mandatory.

Use a single host as the writer for an active governed stage. Sharing the same repository does not create a supported cross-host handoff workflow.

2. Install the CLI and sign in

Install once per laptop:

# macOS / Linux
curl -fsSL https://synaptory.h3t.co/cli/install.sh | bash
# Windows PowerShell
iwr -useb https://synaptory.h3t.co/cli/install.ps1 | iex

Then sign in with your organization identity:

synaptory login
synaptory whoami
synaptory projects list

For a machine without a browser, use synaptory login --device. See Install the CLI for PATH, update, checksum, and keychain details.

3. Install the host plugin

Claude Code

Run these commands inside Claude Code:

/plugin marketplace add https://github.com/h3tech-ai/marketplace
/plugin install synaptory@h3tech-ai

Restart Claude Code or reload the window. For automatic updates, open /plugin, select the h3tech-ai marketplace, and turn Auto-update on.

Verify with:

/synaptory doctor

Codex

Run these commands in a terminal:

codex plugin marketplace add https://github.com/h3tech-ai/marketplace
codex plugin add synaptory@synaptory-dev

Start a new Codex task and invoke $synaptory. On the first project run, Synaptory checks readiness and presents a bootstrap dry-run if the managed profiles or project configuration are missing. Review the planned files, confirm apply, and then start another new task so Codex discovers the nine profiles.

Codex refuses regulated baa_enforced projects on this standard path. Do not interpret a successful install as regulated certification.

Cursor IDE

An organization administrator imports GitHub repository h3tech-ai/marketplace into the Cursor Team marketplace and makes the synaptory plugin available. Install it from the team catalog, then run:

synaptory skills sync --host cursor

Reload Cursor and verify with /synaptory doctor.

Synaptory is not distributed through the public cursor.com marketplace because that marketplace requires open-source packages.

Cursor CLI or CI

The IDE convention ~/.cursor/plugins/local is not loaded by cursor-agent. For a licensed checkout, wire and verify the project MCP before every headless run:

python3 plugin-cursor/scripts/preflight.py --project <project> --write
cd <project>
cursor-agent mcp enable synaptory
python3 plugin-cursor/scripts/preflight.py --project <project>

The final command must print ready: and exit 0. For an explicit plugin path, use agent --plugin-dir ./plugin-cursor.

4. Bind the repository to a project

At the repository root, identify the Control Plane project and select SPQ explicitly:

# .synaptory.yaml
project_id: "my-project"
build_mode: "spq"
engagement_mode: "structured"

tracker:
  backend: "local"

You can ask the host to generate the file:

Initialize this project for governed SPQ delivery.

Review the proposed file before approving it. In particular, confirm project_id, build_mode: spq, repository paths, and tracker configuration.

Why explicit? SPQ is the recommended lifecycle, but the current compatibility default for an omitted build_mode is still Scrum. Explicit configuration prevents a new project from entering the legacy lifecycle.

5. Declare the source region and the trunk

A Cycle declares the repository paths it may address and the one shared branch it integrates into. There are no lanes to define and no parallelism to switch on -- concurrency is a consequence of the path scope each Work Unit declares.

spq:
  source_region:
    - "api/"
    - "web/"
  trunk_ref: "refs/heads/dev"

Overlapping source regions are refused at declaration. That refusal is what lets two Cycles run concurrently without either one inspecting what the other admits.

6. Start the first Cycle

Give Synaptory an outcome, not an instruction to mutate lifecycle files:

Use SPQ to deliver account sign-in with audit logging. Start Discovery and
show me the baseline before Commit.

The normal path is:

  1. Discovery frames the outcome, the constraints, the source region and the evidence expectations.
  2. Baseline approval is a human gate. It needs a measured calibration sample, not just a sha -- review and explicitly approve or request changes.
  3. Commit admits a non-empty set of ready Work Units, each declaring its path scope, and seals the declaration. Nothing joins the Cycle afterwards.
  4. The Cycle dispatches the exact next role for each Work Unit and validates its receipt. Disjoint units run concurrently with nothing to enable; intersecting ones run in the order they declared.
  5. A cut, if the Cycle cannot finish its admitted set. Explicit reason, backlog return, and a key a later Commit can name. It never moves the baseline.
  6. The barrier evaluates the admitted set minus the recorded cuts -- all of it or none -- and integrates the result to the shared trunk.
  7. Checkpoint records the demonstration, the verdict, the integrated trunk revision and the cut list, and asks whether to open another Cycle or proceed to Acceptance.
  8. Acceptance runs the release roles and stops for the human release decision. Only the final one closes the engagement.

There is no Sync to wait for. Sync records that one Cycle waited on another's published result and how it cleared; it has zero or more occurrences and blocks nothing. What blocks a Work Unit is an unsatisfied dependency, and /synaptory status says which one.

At any boundary, ask:

/synaptory status

On Codex, use $synaptory and ask for status in the same request. Do not run the lifecycle Python modules directly and never edit .synaptory/.orchestrator/pipeline-state.json.

7. Add runtime federation only when needed

The host-native path is enough for the first Cycle. To inspect the runtimes the machine can serve:

synaptory runtimes list
synaptory runtimes doctor

Runtime selection remains inert until an enabled runtimes: policy is present in an SPQ project. The selected delivery role maps to one of four capability profiles, and policy cannot select anything outside allowed_profiles. Capability profiles do not grant authority; the dispatch envelope does.

Read Hosts and Runtimes before enabling it.

8. One shape, and when to open a second Cycle

There is one delivery shape: a Cycle. Open a second concurrent Cycle when the work has its own cadence and a source region that does not overlap the first -- that is the whole condition, and no layer above them composes anything.

  • Work that belongs to one increment: one Cycle. Continue with

SPQ Delivery.

  • Work with its own cadence and a disjoint region: a second Cycle, with its own

Lead, Crew and Checkpoint. Neither waits for the other.

  • Work that cannot be ordered -- a mutually dependent pair -- goes in one

Cycle. It cannot be split across two, and the declaration refuses the split and names the route.

  • Existing Scrum, Kanban, or Multi-Spec project: follow

Migrating to SPQ.

Next reading

Start · 03

Install the synaptory CLI

The synaptory CLI handles sign-in, session state, governed skill/policy delivery, diagnostics, telemetry, and optional Runtime Bridge operations. Install it once per laptop — the same install works across Claude Code, Codex, Cursor, and every Synaptory project you can access.

The CLI is shipped separately from all host plugins. The download script detects your OS/architecture, verifies SHA-256, and places the binary on 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.
  • Resolves latest.json, then downloads the versioned binary and sha256sums.txt from synaptory.h3t.co/cli/.
  • 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).
  • Resolves latest.json, then downloads synaptory-windows-amd64.exe and sha256sums.txt from synaptory.h3t.co/cli/.
  • 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.
synaptory statusFull diagnostic — control-plane URL, session state, skill cache, outbox depth.
synaptory logoutClear the cached session. The next governed host 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 normally run these operations. Claude Code uses native session hooks; Codex and Cursor obtain the same governance outcomes through their project bootstrap, supported hooks, and MCP integration:

  1. The host integration checks CLI/session readiness. If the cached session cannot be refreshed, it stops governed mutation and asks you to sign in.
  2. It refreshes the project's governed skill and policy cache.
  3. It loads host-native instructions/rules and reads canonical lifecycle state.
  4. It flushes durable telemetry when connectivity is available.

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 is needed; start a fresh host turn if the integration asks you to reload state.
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.

SPQ Concepts · 04

How Synaptory works

Synaptory is a governed delivery system that runs inside supported coding hosts and records authoritative lifecycle state in a shared control plane. The host helps people and agents do the work; Synaptory decides what is authorized, what evidence is required, and whether the work may advance.

If you want to install and run a first Cycle, start with Getting Started.


Component map

flowchart LR
  U["Delivery user"] --> H["Host adapter<br/>Claude Code · Codex · Cursor"]
  H --> K["SPQ governance<br/>dispatch + advance"]
  K --> R["Runtime adapter<br/>optional federation"]
  R --> A["Governed attempt"]
  A --> E["Events + receipt + evidence"]
  E --> K
  H --> C["synaptory CLI"]
  C <--> CP["Control Plane API"]
  CP <--> DB[("Canonical state<br/>policy · audit · telemetry")]
  CP <--> W["Control Plane web"]
ComponentWhat it owns
Host adapterHost-native instructions, skills, agents, hooks, and MCP wiring; the user's lifecycle conversation.
SPQ governanceState transitions, gate prerequisites, dispatch authority, idempotency, receipt validation, and advancement.
Runtime adapterExecution of one already-authorized dispatch envelope on a certified runtime profile.
synaptory CLIIdentity, project resolution, governed skill/policy sync, diagnostics, telemetry outbox, and Runtime Bridge operations.
Control Plane APIProject authorization, canonical lifecycle state, runner leases, runtime supervision, skills/policy, and telemetry ingestion.
Control Plane webHuman views for Cycles, Acceptances, attempts, evidence and administration.

Host and runtime are different roles

The host is where you talk to Synaptory. The runtime is where one authorized attempt executes.

You can use Claude Code as the host and keep all attempts there. SPQ runtime federation is an operator preview: an attempt can be executed on a certified Codex, Cursor, or managed Claude profile through the synaptory runtime commands, but enabling runtimes: does not make an ordinary Work Unit route there, because no host dispatch path calls the selector yet. Installing multiple host packages alone does not connect them, and a runtime cannot approve its own evidence or advance canonical state.

See Hosts and Runtimes for the support and profile matrix.


Why the control plane matters

A host-native session is useful but not sufficient for governed delivery. The control plane provides:

  • per-user and per-project authorization;
  • canonical SPQ state across sessions;
  • versioned policy and governed skill delivery;
  • immutable Cycle, Work Unit, attempt, and gate records;
  • leases and fencing for supervised workers;
  • evidence, cost, quality, reliability, and audit views.

This separation prevents a chat summary, a stale worker, or a runtime's private session state from becoming the delivery record.


How a Work Unit travels

  1. The host re-reads the current Cycle and Work Unit.
  2. The dispatch kernel checks state, dependencies, selected role, policy, and

budget.

  1. The host runs the dispatched role through its own runtime.

Runtime selection, the signed dispatch envelope, and adapter-prepared execution contexts exist as components and are not yet on this path. See Hosts and runtimes for what is and is not wired.

  1. Supervision records typed events; the runtime produces artifacts and a receipt.
  2. The advance kernel validates identity, binding, required evidence, and Checkpoint policy.
  3. Only then may the Work Unit advance. Human gates still require explicit approval.

Retries create new attempts. They never erase the history of the previous attempt.


Identity, skills, and policy

synaptory login establishes the user's Entra identity and stores the session in the OS credential store. The control plane checks project membership per request.

Host packages contain the integration scaffold. Governed skill and policy content is fetched through the CLI and tied to the authenticated project context. No source-control token is a substitute for Synaptory project membership.

For headless environments, use synaptory login --device.


Control Plane views

Delivery users most often use:

  • /cycles for Cycle stage, gates, source region, Crew and Work Units;
  • /attempts for runtime state, evidence, and supervision history;
  • /projects for project configuration and access; and
  • /quality, /cost, /reliability, and /audit for governed outcomes.

The same pages are role-aware and server-scoped to the caller's permissions.


What's next

SPQ Concepts · 05

Architecture

This page maps the SPQ control flow onto Synaptory's local and hosted components. It is intended for operators and integrators; most delivery users only need How Synaptory works.


Trust boundaries

flowchart TB
  subgraph Local["User or runner environment"]
    H["Claude Code / Codex / Cursor"]
    HA["Host adapter"]
    CLI["synaptory CLI"]
    RT["Runtime adapter"]
    WS["Bound workspace"]
    H --- HA
    HA --- CLI
    CLI --- RT
    RT --- WS
  end

  subgraph Control["Synaptory Control Plane"]
    API["FastAPI"]
    DB[("Postgres")]
    WEB["Next.js"]
    API --- DB
    WEB --- API
  end

  CLI <-->|"authenticated HTTPS"| API

The host can propose operations. The dispatch kernel authorizes them. The runtime adapter can execute only the envelope it receives. The advance kernel alone decides whether evidence is sufficient to advance. The human alone approves human gates.


Governed attempt sequence

sequenceDiagram
  participant User
  participant Host as Host adapter
  participant CP as Control Plane
  participant Runtime as Runtime adapter
  participant Evidence as Receipt/evidence

  User->>Host: Continue Work Unit
  Host->>CP: Read canonical Cycle + Work Unit
  CP-->>Host: State, policy, manifest binding
  Host->>CP: Request governed dispatch
  CP-->>Host: Authorized envelope + attempt ID
  Host->>Runtime: Execute envelope
  Runtime-->>CP: Typed supervision events
  Runtime->>Evidence: Artifacts + receipt
  Host->>CP: Request Checkpoint/advance
  CP->>Evidence: Validate binding and proof
  CP-->>Host: Advanced or refused with reasons
  Host-->>User: Canonical outcome

An agent completion message is not an advancement signal. The host must report the canonical result returned after validation.


Static and application surfaces

URL patternServed byPurpose
/, /home, /projects, /cycles, /attempts, analytics and administration pagesNext.js webRole-aware Control Plane UI.
/auth/*, /api/web/*Next.js webBrowser authentication and web-facing API routes.
/v1/*FastAPICLI, lifecycle, runtime, policy, and telemetry API.
/get-startedStatic web assetShort multi-host installation landing page.
/docs/getting-started.htmlGenerated static documentationStandalone onboarding guide.
/docs/user-guide.htmlGenerated static documentationComplete user guide.
/cli/*Static distributionCLI installers, release metadata, and binaries.

See URLs for the public URL map.


Runtime supervision

A registered runner advertises certified profiles and obtains time-bounded leases from the control plane. Lease renewal establishes continued ownership. Fencing rejects a stale worker after ownership changes.

Runtime output is reduced to typed, bounded supervision events; arbitrary runtime prose does not become canonical state. The attempt record includes terminal outcome, failure class, budget facts, receipt location, and the envelope authority used to produce it.

Local one-shot commands can inspect local attempts. Cross-machine control requires a live control-plane runner/worker path, and the user-facing result must distinguish “recorded locally” from “delivered to the running worker.”


Deployment components

ComponentImplementationResponsibility
Edge/static routingCaddyTLS, routing, static downloads and docs.
WebNext.jsRole-aware Control Plane pages.
APIFastAPIAuth, project/lifecycle/runtime/policy services.
DatabasePostgresCanonical and operational records.
ObservabilityGrafana and telemetry pipelineOperational and delivery signals.
CLI distributionStatic release treeInstallers and versioned binaries.
Host distributionsClaude marketplace, Codex plugin, Cursor packageHost-native integration scaffold.

Data ownership

DataAuthority
Cycle, Work Unit, gate, attempt, and release stateControl Plane canonical store
Project configuration.synaptory.yaml plus validated control-plane policy
Source and generated artifactsBound project/worktree storage
Runtime-native sessionsEphemeral/non-canonical
Receipts and verification evidenceAttempt artifacts plus accepted control-plane records
Tracker issuesExternal projection; never the sole lifecycle authority

What's next

SPQ Concepts · 06

Identity and Access

Who you are (Entra — any H3Tech identity can sign in), whether you're an admin (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/synaptory_api/tokens.py KeyVaultSigner). The public key is exposed at GET /v1/public-key so the CLI can verify signed config offline.


Groups: synaptory-admins (and synaptory-users)

Per ADR-024, sign-in is not group-gated — any H3Tech Entra identity that passes token verification can log in. Group membership drives one thing: admin.

  • synaptory-admins — the admin role. Grants access to every /v1/admin/* endpoint and the admin-only pages. Members without it sign in as regular users.
  • synaptory-users — no longer a login gate. It's retained only to seed the dev/on-prem local-auth slots and as a documentation marker; Synaptory does not require it for access.

A user with no project membership still signs in — they just see an empty scope until an operator adds them to a project (project_members).

The grp claim is a list, so admins carry synaptory-admins. 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/synaptory_api/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/synaptory_api/watermark.py and is applied by api/synaptory_api/routers/skills.py. See ADR-016 for the IP-delivery model.


What's next

SPQ Concepts · 07

Personas

Synaptory serves several roles. A person may hold more than one, but authority follows the action being performed rather than the person's informal title.


Delivery user

You are: a developer, product owner, technical lead, or delivery manager running governed work inside Claude Code, Codex, or Cursor.

You use: the host entry point, .synaptory.yaml, the synaptory CLI, and the Cycle/attempt views in the Control Plane.

Start with:


Gate approver

You are: the human accountable for the admitted set at Commit, a cut, the Checkpoint close, or an Acceptance.

You decide: whether the proposed scope/outcome is acceptable given the displayed evidence, exceptions, dependencies, and residual risk.

You do not delegate: the approval itself to a host agent or runtime. Automation may prepare the decision package, but it cannot approve on your behalf.

Start with: SPQ Cycle Model and Release.


Project administrator

You are: responsible for project membership, policy, trackers, runtime eligibility, and delivery visibility.

You use: /projects, /policy, /cycles, /attempts, and the analytics/audit pages available to your role.

Start with: Configuration, Inviting Users, and Using the Control Plane.


Runner operator

You are: responsible for machines that execute local or managed runtime profiles.

You verify: runtime installation/version, credential scope, registration, leases, fencing, budgets, cancellation delivery, and teardown.

Useful commands:

synaptory runtimes list
synaptory runtimes doctor
synaptory runtimes register
synaptory runtime explain --attempt <id>

Start with: Hosts and Runtimes and Troubleshooting.


Global administrator

You are: responsible for the Synaptory service across projects.

You own: tenant-wide access, policy publication, system health, pricing, backups, audit, runner supervision, and incident response.

You do not use delivery authority to bypass: project membership, evidence gates, or human approvals.

Start with: the operator documentation in the repository module READMEs and Architecture.


Synaptory maintainer

You are: changing the host distributions, CLI, API, web application, lifecycle kernel, runtime adapters, or infrastructure.

You preserve: cross-host semantic parity, fail-closed capability behavior, versioned contracts, append-only state, and accurate user documentation.

You use: the source repository and maintainer-only ./synaptory build/release script. Those commands are not part of the consuming-project interface.

Start with: the relevant module README, architecture decisions, and the generated-doc build/tests.


Legacy project owner

You are: responsible for an existing Scrum or Kanban compatibility project.

Recommended path: finish a safely bounded in-flight unit if necessary, preserve historical state, and start new governed work as SPQ. Do not enable runtime federation on the legacy lifecycle.

Start with: Migrate to SPQ.

SPQ Concepts · 08

The SPQ Delivery Lifecycle

SPQ is Synaptory's primary lifecycle for new and continuing delivery. It makes scope, role dispatch, evidence, integration, and human approval explicit.

Unlike a prompt-driven workflow, SPQ does not let the current conversation decide what happens next. The repository-owned lifecycle state and the shared advance kernel select the next legal action.

Lifecycle overview

Four stages. Commit, Sync and Checkpoint are recorded events alongside them, not stages of their own -- a distinction that matters because an event gates nothing.

stateDiagram-v2
  [*] --> DISCOVERY
  DISCOVERY --> CYCLE: baseline approved
  CYCLE --> CYCLE: another Cycle
  CYCLE --> ACCEPTANCE: go-live candidate
  ACCEPTANCE --> CYCLE: not the final Acceptance
  ACCEPTANCE --> COMPLETE: final Acceptance, evidence valid, human approval
  COMPLETE --> [*]

COMPLETE has no outgoing transition at all, which is stronger than an empty one: there is no edge to relax, so only the final Acceptance can end the engagement.

Discovery

Discovery frames the outcome, the constraints, the source region, the dependencies and the evidence expectations. It produces the baseline every later Commit is measured against.

Discovery ends at a human baseline-approval gate, and the baseline is more than a revision: approved scope and non-scope, timeline and cost, a measured calibration sample, the architecture and current-system assessment, and the approving human decisions. A git sha plus a boolean cannot satisfy it. Agents may recommend a baseline; they cannot approve it on the user's behalf.

Commit

Commit is the event that opens one scope-defined Cycle. It:

  • admits a non-empty set of ready Work Units, each declaring its path scope;
  • seals the declaration -- the hash is what closes the set, so nothing joins the

Cycle afterwards;

  • names exactly one owning Work Unit for every shared path;
  • publishes the barrier criteria in advance, so the Cycle sizes against them

rather than discovering them at close; and

  • records dependencies and Definition of Done expectations.

A Cycle ends when its admitted scope is terminal, not when a calendar interval expires. No timer forces an unverified close: a Cycle that cannot finish cuts rather than running long.

Cycle Execution

The advance kernel repeatedly selects an exact Work Unit and role. The normal implementation path is:

Software Engineer → Quality Engineer → Code Reviewer → Work Unit DoD

Conditional or recovery actions may select the Project Owner, Solution Architect, Compliance Engineer, Platform Engineer, Technical Writer, or Research Advisor. The orchestrator must use the selected action and may not replace it with a role chosen from memory.

Each dispatch carries an execution envelope and unique dispatch identity. The receipt must be written to the exact requested location, validate against the contract, and bind to the active dispatch before advancement is legal.

The barrier

The all-or-nothing integration barrier runs at Checkpoint, over the admitted set minus the recorded cuts, and it integrates the result to the shared trunk. It starts once every admitted Work Unit is done or explicitly cut.

Its criteria are published at Commit from one constant:

CriterionAsserts
admitted_set_closedthe set the barrier ranges over is the one Commit fixed
path_scopes_disjointno two units in a concurrent set claim intersecting paths
shared_paths_ownedevery shared path has exactly one owning Work Unit
criteria_all_returnedevery criterion actually returned a result
acceptance_criteria_meteach retained unit met the criteria it was admitted with
regression_greenthe combined result has no regression
trunk_integratedthe result reached the shared trunk

criteria_all_returned is the one worth reading twice. Without it, evaluated nothing and evaluated everything and passed are the same verdict -- and an unevaluated criterion counts as unmet, never as absent.

There is no partial admission: no per_workstream mode, no per-unit promotion, no closing the part that passed. An unresolved dependency, an unverifiable event, a superseded declaration or a failed regression blocks the Cycle, and the remedy is to fix it or to cut the work that will not make it.

If another Cycle moves the trunk while this one is ready, the candidate is rebuilt and re-verified.

Sync is not this

Sync is a separate event, and it is the change most likely to surprise a reader of the older model. It records that one Cycle waited on a result from another and how that cleared. It has zero or more occurrences, no calendar slot, and it blocks nothing at all. What blocks a Work Unit is an unsatisfied dependency; the absence of a Sync event blocks nothing. There is no Sync entry to confirm and no Sync to clear.

Checkpoint

Checkpoint is the event recording what the Cycle proved: the demonstration, the barrier verdict, the integrated trunk revision, and the cut list. It then presents the next governed decision:

  • open another Cycle; or
  • take the integrated revision to Acceptance.

Checkpoint is not a release, and it is not the authority: the barrier is the mechanical condition and a named human records the close. It is the increment boundary where scope, evidence and follow-up work become visible -- and no closed Cycle can publish code later.

Acceptance and Complete

Acceptance runs the release-level Quality Engineer, Compliance Engineer, Platform Engineer, Technical Writer, and Code Reviewer activities. Each must produce a valid release receipt.

Acceptance is repeatable (C-15). Each go-live compiles its own evidence package on an Acceptance identity plus the trunk digest it pinned, and delivery continues in another Cycle meanwhile.

Complete is refused when any required receipt is absent or invalid, tests fail, a critical security finding remains, Code Review is not approved, or a closed Cycle lacks a recorded green barrier verdict naming its integrated trunk revision. Only the final Acceptance closes the engagement, and whether an Acceptance is the final one is derived from outstanding commitments and a recorded handover rather than read from a flag. The final release decision is a human gate.

Two Cycles, and nothing above them

SPD-194 retires the Coordination Cycle. It was the release layer above independent child Cycles, and it existed only because integration was deferred: nothing reached the trunk until a human merged, so something downstream had to gather it.

With the barrier integrating to the shared trunk at each Checkpoint there is nothing to gather. Two Cycles run concurrently when their declared source regions do not overlap -- that is the whole condition. Each has its own Engineering Lead, Crew, cadence and Checkpoint; neither waits for the other, and no cross-Cycle check runs at admission.

Two limits follow, and both are refusals rather than conventions:

  • a mutually dependent pair cannot be split across Cycles. Work that cannot

be ordered cannot be split, and the declaration refuses the split and names the one-Cycle route.

  • a Cycle addresses one repository. A cross-repository declaration is

refused, and the refusal names the published-package route.

See ADR-035.

Standalone operations

Status, Doctor, Help, Debug, Explore, Review, Secure, Document, Preview, and other focused operations can run without advancing SPQ. They still respect host readiness, project boundaries, and role authority.

Legacy lifecycle status

Scrum and Kanban remain available for existing projects while retirement is planned. They use the same shared receipt and advance kernel, but they are not the recommended path for new work. Codex and Cursor explicitly treat them as uncertified delivery paths.

Do not change an active project's build_mode and then hand-edit the state to match. Follow Migrating to SPQ.

SPQ Concepts · 09

SPQ Cycle Model

SPQ keeps three levels distinct. Older sprint vocabulary blurred them, and an earlier revision of this page described five -- a Coordination Cycle above child Cycles above Workstreams. SPD-194 retires the Workstream and the Coordination Cycle and refuses the folk term Cycle of Cycles; see ADR-035.

The three levels

flowchart TD
  engagement[Engagement]
  cycle[Cycle]
  unit[Work Unit]
  engagement --> cycle
  cycle --> unit
LevelOwnsDoes not own
EngagementThe baseline, the shared trunk, and every AcceptanceA Cycle's admitted set or its cadence
CycleIts admitted Work Units, its source region, its barrier, its CheckpointAny other Cycle. No Cycle inspects what another admits
Work UnitAtomic implementation and proof, and its declared path scopeThe Cycle's barrier or its integration

The Cycle is the only unit of parallelism (C-01, SC-MTH-012). Two Cycles run concurrently because their declared source regions do not overlap, not because something above them coordinates them.

Four stages, three events

DISCOVERY ──► CYCLE ──► ACCEPTANCE ──► COMPLETE
                ▲            │
                └────────────┘   a non-final go-live returns to CYCLE

Commit, Sync and Checkpoint are recorded events, never stages and never gates. That is the largest change from the older model, and the part most worth reading twice:

  • Commit seals the admitted set and opens the Cycle. It blocks nothing: a

Cycle with no Commit event simply has nothing for the barrier to range over.

  • Sync records that one Cycle waited on a result from another and how it

cleared. It has zero or more occurrences and blocks nothing at all. What blocks a Work Unit is an unsatisfied dependency; the absence of a Sync event blocks nothing. If you are used to waiting for Sync, stop -- there is nothing to wait for.

  • Checkpoint records the demonstration, the barrier verdict, the integrated

trunk revision and the cut list. The barrier is the mechanical condition and a named human is the authority; the event is the record of both.

Cycle identity

A Cycle is scope-defined. Its sequence number is allocated within its own project and is not globally unique across clones -- two clones can each open a Cycle 7. Anything crossing a Cycle boundary uses the stable cycle_id and the declaration_hash, never a display number.

The sealed declaration fixes the admitted Work Units, the source region, the trunk, the barrier criteria and the evidence expectations. It is written twice -- a local copy and a committed one that travels through git -- and a reader consults both, because a clone that fetched the Cycle holds only the second. If the local board is on a superseded revision, dispatch stops until the Cycle is hydrated again.

Source region, not a lane

A Cycle declares the source region it may address (C-08): repository-relative directory prefixes. Overlapping regions are refused at declaration, which is what lets concurrent Cycles stay independent -- no Cycle has to inspect what another is admitting.

There is no durable Workstream and no lane pin. A Crew is the people and agents seated on one Cycle; it grants nothing and is re-seatable between Cycles without changing a single barrier admission. An Engineering Lead is named per Cycle.

SPQ never resolves anything through SYNAPTORY_ACTIVE_SPEC -- that variable belongs to the Scrum/Kanban Multi-Spec mechanism, and an SPQ project ignores it.

Work Units, and how concurrency actually works

A Work Unit is admitted at Commit and carries:

  • a stable identity and a kind;
  • at least one acceptance criterion;
  • a declared path_scope -- the paths it may change;
  • dependency edges, each with a condition;
  • optionally acceptance_cases (the authored set) and execution_order.

path_scope is required, and concurrency is its consequence (C-07, SC-MTH-010). There is no parallelism switch to turn on:

  • Two units whose declared scopes intersect are refused at Commit unless

each declares a distinct execution_order. Intersecting work may run in one Cycle -- sequentially -- but never concurrently.

  • With an order declared, a second dispatch onto an intersecting scope is

refused at dispatch with scope_collision while the first holds a live attempt.

  • Disjoint work proceeds with no enablement. Nothing has to be configured

for two disjoint units to run at once.

The scopes compared are the ones in the sealed declaration, never the board: the board is agent-writable, and a unit that could narrow its own recorded scope could dispatch into another unit's files.

A shared path -- one more than a single unit would otherwise touch -- names exactly one owning Work Unit. Never none, never two.

Cutting is the one valve

A Cycle that cannot finish its admitted set cuts rather than running long. A cut:

  • needs an explicit reason (there is no default);
  • cannot take a finished unit -- it is the valve for unfinished work;
  • returns the unit to the backlog and issues a key a later Commit can name;
  • never moves the approved baseline. A cut that moved it would be a

re-baseline wearing a cut's name.

The cut is a committed record beside the declaration, not a field inside it: the declaration is sealed, and a resealable commitment is not a commitment. A later Commit links the re-admission, so cut and re-admitted and cut and forgotten are different records.

The barrier's subject is the admitted set minus the recorded cuts. The count taken at Commit does not shrink -- that is the denominator the cut-rate is measured against.

Acceptance repeats

Acceptance is not terminal (C-15, SC-MTH-014). Each go-live compiles its own evidence package from records the work already produced, and delivery continues in another Cycle meanwhile. Only the final Acceptance closes the engagement and records the handover -- and whether an Acceptance is the final one is derived from outstanding commitments and a recorded handover, not read from a flag somebody could set.

Repository authority

Lifecycle state, declarations, receipts and verified events are repository-owned evidence. The Control Plane provides visibility and supervision, plus the two records that must live outside the executing agent's reach -- the source-region registry and the authority-decision store -- because a process-local lock cannot be atomic across clones.

Do not:

  • edit pipeline state directly;
  • hand-author receipt evidence;
  • use a branch tip where an exact integrated revision is required;
  • let two hosts mutate the same governed stage concurrently; or
  • treat a specification document as execution state.
SPQ Concepts · 10

Hosts and Runtimes

Synaptory supports several coding hosts and several execution runtime profiles. They solve different problems and must not be treated as synonyms.

Host versus runtime

ConceptMeaningExample
HostThe application where the user invokes Synaptory and sees lifecycle guidance.Claude Code, Codex, Cursor
Runtime familyThe coding-agent implementation that executes an attempt.claude-code, codex, cursor-agent
Adapter profileA certified runtime family, placement, capability, and policy combination.codex-local-v1
PlacementWhere the adapter executes.local, managed-laptop
AttemptOne execution of one immutable dispatch envelope.A QE proof run for one Work Unit

Installing a plugin selects a host. It does not automatically opt the project into runtime selection or permit a different runtime to execute a stage.

Host support matrix

HostInstall and invokeCertified delivery scopeKey limitations
Claude CodeH3Tech marketplace; /synaptoryPrimary SPQ host with the full Claude hook adapterRequires Claude Code 2.1.196 or newer. Organization compliance policy and contract determine regulated use.
CodexCodex marketplace; $synaptoryStandard, non-regulated SPQ on Codex CLI 0.147.0 or newerRefuses baa_enforced; four total agent threads including the parent, so five Acceptance roles run sequentially; new task required after bootstrap.
Cursor IDEStaff Team marketplace; /synaptorySPQPublic marketplace is not used. Cursor model substitution is verified through receipts rather than trusted from configuration alone.
Cursor CLI/headlessProject MCP preflight or agent --plugin-dir; /synaptorySPQ when preflight reports readyThe IDE local-plugin path is ignored. One-level agent nesting.

Scrum and Kanban share the kernel but are uncertified on Codex and Cursor. New projects should use SPQ.

Capability profiles

Runtime policy is written against four stable capabilities. The selected delivery role projects to one of them for the bounded attempt:

ProfileDelivery rolesTypical capability
analystResearch AdvisorRead, investigate, compare, explain
plannerProject Owner, Solution ArchitectDefine scope, architecture, and readiness
producerSoftware Engineer, Platform Engineer, Technical WriterModify governed artifacts and run checks
proverQuality Engineer, Code Reviewer, Compliance EngineerVerify evidence and return findings or verdicts

Synaptory v1 still dispatches and receipts the selected delivery role. Its fixed stage/capability projection supplies the runtime selector and envelope overlay. Capability profiles grant no authority.

Available pilot profiles

The current runtime bridge exposes these profiles:

ProfileRuntime familyPlacementScope
claude-local-v1Claude Codelocalanalyst, planner, producer, prover
codex-local-v1Codexlocalproducer, prover (certified, and not selectable today: see below)
cursor-local-readonly-v1Cursor Agentlocalread-only prover
claude-managed-standard-v1Claude Codemanaged-laptopproducer, prover on a materialized disposable workspace

Always inspect the installed CLI rather than assuming a machine can serve a profile:

synaptory runtimes list
synaptory runtimes doctor
synaptory runtimes doctor --profile codex-local-v1

doctor distinguishes a known profile from a runtime that is actually installed, reachable, version-compatible, and eligible on that machine.

Why codex-local-v1 reports not-ready even when Codex is installed

A receipt has to record the exact model that produced it, and a stand-in is refused rather than accepted: a receipt naming codex-runtime-unattributed is evidence of nothing, and it is worse than an empty field because only the empty one is visibly missing.

Codex does not tell anyone which model ran. A whole codex exec --json run is thread.started, turn.started, one or more item.completed, and turn.completed with a usage block, and none of them carries a model. Claude Code and Cursor Agent both open with a session header that names one; Codex has no equivalent line. Every envelope the kernel mints leaves the model to policy (model_route.requested: "policy-default"), so on a governed dispatch the runtime is the only possible source, and there is none.

So doctor reports the profile not-ready with that reason, register withholds it, and a dispatch to it is refused before the runtime starts. The alternative was measured: a governed Codex attempt implemented its Work Unit, ran its tests green, and was closed as a structural failure 605 seconds later for a model it could never have produced. The refusal was right; arriving at it after the work was not.

This is a certification that cannot currently be served, not a withdrawn one. The profile stays in the table, and the day the Codex CLI states its model the declaration in cli/internal/cli/runtime_local.go changes and the profile becomes selectable again. Re-measure it yourself with:

SYNAPTORY_RUNTIME_MODEL_PROBE=1 go test ./internal/cli \
  -run ModelIdentityDeclarationSurvivesALiveProbe -v

Until then, route producer and prover work to claude-local-v1 (or claude-managed-standard-v1); cursor-local-readonly-v1 is unaffected and still serves prover.

How cursor-local-readonly-v1 stays read-only

Its ceiling is the runtime's own plan mode, not a sentence in the prompt. The bridge invokes cursor-agent --mode plan, so Cursor itself refuses edits whatever the model decides to attempt; --force and --yolo, which would grant those writes back, are never passed. --trust accompanies them and grants nothing: without it Cursor stops on its workspace-trust banner and exits before the attempt starts.

One consequence is visible in the evidence. A plan-mode runtime has no file handle, so it cannot write the receipt the envelope names. It states the receipt as JSON in its final message instead, and the bridge files it at the envelope's receipt path before validation. The runtime still authors the receipt — only the delivery moves — and an attempt that states nothing receipt-shaped fails as workflow-structure rather than receiving one the bridge invented.

Where a managed attempt's receipt ends up

claude-managed-standard-v1 runs in a workspace the bridge materialized from the envelope and destroys at teardown, so a receipt left there would go with it. Before teardown the bridge files that document into your project, at the same relative path the envelope named, which is the canonical receipt path the advance gate reads. So validate_receipt and advance act on the file the attempt actually produced rather than on a digest of a file that no longer exists.

Two consequences for an operator:

  • A managed attempt needs a project directory. Run the bridge from inside

the project, or pass --project-dir. Without one the attempt is refused at Prepare rather than running to completion and then having nowhere to put its evidence.

  • A receipt that could not be filed fails the attempt. A blocked path, a

symlinked receipt directory or an unwritable project reports failed with workflow-structure and names the path, because a receipt nobody can open is not evidence. synaptory runtime status --attempt <id> prints the filed path for an attempt that completed.

Nothing else crosses out of the workspace: not the generated settings, not the runner's Claude configuration, not the runtime's session state, and no credential. The artifacts the receipt names stay in the workspace and survive only as digests on the attempt record, which is what keeps the placement disposable.

Enabling runtime selection

Status: not yet wired into normal dispatch. The policy below is parsed and validated, and the selector resolves against it, but no host dispatch path calls the selector today. Configuring runtimes: therefore has no effect on an ordinary SPQ Cycle Execution run: the host dispatches through its own runtime exactly as it did before. The selector and the Runtime Bridge are reachable only through the operator commands in the next section.

Do not adopt this section expecting routing behaviour. It is published so the policy shape can be reviewed and so a project can be configured ahead of the wiring, which is tracked as the dispatch-integration work in Epic #339.

Runtime selection applies only to SPQ and is inert when the section is omitted. A minimal policy is:

runtimes:
  version: 1
  enabled: true
  allowed_profiles:
    - "claude-local-v1"
    - "codex-local-v1"
  allowed_placements: ["local"]
  preferences:
    producer:
      - "claude-local-v1"
    prover:
      - "codex-local-v1"
  required_capabilities:
    producer:
      - "workspace.write"
      - "process.test"
    prover:
      - "receipt.v2"
  fallback:
    enabled: true
    max_reroutes: 2
    allow_out_of_order_reroute: false

allowed_profiles is the authority ceiling. A preference or pin can reorder or narrow it but cannot add an unauthorized profile. Unknown policy versions, invalid capability keys, missing requirements, and exhausted reroutes fail closed or leave selection inert with an explanation.

Runtime Bridge commands

The CLI exposes two command families:

synaptory runtimes list
synaptory runtimes doctor [--profile <id>]
synaptory runtimes register

synaptory runtime execute --envelope <path-or->
synaptory runtime status --attempt <id>
synaptory runtime cancel --attempt <id>
synaptory runtime explain --attempt <id>

Most users use list, doctor, and the Control Plane Attempts view (/attempts). Direct execute is for an already-authorized dispatch envelope; it is not a shortcut around the SPQ selector or lifecycle kernel.

An attempt has immutable identity. Status, cancellation, progress, directives, and the final receipt attach to that attempt rather than to a mutable filename or chat session.

Managed placement

The first managed profile is Claude Code on a managed laptop. The bridge materializes the exact repository revision into a disposable workspace, injects only declared connector references and capability ceilings, launches the runtime, captures normalized progress and evidence, and disposes of the workspace.

Managed placement is not available to baa_enforced projects in the current standard profile. It also does not make every local profile available remotely; each (runtime family, placement) pair needs its own certified adapter.

Having the pinned Claude Code release installed does not make a laptop a managed runner. The managed profile is served only where the runner was deliberately configured for it, with SYNAPTORY_CLAUDE_CONFIG_DIR pointing at the isolated vendor-state directory that gives the placement its one dedicated subscription identity. A developer laptop without it probes as a local runner, so doctor reports claude-managed-standard-v1 as not ready, and neither runtimes register nor the worker advertises it there.

Compliance boundaries

  • Codex: the standard Synaptory package refuses regulated projects. A host

account or contract on its own does not override that product gate.

  • Cursor: HC0 requires Cursor Enterprise, a signed BAA, organization-wide

Privacy Mode lock, and an eligible model. Teams, Pro, and Start are refused; third-party MCP services are not automatically covered.

  • Claude Code: follow the organization's approved Claude access path,

contract, model pins, and Synaptory policy. This guide does not make a blanket regulated-certification claim.

ZDR, BAA eligibility, and Synaptory host certification are separate questions.

Cross-host discipline

Cross-host handoff is not a product feature. Claude Code, Codex, and Cursor can read the same repository-owned state, but an active governed stage follows normal single-writer discipline. Finish or stop the active dispatch, persist its valid receipt and state, and then resume from the kernel-selected action on the chosen host.

Never copy chat history or invent a transfer receipt to make a host switch look governed.

SPQ Concepts · 11

Operation Modes

Synaptory classifies a request, reads project state, and selects either a lifecycle action or a focused operation. You normally describe the outcome rather than memorizing commands.

SPQ lifecycle operations

On a project with explicit build_mode: spq, build and continuation requests are routed through the SPQ kernel:

IntentExampleGoverned result
Start delivery"Use SPQ to deliver account recovery"Discovery or the current required ceremony
Continue"Continue the Cycle"The exact next ceremony, dispatch, transition, or gate
Inspect"Show SPQ status"Read-only Cycle, Work Unit, Sync, and receipt summary
Release"Prepare this for Acceptance"Acceptance only when the kernel says the project is eligible

The orchestrator must call the state authority at each boundary. It cannot use the last chat message as permission to skip a role, transition, or human gate.

An omitted build_mode still falls through to legacy Scrum for compatibility. That is why new projects must set build_mode: spq explicitly.

Diagnostics and setup

ModeTrigger examplesBehavior
Doctor"doctor", "check readiness", "validate config"Read-only host, auth, configuration, lifecycle, runtime, and policy diagnostics
Init"initialize this project for SPQ"Detects the project and proposes configuration/state through the governed host flow
Status"where are we?", "show Cycle status"Compact lifecycle, Work Unit, receipt, gate, and attempt summary
Help"help", "what can Synaptory do?"Host-aware quick reference
Report"report a Synaptory bug"Gathers bounded diagnostic context for a product issue
UpdateAutomaticChecks the installed host package and CLI version without blocking an offline run

Doctor never repairs state by silently writing files. Init or bootstrap must show planned changes and follow the host's confirmation rules.

Focused delivery operations

These operations can run without advancing an SPQ Cycle unless the request explicitly binds them to a Work Unit dispatch:

ModeTypical requestPrimary role
Debug"Find why login returns 500"Software Engineer with structured root-cause workflow
Explore"Help me compare these designs"Research Advisor
Review"Review this branch"Code Reviewer, read-only
Secure"Run a security review"Compliance Engineer
Test"Add tests for this change"Quality Engineer
Architect"Design the event contract"Solution Architect
Document"Write the operator runbook"Technical Writer
Optimize"Investigate API latency"Platform Engineer and Code Reviewer
Stabilize"Add characterization tests before refactoring"Quality Engineer and Code Reviewer
Modernize"Plan a strangler migration"Solution Architect and Compliance Engineer
Preview"Run and smoke-test the app"Host-native execution with project checks
Branch Finish"Verify this branch before merge"Branch-scoped quality and review workflow
Retro"Analyze what this Cycle taught us"Evidence-driven retrospective

Focused output is not automatically SPQ completion evidence. When a focused operation is part of a governed Work Unit, it must use the kernel-selected dispatch and write the required receipt.

Work Unit assistance

A request containing a stable Work Unit, story, or ticket identifier can route to focused assistance:

  • Project Owner refines outcome and acceptance expectations.
  • Software Engineer implements the bounded unit.
  • Quality Engineer designs or executes proof.
  • Code Reviewer performs read-only adversarial review.

On an active SPQ Cycle, the kernel remains authoritative. Mentioning WU-42 does not authorize an arbitrary role or transition.

Runtime supervision is not a mode

Runtime selection and attempt supervision happen below role dispatch. Commands such as synaptory runtime status inspect an authorized attempt; they do not select the next delivery action or advance state.

The Control Plane Attempts page (/attempts) likewise observes attempts and sends governed directives without becoming another scheduler.

Legacy modes

Scrum Build/Sprint and Kanban ticket flow remain available for existing projects during planned retirement. They are not the recommended starting point, and Codex/Cursor warn that these paths are uncertified.

Use the Scrum and Kanban guides only for a project that is already on that lifecycle. For new work, use SPQ. For conversion, see Migrating to SPQ.

Routing priorities

When signals overlap, Synaptory prefers the narrowest safe interpretation:

  1. Current governed state and exact Work Unit identity.
  2. Explicit diagnostic or focused-operation intent.
  3. Configured lifecycle continuation.
  4. New SPQ outcome when build_mode: spq is explicit.
  5. Legacy compatibility routing only for an existing legacy project or omitted mode.

Ambiguity that would materially change scope or lifecycle must be surfaced to the user rather than guessed.

SPQ Concepts · 12

Delivery Roles and Runtime Profiles

Synaptory v1 dispatches nine delivery roles. For runtime selection it projects each bounded role dispatch onto a stage profile and one of four capability profiles. The role remains the dispatch and receipt identity; the profile overlay lets the runtime selector choose an eligible adapter.

Neither a role nor a profile can bypass the execution envelope, receipt validator, advance kernel, or a human gate.


Runtime profile vocabulary

Capability profiles are routing and skill-composition labels:

Capability profileTypical work
analystInvestigate, compare, challenge, and explain
plannerFrame scope, architecture, criteria, and readiness
producerModify governed artifacts and run producing checks
proverReplay checks, review independently, and return findings or verdicts

Stage profiles describe where obligations sit:

admitting, analysing, planning, producing, verifying, releasing, and operating.

Capability profiles grant no authority. Filesystem, network, tool, credential, budget, and lifecycle authority come from the dispatch envelope and project policy.

Role projection

The current bounded dispatch projection is:

CodeDelivery roleStage profileCapability profile
POProject Ownerplanningplanner
SASolution Architectplanningplanner
SESoftware Engineerproducingproducer
QEQuality Engineerverifyingprover
CRCode Reviewerverifyingprover
CECompliance Engineerverifyingprover
PEPlatform Engineerproducingproducer
TWTechnical Writerproducingproducer
RAResearch Advisoranalysinganalyst

Project Owner was previously called Product Manager. Older data may retain the historical value; new dispatches and receipts use project-owner.

Why roles remain separate

  • Software Engineer produces the candidate; Quality Engineer proves behavior.
  • Code Reviewer stays clean-context, diff-focused, and read-only.
  • Compliance Engineer owns security and compliance findings rather than

folding them into general code review.

  • Project Owner frames the outcome; Solution Architect owns architecture and

technical contracts.

  • Platform Engineer owns infrastructure and operational readiness.
  • Technical Writer traces release documentation to delivered artifacts.
  • Research Advisor supplies bounded research without owning lifecycle state.

Conditional work may be skipped when its trigger is absent, but the orchestrator cannot substitute a different role for a kernel-selected action.

SPQ activity map

SPQ state/eventTypical role activity
DiscoveryPO, SA, and RA frame the outcome, the constraints, the source region, and the proposed baseline.
CommitPlanning work fixes ready scope and acceptance expectations before production.
Cycle ExecutionSE produces; QE and CR verify; conditional CE, PE, or other work runs when selected.
CheckpointThe barrier proves the whole admitted set and integrates it to the shared trunk; a named human records the close.
CheckpointTW records the integrated increment; a human chooses the next direction.
AcceptanceQE, CE, PE, TW, and CR assemble the release evidence package.

No role, host, or runtime can approve baseline, Commit scope, Sync entry/clearance, Checkpoint direction, or release completion for the human.

Host execution

HostCurrent packagingImportant behavior
Claude CodePlugin skills, agents, and native hooksFull host-native adapter; protected bodies are Control Plane delivered.
CodexNine managed profiles installed by dry-run-first project bootstrapFull standard non-regulated SPQ; four total live threads including parent.
CursorComposed skills/subagents, rules, hooks, and MCPOne delegation level; headless work requires MCP preflight.

Host packaging does not change the selected role or receipt contract.

Dispatch envelope

A governed attempt receives only the context needed for its selected action:

  • Cycle, declaration and Work Unit identity;
  • selected role plus stage and capability profile overlay;
  • allowed paths, tools, network, and credentials;
  • required artifacts, checks, and Definition of Done expectations;
  • budget, expiry, and runtime profile;
  • exact receipt path; and
  • unique attempt and dispatch identity.

Missing scope is not permission to infer a larger task. The runtime must refuse or return an actionable failure.

Receipt evidence

Receipts identify the role and record artifacts, findings, executed verification commands, Definition of Done signals, runtime attribution, and completion metadata. The validator replays supported commands and rejects a receipt that is missing, stale, failed, or bound to another dispatch.

Human decisions are recorded through the governed lifecycle operation, not invented inside an agent receipt.

SPQ Concepts · 13

Engagement Modes

Engagement mode controls how many intermediate decisions Synaptory surfaces between mandatory gates. It does not change canonical state, evidence requirements, runtime authority, or who may approve a human decision.

Structured

structured is the default. Synaptory continues through authorized, bounded operations when the next action and evidence contract are unambiguous.

Use it when:

  • the Cycle baseline and Work Units are clear;
  • verification commands and evidence requirements are established; and
  • you want fewer prompts between mandatory gates.

Structured still stops for baseline approval, the admitted set at Commit, any cut, the Checkpoint close, and Acceptance / completion. Sync is not among them: it records a dependency having cleared and authorizes nothing.

Interactive

interactive surfaces more intermediate choices—for example architecture tradeoffs, risk decisions, scope clarification, or recovery options—before dispatch continues.

Use it when:

  • Discovery is ambiguous;
  • the work has material security, compliance, or product tradeoffs;
  • a recovery choice could change scope or evidence; or
  • a stakeholder wants a more explicit decision trail.

Interactive mode does not turn a human into the verifier and does not let an invalid receipt advance.

Configuration

engagement_mode: "structured"   # structured | interactive

Compatibility aliases may still be accepted, but new configuration should use the canonical values.

Host and model behavior

The installed host and certified adapter policy determine available models, tools, and execution limits. Engagement mode is not a model selector and is not a promise about cost. A host may implement extra decision prompts differently while preserving the same governance boundaries.

Practical use

A common pattern is:

  1. use Interactive during Discovery to resolve outcome and risk;
  2. use Structured for well-bounded Cycle Execution;
  3. return to Interactive when recovery could change scope or at Acceptance/Release preparation.

Changing engagement mode never retroactively approves a gate or repairs missing evidence.

SPQ Concepts · 14

Enforcement and Safety Nets

Synaptory does not treat lifecycle and quality requirements as suggestions to a model. Host adapters, the shared advance kernel, receipt validation, Sync barriers, and human gates enforce them.

Fail-closed principle

The kernel stops when it encounters:

  • an illegal lifecycle transition;
  • a missing, stale, invalid, or wrongly bound receipt;
  • a failed verification command;
  • an unresolved dependency or stale manifest;
  • a non-green Sync or release-readiness verdict;
  • an ineligible runtime profile;
  • a tracker or Control Plane handoff error required by policy; or
  • a human gate with no explicit decision.

structured and interactive engagement modes do not turn these failures into optional warnings. They change decision visibility, not safety invariants.

State authority

At every boundary the host asks the shared lifecycle authority for the next action. The returned action can authorize an exact role dispatch, an exact transition, a ceremony, recovery, or a stop reason.

The orchestrator must not:

  • select a different Work Unit or role;
  • advance using chat memory;
  • write pipeline state directly;
  • call a host's private lifecycle module as a mutation shortcut; or
  • continue after an MCP, adapter, tracker, or validation error.

Dispatch binding

Before work starts, Synaptory creates an immutable dispatch identity and exact execution envelope. The envelope limits scope and names the required receipt.

A valid-looking receipt from an earlier or concurrent dispatch is rejected. A retry gets a new dispatch identity; failed evidence is preserved or archived according to the host adapter rather than silently reused.

Receipt protocol

A receipt is a verifiable claim from one selected delivery role. Its contract includes:

  • stable Work Unit, role, attempt, and dispatch identity;
  • Cycle, stage/capability overlay, and adapter identity when the

execution envelope provides them;

  • honest host, runtime, and model attribution;
  • artifacts and findings appropriate to the role;
  • executed verification commands and their results;
  • Definition of Done signals; and
  • completion timestamps fresh for the current stage.

Conceptual example:

{
  "task": "Verify WU-42 against its authored acceptance cases",
  "agent": "quality-engineer",
  "backend": "codex",
  "model": "codex-runtime-reported-id",
  "attempt_id": "att_01J6EXAMPLE",
  "dispatch_id": "1a2b3c4d5e6f708192a3b4c5d6e7f809",
  "adapter_profile_id": "codex-local-v1",
  "placement": "local",
  "stage_profile": "verifying",
  "capability_profile": "prover",
  "verification_commands": [
    {
      "command": "npm test -- --runInBand",
      "exit_code": 0,
      "summary": "Acceptance suite passed"
    }
  ],
  "story_dod": {
    "tests_pass": true,
    "build_succeeds": true,
    "no_critical_findings": true,
    "code_reviewed": true,
    "coverage_no_decrease": true
  }
}

When a host cannot expose an exact model identifier, the receipt records an honest unattributed value rather than guessing.

Validation

Validation checks:

  1. Schema and required fields.
  2. Work Unit, selected role, attempt, and dispatch binding, plus any runtime

identity copied from the execution envelope.

  1. Receipt freshness relative to stage entry.
  2. Artifact and allowed-path expectations.
  3. Verification object shape and actual result.
  4. Role-specific findings, verification results, and Definition of Done.
  5. Durable, minimized Control Plane delivery when required.

Local schema validity alone is not enough when the configured policy requires the authenticated projection to reach the Control Plane or durable outbox.

Work Unit pipeline

The current compatibility state path is:

queued → in progress (SE) → testing (QE) → reviewing (CR) → done
                                  ↘ recovery / blocked ↗

At the governance layer this is producing followed by isolated proving and a clean-context review. The next transition becomes legal only after the current profile-bound receipt validates. Conditional skills/checks can insert authorized activities without changing this rule.

Evidence quality

Deterministic verification commands are re-run where the host can replay them. Review and compliance findings remain structured, role-scoped evidence. Human decisions are recorded by the lifecycle operation with the real principal and exact candidate context; an agent must not manufacture them.

Missing evidence does not become a pass. The current gate remains blocked or incomplete until the required receipt and checks validate.

Sync enforcement

A Work Unit marked done in one clone is not proof that the Cycle integrates. Sync separately requires:

  • terminal admitted Work Units;
  • a generated barrier verdict, never a hand-authored one;
  • exact sealed heads;
  • verified dependency closure;
  • regression, journey, and digest evidence configured by policy;
  • human confirmation before integration; and
  • an explicit human clear on a green verdict.

Readiness and barrier records cannot be replaced by hand-authored JSON.

Acceptance enforcement

Acceptance requires valid QE, CE, PE, TW, and CR release receipts. Complete is refused for failed tests, critical security findings, non-approved Code Review, missing release documentation, invalid receipts, or any closed Cycle without a green Sync verdict.

A repeated Acceptance compiles its own package but takes no shortcut around child evidence.

Runtime attempt enforcement

Runtime federation does not move lifecycle authority into an adapter. The selector chooses only a profile inside the configured authority ceiling. The bridge then executes the immutable envelope and records progress, directives, status, artifacts, and receipt against one attempt identity.

Unavailable capabilities cause an explained denial or governed reroute, never silent degradation. Cancellation stops the attempt; it does not advance the Work Unit.

Data minimization

The authenticated Control Plane projection is intentionally smaller than the local receipt. It can contain identifiers, host/model/token attribution, timestamps, Cycle metadata, and Definition of Done booleans. Prompts, transcripts, artifact contents and paths, commands, summaries, and findings remain local unless a separate authorized feature explicitly says otherwise.

Host adapters

The enforcement mechanism differs by host:

  • Claude Code uses its full hook graph plus shared runtime operations.
  • Codex uses authenticated MCP mutation gates, managed profiles, supported

hooks, and explicit bootstrap/readiness checks.

  • Cursor uses MCP advancement, host hooks, composed agents/rules, and mandatory

headless preflight where the plugin path is not automatically loaded.

Differences in hook coverage do not change the shared receipt and advancement contract.

Cross-session persistence

Lifecycle state, manifests, receipts, readiness records, attempts, and context packages survive chat sessions. On resume, the host re-reads repository state and asks the kernel for the current action.

Chat transcripts are not delivery state. A new session, host restart, context compaction, or runtime process restart must not create permission to repeat or skip work.

SPQ Concepts · 15

What's next: Synaptory Platform

This guide describes the product in this repository (Synaptory 1.x). The next system is Synaptory Platform, specified in the sibling synaptory-spec repository (local checkout: ../synaptory-spec). This page is a pointer. It creates no requirement.

The rest of this guide is 1.x. Synaptory Platform is a greenfield rebuild, not an upgrade of this install.

Authority. synaptory-spec spec/ is the only authority for platform requirements. Start with presentations/proposal-brief.html if you are new. Catalog rows (SP-*, SC-*) oblige; this page does not restate them. Decision state lives in that repository's decision register. If this page and the spec disagree, the spec wins. Decoder for 1.x UI labels: the glossary.

A naming collision. In this repository, “v1” means the shipping predecessor. In synaptory-spec, “v1” means the platform's first release (kernel + rebuilt Code slice). This page does not call the next system “v2.0.”


This product keeps shipping

This repository is the predecessor product. It stays revenue-bearing while the platform is built.

The lifecycle policy is freeze at G3 · migrate by consent · retire when empty (SPD-150, ADR-112):

  • Until platform gate G3 (one complete customer-zero Code workflow), work

here continues normally.

  • From the freeze: security fixes and delivery-blocking fixes continue; new

capability lands on the platform.

  • A customer moves when the platform's minimum sellable subset covers their

usage. Migration is per customer, by consent, with export from here and fresh intake there.

  • This product retires when no customer remains on it.

Nothing on this page changes how you use the 1.x plugin, CLI, or Control Plane today.


What Synaptory Platform is

Synaptory Platform is H3T's multi-tenant AI-enablement and delivery platform. It turns an authorized request into a governed, owned deliverable through reusable workflows that combine deterministic code, AI agents, and human judgment — while preserving each business's method, risk appetite, commercial commitments, data boundaries, and client relationships.

Work follows one seven-stage path:

Request → Analyze → Plan → Build → Prove → Release → Operate

Disciplines plug in as slices through one public contract. Synaptory Code (software delivery) is the first slice and the engine that builds the platform itself. Synaptory Consult and Synaptory GTM follow.

The canonical hierarchy is Tenant → Client → Project → Job. The contracting customer is the tenant; the tenant's own customer is the nested client. That second boundary is load-bearing.

The platform sits above AI runtimes rather than competing with them. Coding agents answer can an agent complete this task? Synaptory answers should this work happen, under whose authority, using whose data, against which commercial commitment — and what proves the accepted result was delivered?

Implementation is four repositories, consumed as pinned published artifacts — never as a copy of this tree:

RepositoryWhat it builds
synaptory-specThe specification and its validators
synaptory-infraShared foundation
synaptory-foundationControl-plane implementation
synaptory-factoryThe Code slice (Synaptory Code)

This repository is not one of those four. It is the predecessor they replace.

Progress on the platform is gated on evidence (G0–G6), not on a calendar copied into this guide. Read document 11 in the spec for gates and increments.


What changes for a 1.x user

Greenfield describes how the platform is built. It does not mean the delivery business restarts from zero. Clients, codebases, and future work carry over as fresh Requests. Identities, sessions, receipts, projects, hook state, and this control plane do not.

1.x todayWhere it lands on the platform
H3Tech, the delivery organizationFirst Tenant
Existing clientsClients under that tenant — a hard isolation boundary
Their codebases and productsProjects under the owning client
In-flight and future workFresh Requests. Prior 1.x artifacts may be referenced as source attachments; they are re-evaluated, not inherited

Standing separation (see spec document 11 §5 and ADR-112; do not treat this list as catalog text):

  • The platform deploys clean: no runtime, identity, data, or evidence

dependency on this product.

  • Predecessor identities cannot authenticate there.
  • Predecessor receipts satisfy no platform criterion.
  • The nine 1.x agent names survive only as documented aliases for user

education (SC-MTH-005).


Labels you already see in this Control Plane

The 1.x UI adopted some next-system nouns early so a later cut-over would not be a label rewrite. Treat them as labels on 1.x objects, not as a migration path. The objects behind them stay 1.x and will be rebuilt, not carried over.

Where you see itWhat it means todayOn the platform
Label “Spec” instead of “Story”Renaming only; same 1.x tableA different noun: H3T-owned reusable source definition. Not this row.
“Project Owner” instead of “Product Manager”Agent rename complete in 1.xThe nine agent names are education aliases only
“Delivery Owner” for the human roleUI-only termA defined authority on the platform, not this UI string
Overview “Gate Queue” with four gatesThree are placeholders; only Evidence/DoD has a wired backend signalRisk-scored gates at every stage boundary, not this fixed list
Cost panel “11 stages”Aggregated from existing receipt fieldsPer-stage receipts on the platform spine
Quality panel “Evidence/DoD”Same as 1.x DoD evaluationProve: independent verification of the exact candidate

What does not carry over

1.x mechanismPlatform position
Entra groups + SYNAPTORY1 sessions + project_membersNew identity realm. Predecessor identities cannot authenticate.
This CLI command surfaceGoverned clients exist on the platform; this command set is not compatible.
Build-time control-plane URL stampingA 1.x deployment detail. Platform topology is specified elsewhere.
The 9-agent crew and its orchestrationReplaced in the Code slice; names are aliases for education only.
.synaptory.yaml, hooks, and the 1.x state machinesSuperseded. Controls sit outside runtime prompts, plugins, and hooks.
Scrum / Kanban as alternative operating modelsOne seven-stage spine. Cycle / Commit / Checkpoint / Sync are Code method vocabulary, not a second lifecycle.

Ideas that recur are rebuilt, not migrated: watermarked method delivery, signed hash-chained receipts, a durable outbox, signed policy bundles. Each starts a new registry. 1.x receipts may enter only as untrusted attachments with provenance.


Leftover v2 / v3 labels in this repo

Those strings are not the platform version:

  • Runtime identifiers. V3_STAGES in the API analytics router and

VALID_V3_STAGES in the receipt validator still carry an old name. They are 1.x module identifiers.

  • On-disk state layout. The plugin state file has a v2 (single-spec) and

v3 (multi-spec) layout version. Unrelated to the product version.

  • Teamwork REST API v3. A tracker adapter detail.

Where to read the real spec


What's next?

Guides · 16

SPQ Delivery

SPQ is the primary Synaptory delivery lifecycle. Use it for new projects, continuing product work, and maintenance that needs governed scope, evidence, and integration—not only for large multi-team programs.

DISCOVERY → CYCLE → ACCEPTANCE → COMPLETE
              ↑         |
              +---------+   a non-final go-live returns to CYCLE

Four stages. Commit, Sync and Checkpoint are recorded events, not stages and not gates: Commit seals the admitted set and opens the Cycle, Sync records a dependency having cleared, and Checkpoint records the demonstration, the barrier verdict and the integrated trunk revision.

Before the first Cycle

Confirm:

  • the host plugin and matching synaptory CLI are installed;
  • synaptory whoami succeeds;
  • .synaptory.yaml names the correct project_id;
  • build_mode: spq is explicit;
  • the source region names durable code areas and does not overlap another live Cycle's;
  • trunk_ref names the one shared branch, and the regression proof passes on it; and
  • /synaptory doctor or $synaptory readiness reports no blocking failure.

See Getting Started and the SPQ Setup Runbook.

Discovery

Start with the desired outcome:

Use SPQ to deliver account recovery with auditable security events. Run
Discovery, declare the source region, and show me the proposed baseline.

Discovery frames:

  • the user and business outcome;
  • system constraints and risk;
  • its declared path scope;
  • proposed Work Units and dependency edges;
  • verification and shared-component expectations; and
  • whether any other Cycle is live, and whether its region overlaps.

Review the baseline. Approval must be explicit and attributed to the real human principal. If the baseline is incomplete, request changes rather than approving with an informal caveat.

Commit

Commit admits the approved Work Units and opens the Cycle. Before confirming, review:

  • every Work Unit has useful acceptance expectations;
  • its path_scope names the paths it will actually change, and no wider;
  • dependencies name verifiable conditions;
  • no work is admitted merely because an agent already started it; and
  • the Cycle scope is small enough to integrate coherently.

The resulting manifest is sealed. Changing scope later is a governed operation, not a direct JSON edit.

Cycle Execution

Ask Synaptory to continue the Cycle. At every boundary the kernel selects one of these outcomes:

  • dispatch the exact next role for one Work Unit;
  • validate an existing fresh receipt and advance;
  • recover a blocked Work Unit with an authorized role/runtime contract;
  • run a lifecycle ceremony;
  • stop at a human gate; or
  • report a terminal or fail-closed reason.

The current compatibility state path names Software Engineer, Quality Engineer, and Code Reviewer. Its governance meaning is producing → isolated proving → clean-context review → Definition of Done. Do not skip a selected action because the change looks small.

Receipts

Each attempt receives an exact execution envelope containing the Work Unit, allowed paths, expected artifacts, verification commands, receipt path, and dispatch identity. A receipt is accepted only when it:

  • uses the selected role and honest host/runtime attribution;
  • binds to the active dispatch;
  • records actually executed verification commands and exit codes;
  • satisfies the role-specific verification and Definition of Done contract; and
  • is fresh for the current stage.

Supported verification commands are replayed, and structured review or compliance findings stay role-scoped. Human judgments are recorded through the governed lifecycle operation. A missing or invalid receipt stops advancement. Repair the evidence or repeat the governed dispatch; never copy an older receipt into place.

Dependencies

Within one Cycle the declaration refuses an edge to a unit the Cycle did not admit, and the refusal names the two legal routes: co-admit the pair, or consume a published version of the upstream at this Cycle's own Commit. Work that cannot be ordered cannot be split across Cycles.

Across concurrent Cycles the producer publishes a verifiable dependency event and the consumer refreshes its ledger before the kernel re-evaluates dispatch. Prefer the narrowest condition that makes the consumer safe -- wait for a verified contract, not for the producer's whole Cycle. When the wait clears, a Sync event records it. Nothing waits for the event itself.

An event that cannot be verified is a claim, not evidence. The default policy keeps it blocked.

The barrier, at Checkpoint

When every admitted Work Unit is terminal -- done, or explicitly cut -- the Cycle closes through its barrier. The barrier is all-or-nothing over the admitted set minus the recorded cuts (C-04), and it integrates the result to the shared trunk (C-05). There is no partial admission and no per-unit promotion.

Its criteria are published at Commit, from one constant, so the Cycle sizes against them rather than discovering them at close:

admitted_set_closed   path_scopes_disjoint   shared_paths_owned
criteria_all_returned   acceptance_criteria_met   regression_green
trunk_integrated

criteria_all_returned is not decoration. Without it, evaluated nothing and evaluated everything and passed are the same verdict.

A red barrier names the failed criterion. Repair the named evidence and re-evaluate -- and if the Cycle cannot meet its barrier, cut the work that is not going to make it rather than closing on a weaker verdict. A cut needs an explicit reason, returns the unit to the backlog, and never moves the approved baseline.

If another Cycle moves the trunk while this one is ready, the candidate is rebuilt and re-verified. A green result against a trunk revision that has moved is green about something else.

Checkpoint

Checkpoint captures the integrated increment, Technical Writer evidence, Cycle metrics, and follow-up decisions. Choose one:

  • Continue: return to Commit with the next approved scope.
  • Accept: move the accumulated release candidate to Acceptance.

Checkpoint is also the natural place to stop a working session. Repository state and receipts—not the chat transcript—allow the next session to resume.

Acceptance

Acceptance dispatches five release activities:

  1. Quality Engineer—full release verification.
  2. Compliance Engineer—security and compliance evidence.
  3. Platform Engineer—deployment and operational readiness.
  4. Technical Writer—release documentation and runbooks.
  5. Code Reviewer—final read-only release review.

Hosts may execute these sequentially even when the activities are logically independent. In particular, the certified Codex path has a four-thread total limit including the parent and therefore runs all five sequentially.

Complete remains blocked until every required receipt is valid, every closed Cycle recorded a green barrier verdict naming its integrated trunk revision, and the human explicitly accepts the release. Only the final Acceptance closes the engagement -- an earlier one produces its own package and returns delivery to another Cycle.

Runtime-supervised attempts

When an SPQ runtimes: policy is enabled, the selected role projects to a capability profile that maps to an eligible adapter profile. The lifecycle authority does not move into the runtime bridge: attempts execute envelopes and return evidence; only the advance kernel changes delivery state.

Use synaptory runtime status --attempt <id> or the Control Plane Attempts page (/attempts) for long-running attempts. Cancellation stops the attempt but does not mark its Work Unit complete.

Common stop reasons

ReasonResponse
Missing or stale receiptRe-run the authorized role dispatch and produce a fresh dispatch-bound receipt.
Declaration supersededRe-hydrate through the governed host action before dispatching. A board on a superseded revision is executing an easier admitted set.
scope_collisionAnother Work Unit holds a live dispatch on an intersecting declared path scope. Finish or release it; intersecting work runs sequentially.
Dependency ledger staleRefresh once; if still unresolved, coordinate with the named producer.
Unverified dependencyReplace the claim with a verifiable condition or evidence.
Barrier regression failedFix the integrated result, then re-evaluate the whole set. A partial fix does not clear an all-or-nothing barrier.
Runtime profile ineligibleUse runtimes doctor and runtime explain; do not silently substitute.
Human gatePresent the evidence and wait for the real user's decision.
Guides · 17

SPQ Setup Runbook

Use this runbook to prepare the repository, the source region, the trunk and the tracker before the first SPQ Commit. Lifecycle mutations go through the installed host adapter; the commands below are normal Git and diagnostic operations only.

This runbook changed shape at SPD-194. The previous version had you provision one clone per Workstream plus an integration clone, commit three Sync proof scripts, and track a readiness record per lane. The Workstream and the Coordination Cycle are retired, the barrier moved from Sync to Checkpoint where it integrates to the shared trunk, and sync-regression.sh / shared-digest.sh are deleted. One clone is the normal case. See ADR-035.

1. Confirm the host

Complete Getting Started and run the host's Doctor flow. The project must have:

  • a matching host plugin and synaptory CLI;
  • an authenticated user and a valid project_id;
  • explicit build_mode: spq;
  • a host certified for the intended project class; and
  • no active legacy dispatch that would overlap initialization.

Codex standard SPQ refuses regulated projects. Cursor regulated use requires the Enterprise conditions in Hosts and Runtimes.

2. Choose the source region

This is the input codebase detection cannot decide safely, and it is now the only topology decision.

A source region is the set of repository-relative paths a Cycle may address (C-08). It is declared per Cycle and sealed with it.

DecisionWhy it matters
Region pathsTwo Cycles may run concurrently only if their regions do not overlap. Overlapping regions are refused at declaration
Trunk refThe one shared branch the Cycle integrates into at Checkpoint. A Cycle that closes having integrated nothing anyone else can see has not closed
RepositoryExactly one per Cycle (C-10). A cross-repository declaration is refused, and the refusal names the published-package route

Name product or code areas, not people, teams or runtimes. There is no shared owner to nominate at the project level and no integration seat: a shared path -- one that more than a single Work Unit would touch -- names exactly one owning Work Unit in the declaration, decided per Cycle.

build_mode: "spq"

spq:
  source_region:
    - "api/"
    - "web/"
  trunk_ref: "refs/heads/dev"

There is no parallelism switch and no isolation mode. Concurrency is a consequence of the path_scope each Work Unit declares:

  • intersecting scopes are refused at Commit unless each declares a distinct

execution_order -- they then run sequentially in one Cycle;

  • a concurrent dispatch onto an intersecting scope is refused with

scope_collision;

  • disjoint work proceeds with nothing to enable.

See Configuration for the full key list.

3. Prepare the regression proof

The barrier publishes its criteria at Commit, from one constant, and regression_green is one of them. Commit the script that proves it and run it manually once on the trunk before opening the first Cycle -- a proof command that has never succeeded outside the barrier is setup debt, not evidence.

The three-script Sync arrangement is gone with the Sync barrier. There is no shared-digest step: shared-path ownership is declared per Cycle and checked against the declaration rather than recomputed from a digest on two sides.

4. One clone is the normal case

Open Discovery and Commit in your working clone. Commit allocates the stable cycle_id and seals the declaration; do not invent matching branch names independently.

A second clone is for a second concurrent Cycle with a disjoint source region, not for a lane inside one Cycle. In that clone, ask Synaptory to hydrate the sealed Cycle. Hydration verifies the seal before adopting anything and projects the whole admitted set -- there is no slice of the board to take.

SYNAPTORY_ACTIVE_SPEC is a legacy Scrum/Kanban Multi-Spec variable and an SPQ project ignores it.

5. Configure committed SPQ paths

Two things must be visible across clones: the sealed declaration and the cut record. Other local runtime state stays ignored.

.synaptory/*
!.synaptory/cycles/

The first rule must use .synaptory/*, not .synaptory/. Git cannot re-include a child of a directory that was excluded as a whole.

.synaptory/cycles/<cycle-id>/ holds manifest.json (the sealed declaration), cuts.json (the recorded cuts) and events/ (verified dependency events). The cut record is committed for a specific reason: the barrier's subject is the admitted set minus recorded cuts, and the barrier can run in a clone that did not make the cut.

.synaptory/sync/ is gone, and so is the boundary guard that protected it.

Before Commit, verify the paths can be tracked:

git check-ignore -v .synaptory/cycles/example.json

open_cycle refuses to seal a Cycle whose committed transport is gitignored, so a misconfigured .gitignore fails at Commit rather than at the barrier. Remove the example file after the diagnostic.

6. Configure the tracker

The local, GitHub, Jira, Teamwork and Linear adapters can all serve SPQ. The tracker reflects Work Units and Cycle association; it does not become lifecycle authority.

For Linear:

  • enable Cycles on the team;
  • prefer manage_cycles: false so Synaptory binds to the team's existing cadence;
  • create an Awaiting Acceptance state when the workflow needs it.

If two concurrent Cycles run at different cadences, do not force their tracker Cycle numbers to match. Cycle sequence numbers are per-project and collide by design -- anything crossing a Cycle boundary uses the stable cycle_id and the declaration_hash.

7. Dependencies, and when Sync appears

A depends_on edge names a unit and a condition. Within one Cycle the declaration refuses an edge to a unit the Cycle did not admit, and the refusal names the two legal routes: co-admit the pair to one Cycle, or consume a published version of the upstream at this Cycle's own Commit.

Across concurrent Cycles, a consumer waits on the dependency fact, not on a ceremony. When it clears, a Sync event records which Cycle waited on what, from where, and how it resolved. Sync authorizes nothing and blocks nothing -- there is no Sync entry to confirm and no Sync to clear.

An unverified claim never unblocks downstream work, and there is no toggle. That has a real cost -- a plain-string depends_on becomes usable only for board state, and the author must name a condition the consumer can check -- and it is the only way "an upstream event safely unblocks downstream work" is true rather than aspirational. A spq.sync.accept_unverified_events key was documented for a while and never read by anything; it is gone rather than wired, because wiring it would have added a documented route to weaken an evidence gate.

8. Open a small first Cycle

Ask Synaptory to run Discovery and present the baseline. Baseline approval needs a measured calibration sample, not a sha and a boolean. After approval, open a small Cycle that exercises the regression proof without carrying release-critical scope.

During the pilot, verify:

  • Work Unit receipts bind to the active dispatch;
  • receipts land under spq/cycles/<cycle-id>/receipts, never a spec slot;
  • two disjoint Work Units dispatch concurrently with nothing enabled;
  • two intersecting ones are refused at Commit without an execution_order, and

the second is refused at dispatch with scope_collision when they have one;

  • a deliberately failing proof blocks the whole barrier, not part of it;
  • a cut records its reason and a backlog return, and does not move the baseline;
  • the green path integrates to the trunk, reaches Checkpoint, and resumes in a

new session.

9. Add runtime selection separately

Do not combine lifecycle cutover and runtime federation unless both changes have independent acceptance evidence. First prove native-host SPQ. Then:

synaptory runtimes list
synaptory runtimes doctor

Add an explicit runtimes: policy only after the allowed profiles, placements, capability requirements and fallback behaviour have been reviewed.

Setup completion checklist

  • [ ] Host Doctor is green for SPQ.
  • [ ] build_mode: spq is explicit.
  • [ ] The source region names durable code areas and does not overlap another live Cycle's.
  • [ ] trunk_ref names the one shared branch, and it exists.
  • [ ] The regression proof is committed and passes manually on the trunk.
  • [ ] .synaptory/cycles/ is not hidden by .gitignore.
  • [ ] Tracker mappings preserve native SPQ identity.
  • [ ] The first baseline is human-approved, with a measured calibration sample.
  • [ ] The first small Cycle integrates to the trunk and reaches Checkpoint.
Guides · 18

Resuming SPQ Pipelines

SPQ resumes from repository-owned state and evidence, not from the previous chat transcript. A new session should ask the kernel for the current action before dispatching or changing anything.

What persists

Depending on the active stage, the project can persist:

  • lifecycle and Work Unit state;
  • the sealed Cycle declaration and the recorded cuts;
  • native Cycle identity;
  • dispatch-bound receipts;
  • readiness records, dependency events, and Sync verdicts;
  • context packages and Checkpoint reports;
  • runtime attempt records and durable progress; and
  • tracker identifiers and status projections.

The exact paths are implementation details of the governed runtime. Never reconstruct them from memory or treat last-session.md as more authoritative than current state.

Normal resume

  1. Open the clone the Cycle was opened or hydrated in.
  2. Confirm there is no still-running writer for the same governed dispatch.
  3. Verify CLI identity with synaptory whoami.
  4. Invoke /synaptory status on Claude Code/Cursor or $synaptory with a status request on Codex.
  5. Review the Cycle, Work Unit, stage, receipt, dependency and human-gate summary.
  6. Ask Synaptory to continue and follow the exact returned action.

Do not begin by asking a role to "finish what we were doing." That prompt can repeat already-receipted work or skip a gate.

Resume at a human gate

Human gates remain pending across sessions. On resume, Synaptory should present the evidence and ask for the missing decision again.

GateConfirm before approval
BaselineDiscovery output, scope and non-scope, constraints, source region, measured calibration sample, proof expectations
CutAn explicit reason, a backlog return, and the baseline unchanged
Clear SyncHuman merge complete and barrier verdict green
AcceptanceAll release receipts valid and included scope correct
AcceptanceThe evidence package is complete for the trunk revision it pinned

A user identity from an old transcript is not approval. The current real principal must make the decision.

Resume a runtime attempt

An authorized attempt can continue independently of the host chat. Inspect it with:

synaptory runtime status --attempt <id>
synaptory runtime explain --attempt <id>

The Control Plane Attempts page (/attempts) shows the same attempt timeline when its projection is available.

  • If the attempt is still running, do not dispatch the same stage again.
  • If it completed, let the host validate the exact receipt and ask the kernel for the next action.
  • If it failed, use the returned recovery/redispatch contract.
  • If it was cancelled, remember that cancellation does not complete or advance the Work Unit.

Resume after context compaction

Host adapters re-anchor critical state around compaction where Synaptory supports it. Even so, the safe sequence is unchanged: read status, ask for the current action, validate any existing receipt, then continue.

Do not rely on the compacted summary for dispatch identity, allowed paths, or human approval.

Resume on another host

Cross-host handoff is not a product feature. A different host can read the same repository only under normal single-writer discipline:

  1. Stop or finish the active dispatch on the original host.
  2. Persist and validate its receipt or preserve the fail-closed status.
  3. Commit/push only the repository evidence that policy requires.
  4. Open the correct clone on the new host and run its readiness/Doctor flow.
  5. Ask the kernel for the current action.

Do not copy chat history, hand-author a transfer receipt, or let both hosts mutate one active stage concurrently.

Resume after plugin or CLI update

Reload or restart the host after a plugin update. Confirm the host plugin and CLI versions are compatible, then run Doctor before continuing a governed stage.

Codex profile/bootstrap changes require a new task for discovery. Cursor IDE requires Reload Window. Cursor headless requires the MCP preflight again.

An update does not permit state migration to happen implicitly. Follow any reported migration plan and re-run Doctor.

Superseded declaration or unresolved Cycle identity

If status reports a superseded declaration or no resolvable Cycle identity, ask Synaptory to hydrate the current sealed Cycle. Hydration verifies the seal before adopting anything and projects the whole admitted set -- there is no slice of the board to take. Do not copy a pin from another clone or substitute a branch name.

If the project still uses legacy Multi-Spec SPQ state, use the migration path in Migrating to SPQ.

Missing or invalid receipt

Do not fabricate a receipt from source changes. Inspect the reason:

  • missing receipt: repeat the authorized dispatch;
  • wrong dispatch: archive/preserve it and create a fresh dispatch;
  • failed verification: fix the bounded work and rerun proof;
  • stale timestamp: produce evidence after the current stage entry;
  • invalid model/host attribution: record the honest runtime result; and
  • Control Plane delivery pending: allow the durable outbox/handoff policy to complete.

State must not advance until validation succeeds.

Corrupt or unreadable state

Run Doctor and stop. Preserve the affected files for diagnosis. Do not delete or regenerate governed state merely to get a green initialization.

Report:

  • host and plugin version;
  • CLI version and identity status;
  • the project and the clone the Cycle was hydrated in;
  • current branch and clean/dirty status;
  • Doctor reason code; and
  • the last known valid Cycle/dispatch identity without pasting secrets or full transcripts.

Use an operator-reviewed recovery plan for material state repair.

Good stopping points

Prefer to stop:

  • after a valid Work Unit transition;
  • while explicitly waiting for a human gate;
  • after a green Checkpoint; or
  • after an attempt has a stable terminal status.

Avoid stopping halfway through an unrecorded human merge or while two clones can both believe they own the same stage.

Legacy pipelines

Existing Scrum/Kanban state can still resume through the shared kernel during the support period, with host certification warnings where applicable. Do not use legacy internal Python commands as a general recovery interface. Plan an SPQ migration at a stable lifecycle boundary.

Guides · 19

Using the Control Plane

The Control Plane at https://synaptory.h3t.co/ provides project-scoped visibility into SPQ Cycles, Acceptances, runtime attempts, quality, cost, reliability, sessions, skills, and audit activity.

It complements repository-owned lifecycle state. It does not select the next role, mutate a Cycle merely because a page was opened, or replace Git evidence.

Sign in and scope

Open the Control Plane and sign in with the same organization identity used by the synaptory CLI. The root redirects administrators to /overview and other authenticated users to /home.

Visibility is enforced by global and per-project roles:

  • Global administrator: organization-wide operational and policy views.
  • Project administrator: project analytics and member administration for projects they administer.
  • Project member: permitted project views, with sensitive data scoped by policy.
  • No project role: identity, access-request, and permitted personal surfaces only.

Requests for a project the caller cannot see return a non-disclosing response.

Most delivery pages accept ?project=<slug>. The project picker carries that scope through sidebar navigation.

SPQ pages

Cycles — /cycles

Cycles lists repository-reported SPQ Cycle telemetry. The summary and detail views can show:

  • stable Cycle identity and project;
  • sealed manifest and admitted Work Units;
  • the declared source region;
  • closure difference between admitted and terminal scope;
  • the barrier verdict and the integrated trunk revision; and
  • links from runtime attempts bound to the Cycle.

Cycle identity is scope-defined, not a time-window metric. The page therefore does not pretend that "Cycles in the last seven days" is the lifecycle model.

Acceptances

/coordination-cycles is gone with the Coordination Cycle. Acceptance is repeatable and each one stands on its own, so the page reports Acceptances rather than a composed parent:

  • the Acceptance identity and the integrated trunk revision it pinned;
  • the Cycles whose work that revision contains;
  • the release-role evidence and which pieces are still outstanding;
  • whether this Acceptance was the final one -- derived from outstanding

commitments and a recorded handover, not from a flag; and

  • the named human who recorded the decision.

The page reports what was delivered to it. It does not dispatch into a Cycle and it is not a second lifecycle authority.

Attempts — /attempts

Attempts lists coordinated runtime attempts newest first. Local host-native dispatches may remain visible only in the host; an attempt appears here after it is coordinated through the Control Plane.

The attempt detail can show:

  • attempt, project, Cycle, Work Unit, role, and runtime-profile binding;
  • placement, worker/lease status, and terminal outcome;
  • budget consumption;
  • typed progress events and tool activity;
  • a live event stream where available; and
  • links back to the bound Cycle.

Lease and fencing state protect against a stale worker completing reassigned work. A stale fencing response is a safety refusal, not a retryable UI glitch.

Some supervision write controls can be unavailable on a deployed Control Plane or for a caller without the needed access. The UI must state that nothing was sent. When that happens, cancel the runtime where it is running and let the normal attempt reconciliation record the outcome.

Operational pages

PathPurpose
/homeIdentity and project-aware starting point
/overviewAdministrator KPIs, gate queue, and recent activity
/projectsVisible projects and project administration
/activityScoped delivery activity
/qualityReceipt and Definition-of-Done evidence
/costToken/model cost projections from reported usage
/reliabilityRuntime latency, errors, and delivery health
/auditScope-aware audit log
/sessionsActive sessions and revocation controls
/skillsSkill manifest and permitted usage information
/peopleScoped participant activity and access patterns
/policySigned policy/configuration view for administrators
/systemService health and deployed versions for administrators
/profileIdentity, groups, and sign-out controls

The exact sidebar is role-aware. Not seeing an administrator page is expected when the current identity lacks that role.

Quality evidence

The Quality page projects receipt and Definition-of-Done signals. Use it to identify failing proof, missing role evidence, or systematic quality drift.

The repository receipt remains the detailed local source. The Control Plane receives a minimized projection rather than prompts, transcripts, artifact contents, commands, summaries, or findings by default.

Cost and attribution

Cost views depend on honest host/model/token attribution delivered with receipts and attempts. An unattributed model value is preferable to a guessed model ID. Missing telemetry should appear as missing data rather than be silently estimated as proof.

Runtime federation makes attempt identity especially important: one Work Unit can have several attempts after a denial, reroute, retry, or recovery, and the page must not collapse them into one mutable row.

Sessions and revocation

The Sessions page shows sessions visible to the caller and supports scoped revocation. Revoking a session does not rewrite repository lifecycle state. A running attempt may fail its next authenticated operation and remain incomplete until reconciled.

After revocation, sign in again with synaptory login, run host Doctor, and ask the kernel for the current action before resuming.

State authority

Use this rule when the browser and a local clone seem inconsistent:

  1. Read the current repository state and exact manifest/receipt identity.
  2. Run host status/Doctor.
  3. Check whether the required projection is still queued in the durable outbox.
  4. Treat the Control Plane as stale visibility until the authenticated handoff succeeds.

Never edit local state to make a dashboard row look current.

Guides · 20

Release and Acceptance

In SPQ, release readiness is proven through Acceptance. When several delivery continues after a go-live, Acceptance repeats: each one compiles its own readiness above the child evidence.

When Acceptance becomes available

At Checkpoint, the delivery lead chooses either another Commit or Acceptance. The kernel allows Acceptance only when:

  • admitted Work Units are terminal;
  • required Cycle receipts are valid;
  • every closed Cycle recorded a green barrier verdict naming its integrated trunk revision;
  • no blocking dependency or recovery remains; and
  • the selected release scope is coherent.

Do not trigger release merely because a branch looks complete. Ask Synaptory for the current action and use the evidence it presents.

Acceptance roles

RoleRelease evidence
Quality EngineerFull regression, acceptance expectations, critical journeys, quality verdict
Compliance EngineerSecurity, privacy, dependency, regulatory, and critical-finding verdict
Platform EngineerBuild, deployment, rollback, infrastructure, monitoring, and operational readiness
Technical WriterRelease notes, runbooks, API/developer documentation, known limitations
Code ReviewerRead-only final review of scope, architecture, quality, and unresolved findings

Each role receives its own release dispatch and writes its own bound receipt. One role's green result cannot substitute for another's missing evidence.

Host execution

Hosts can schedule the logically independent Acceptance activities differently. Codex runs all five sequentially because its certified configuration permits four total agent threads including the parent. Sequential execution does not weaken the required evidence.

Runtime federation does not participate in a normal release: no host dispatch path calls the selector yet, so release activities run on the host's own runtime regardless of any runtimes: policy. When an attempt is driven explicitly through the bridge, its failure or cancellation leaves the release activity incomplete.

Readiness review

Before the human decision, review:

  • the exact Cycle and Work Unit scope included;
  • all release receipts and verification outcomes;
  • the barrier verdict and integrated trunk revision for every included Cycle;
  • known limitations and explicitly accepted risks;
  • deployment and rollback instructions;
  • unresolved non-blocking findings; and
  • runtime/model attribution required by organizational policy.

Critical test, security, review or barrier failures block Complete. The remedy is new governed evidence after repair, not an edited verdict.

Human completion gate

The real delivery lead explicitly approves or rejects completion. Synaptory records the real principal as approver. Agents cannot infer approval from phrases such as "looks good" in an unrelated context or reuse a prior release decision.

After approval, Complete is terminal for that SPQ release state. Start new work through a new governed outcome/Cycle, not by reopening terminal receipt files.

Release when several Cycles are live

There is no layer above the Cycle that composes a release, and that is the change SPD-194 made. A Coordination Cycle used to pin each child's SHA and evaluate six composition criteria; it existed only because integration was deferred -- nothing reached the trunk until a human merged, so something downstream had to gather it.

With the barrier integrating to the shared trunk at each Checkpoint, there is nothing left to gather. Each Cycle reaches the trunk on its own Checkpoint, and an Acceptance releases a trunk revision, not a set of pinned branch heads.

So when several Cycles are live:

  • each closes and integrates independently. Neither waits for the other, and

no cross-Cycle check runs at admission.

  • Acceptance pins one integrated trunk revision and compiles its package from

the records the work already produced.

  • Acceptance repeats. A Cycle continuing through a go-live is normal;

only the final Acceptance closes the engagement.

If two Cycles are ready at the same moment, only the short promotion transaction serializes -- not their cadences. A trunk that moved forces the later one to rebuild and re-verify: reusing a green result against a revision that has changed is green about something else.

Deployment is still a controlled operation

Acceptance proves readiness; it does not grant agents unrestricted production access. Deployment follows repository and organizational controls such as pull request approval, protected environments, change windows, and rollback policy.

The Platform Engineer can prepare commands and evidence. The authorized human or deployment system owns merges, pushes, secrets, and production promotion.

Legacy projects

Existing Scrum and Kanban projects retain their legacy Release flow during the retirement period. Do not use that flow as the model for a new SPQ project. Plan migration at a stable boundary using Migrating to SPQ.

Guides · 21

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/synaptory_api/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

Guides · 22

Migrating to SPQ

Scrum and Kanban projects can continue during their retirement period, but new delivery should converge on SPQ. Migration is a lifecycle transition, not a configuration-only edit.

Do not hand-edit state

Never change build_mode and then rewrite .synaptory/.orchestrator/pipeline-state.json to resemble SPQ. Do not copy legacy receipts into SPQ paths or use a specification identifier as a Cycle identity.

Use governed status, initialization, and migration operations so the resulting state has valid manifests, identities, and evidence boundaries.

1. Reach a stable legacy boundary

Before migration:

  • finish or explicitly defer the active Scrum story or Kanban ticket;
  • resolve in-flight agent dispatches;
  • capture the current status and outstanding backlog;
  • commit project work and lifecycle evidence that policy requires; and
  • prefer a Sprint Close, Kanban Review, or completed release boundary.

If the current project is inconsistent, run Doctor and repair it before starting SPQ. Migration must not hide an existing state failure.

2. Inventory the future SPQ shape

Map the existing delivery structure into:

Legacy conceptSPQ decision
Product/backlogProject outcome and Discovery baseline
Sprint or ticket batchCandidate scope for the first Cycle
Story/ticketWork Unit, after readiness review
Component/team boardPart of a Cycle's source region when it represents a lasting code area. It is not a lane with a lifecycle of its own
Cross-team dependencyA verifiable depends_on edge. Within one Cycle if the pair cannot be ordered; across Cycles only against a published result
Release trainRepeatable Acceptance. There is no layer above the Cycle that composes releases

Do not automatically turn every team or board into a region. Regions must survive staffing changes.

3. Separate Multi-Spec from SPQ identity

Legacy Multi-Spec uses spec-scoped Scrum/Kanban tracker and state projection. SPQ uses native Cycle identity and ignores SYNAPTORY_ACTIVE_SPEC.

If the repository has older SPQ state stored under a Multi-Spec location, ask Synaptory Doctor for the native-SPQ migration plan. The low-level migrate_spq_native.py utility is an operator recovery tool and should not be used as a general Scrum/Kanban conversion command.

4. Prepare configuration

Propose and review:

build_mode: "spq"

spq:
  source_region:
    - "api/"
  trunk_ref: "refs/heads/dev"

Keep existing tracker configuration when supported. Remote trackers work with SPQ; their sprint/cycle terminology is an adapter concern and does not replace SPQ state.

Do not enable runtimes: during the same change unless runtime federation is a separate reviewed objective. First prove the native host path.

5. Initialize SPQ through the host

Ask Synaptory to initialize or migrate the project for SPQ and present the planned state before applying it. Codex uses its authenticated MCP lifecycle operation; Claude Code and Cursor use their governed host adapters. No host should mutate lifecycle state through copied Python commands.

After initialization, run Doctor again and confirm:

  • build_mode: spq is explicit;
  • the SPQ state is readable;
  • Cycle identity is native;
  • the host is certified for the intended project class; and
  • no legacy active dispatch remains.

6. Run a fresh Discovery

Do not treat a legacy backlog as an already approved SPQ baseline. Discovery can reuse existing product and architecture evidence, but it must explicitly frame the first SPQ outcome, the source region, dependencies and proof expectations.

The first Commit should admit a deliberately small Cycle. Use it to validate receipt paths, the regression proof, tracker mappings and the human gate workflow.

7. Preserve legacy history

Legacy state and reports remain historical evidence. Keep them read-only and clearly labeled; do not make the first SPQ Cycle continue legacy sequence numbers merely for cosmetic continuity.

Update team runbooks and automation to stop invoking Scrum/Kanban state-machine commands or setting SYNAPTORY_ACTIVE_SPEC for SPQ work.

Rollback boundary

Before the first SPQ Commit, a failed initialization can be repaired through the governed setup flow. After Work Units are admitted, do not "roll back" by switching build_mode and editing state. Stop the Cycle, preserve evidence, and use an operator-reviewed recovery or migration plan.

Guides · 23

Migrate a project from hiro-crew to Synaptory

Transitional guide. hiro-crew was renamed to Synaptory. If your project repo was set up with the old plugin, run this once to convert it. The synaptory migrate command and the session-start nudge are temporary and will be removed in a future release after all downstream projects have migrated.

What it does

A repo that used hiro-crew has, on disk:

  • .hiro-crew.yaml — project config
  • .hiro-crew/ — orchestrator state (pipeline-state, receipts, specs, protocols, deliverables)
  • CLAUDE.md / AGENTS.md — hiro-crew markers (<!-- hiro-crew-state … -->, fences)
  • .claude/settings.json — the hiro-crew@h3tech-ai plugin id
  • .gitignore / .dockerignore / docs — .hiro-crew path references

synaptory migrate renames .hiro-crew.yaml → .synaptory.yaml, moves .hiro-crew/ → .synaptory/, and rewrites every embedded hiro-crew reference (markers, paths, plugin id, URLs, brand text) so the Synaptory plugin recognizes the project. It takes a backup first and is idempotent.

Steps

From the project root:

synaptory migrate --dry-run   # preview the plan, no changes
synaptory migrate             # apply (asks to confirm; --yes to skip)

A snapshot of the pre-migration state is saved to .synaptory/.migrations/<timestamp>-pre-synaptory-rename.tar.gz. Review git diff, then commit.

Then, in Claude Code, point at the Synaptory marketplace and re-authenticate:

/plugin marketplace add https://github.com/h3tech-ai/marketplace
/plugin install synaptory@h3tech-ai
synaptory login    # re-authenticate against synaptory.h3t.co

Notes

  • Backup + git are your safety net — the "thorough" rewrite also updates

brand prose in README/docs; check git diff and revert anything you'd rather keep verbatim.

  • Multi-spec repos keep their .synaptory/.orchestrator/specs/<id>/

isolation; tracker IDs, sprint metrics, and BAA flags are preserved.

  • Re-running is safe: if .synaptory.yaml already exists, migrate is a no-op.
  • Flags: --project-dir <path> (default: cwd), --dry-run, --yes,

--backup-dir <path>.

Legacy · 24

Legacy Scrum Delivery

Legacy compatibility path. Scrum is maintained for existing projects while retirement is planned. New projects should use build_mode: spq. Runtime federation is not available in Scrum.

This page exists so an in-flight Scrum project can reach a safe boundary without relying on old internal-command documentation. It is not the recommended onboarding path.

When to continue temporarily

Continue the legacy lifecycle only when stopping mid-sprint would create more risk than finishing its bounded scope. Prefer to:

  1. finish or explicitly defer every active story;
  2. preserve receipts, tracker bindings, and DoD evidence;
  3. complete the current review/close boundary through the host adapter; and
  4. start subsequent delivery as a new SPQ Cycle.

Claude Code retains the compatibility path. Codex and Cursor have not certified Scrum end to end and must warn before dispatch.

Supported interaction

Use the active host entry point and natural language:

Show the current legacy Scrum state and the next governed action.
Resume the active sprint without adding new scope.
Prepare the current sprint for its safe close boundary.

Do not run internal state-machine modules or edit .synaptory/ lifecycle files. The host must re-read canonical state, enforce receipts, and stop at human decisions.

Moving to SPQ

Do not translate sprint numbers into Cycle numbers or rewrite historical receipts. Preserve the completed legacy history and initialize the next outcome as SPQ with explicit build_mode: spq.

Follow Migrate to SPQ for the boundary checklist and vocabulary mapping.

See also

Legacy · 25

Legacy Kanban Delivery

Legacy compatibility path. Kanban is maintained for existing projects while retirement is planned. New projects should use build_mode: spq. Runtime federation is not available in Kanban.

Existing maintenance boards may continue long enough to reach a clean handoff boundary. Avoid adding a new program of work to the legacy board.

Safe compatibility use

  1. Finish, defer, or explicitly block the active ticket.
  2. Preserve its receipt, verification evidence, and tracker mapping.
  3. Avoid pulling broad new scope.
  4. Start the next coherent outcome as a bounded SPQ Cycle.

Claude Code retains the compatibility path. Codex and Cursor have not certified Kanban end to end and must warn before dispatch.

Supported interaction

Use the host entry point:

Show the current legacy Kanban state and active ticket.
Resume only the active ticket and preserve its evidence.
Prepare this board for migration to SPQ after the ticket completes.

Do not manipulate the board through private Python modules or hand-edited state. Tracker status is a projection; it does not replace canonical lifecycle state.

Moving to SPQ

A maintenance request can become one Work Unit in a small SPQ Cycle. Group related tickets only when they share one outcome and can pass the same integration/Checkpoint boundary.

Follow Migrate to SPQ rather than renaming tickets or replaying old transitions.

See also

Legacy · 26

Legacy Multi-Spec Delivery

Legacy compatibility path. The former Multi-Spec pattern is superseded by the SPQ Cycle. Do not start new Multi-Spec delivery.

The old model used parallel spec slots inside Scrum. SPQ now represents the useful distinctions directly:

Legacy needCurrent SPQ concept
Parallel product/code areas in one integrated delivery unitOne Cycle, with each Work Unit declaring its own path_scope. Disjoint scopes run concurrently with nothing to enable
Small governed items in each areaWork Units
One cross-area integration boundaryThe Cycle barrier, at Checkpoint, integrating to the shared trunk
Several independent delivery units with different cadencesSeveral concurrent Cycles with non-overlapping source regions. Nothing sits above them
Combined shipmentRelease after the relevant Cycles are accepted

Choose the replacement

Use one Cycle when every area must integrate and pass one barrier at the same Checkpoint.

Use several concurrent Cycles when areas have independent scope, timing and Checkpoints. Their source regions must not overlap; that condition is what keeps them independent, and nothing composes them afterwards -- each reaches the trunk on its own Checkpoint.

Migration boundary

  1. Stop admitting new legacy spec work.
  2. Finish or explicitly defer active stories through the host adapter.
  3. Preserve historical spec IDs and receipts for audit.
  4. Identify durable product/code boundaries as the Cycle's source region.
  5. Decide whether the next outcome is one Cycle or two with disjoint regions.
  6. Initialize new canonical SPQ state; do not rewrite the legacy pipeline.

Follow Migrate to SPQ, then continue with SPQ Delivery.

Reference · 27

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-claude/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
"spq"Recommended. Scope-defined Cycle delivery: Discovery -> Commit -> Cycle Execution -> Sync -> Checkpoint -> Acceptance. Requires an spq: block.
"scrum"Legacy compatibility default when the key is omitted. Planned for retirement.
"kanban"Legacy continuous ticket flow. Planned for retirement.
build_mode: "spq"   # set explicitly for new projects

An omitted value still resolves to Scrum in the current compatibility layer. Documentation therefore calls SPQ the recommended lifecycle, not the implicit technical default. Do not leave the key unset on a new project.


engagement_mode

Controls how prominently Synaptory surfaces decisions between mandatory human gates.

ValueBehavior
"structured"(Default) Continue autonomously between mandatory gates when the dispatch/evidence contract permits.
"interactive"Surface more intermediate choices for human review. Does not weaken validation or add authority.

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.*

Legacy compatibility section. Each host now owns its native role runtime: Claude Code uses Claude, Codex uses Codex/OpenAI models, and Cursor uses its configured model surface. Governed cross-runtime selection is configured under runtimes:, not here.

KeyTypeDefaultDescription
agents.default_backendstring"claude"Accepted for compatibility. It is not the runtime selector and non-Claude values do not create cross-runtime dispatch.

The orchestrator runs in the installed host. Model choice follows that host's approved policy. A selected role maps through the fixed capability projection; role names are not adapter profile IDs.

The runtimes: policy does not influence this today. It is parsed and validated, but no host dispatch path consults the selector, so an ordinary Cycle Execution run is unaffected by it. See Hosts and runtimes.

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, linear. local stores compact state in tracker-data.json and canonical content in ID-named Markdown files under docs/requirements/.
tracker.github.repostring""GitHub repo (owner/repo). Auto-detected from git remote if empty.
tracker.github.cli_commandstring""Command that speaks the gh argument grammar. Empty means plain gh, so tracker writes are attributed to whoever's gh auth session is on the machine. Set it to a token-broker wrapper (e.g. h3t-gh-planner) to attribute agent writes to a bot identity that holds only the permissions the backlog needs. A value set here wins over the SYNAPTORY_GITHUB_CLI environment variable, so an ambient variable cannot silently downgrade a committed identity.
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_stagesobject—Maps synaptory statuses to Teamwork board column IDs.
tracker.linear.team_keystring""Linear team key (e.g. ENG) — the short key, not the team name. Required.
tracker.linear.team_idstring""Optional team uuid. Set to skip the by-key lookup.
tracker.linear.project_idstring""Optional default Linear Project applied to created issues.
tracker.linear.label_prefixstring"hc:"Prefix for the entity labels that type an issue (hc:epic, hc:story, …). Linear has no native issue-type field.
tracker.linear.manage_cyclesboolfalseWhether Synaptory may call cycleCreate. Default false: Linear creates cycles on the team's own cadence, so create-sprint binds to an existing cycle and reports if none matches.
tracker.linear.cycle_length_daysint14Length of a cycle Synaptory creates when manage_cycles is true and the caller supplied no dates. Linear requires both startsAt and endsAt on cycleCreate.

The local backend works in any build_mode. Remote backends (github, jira, teamwork, linear) work with Scrum, Kanban, or SPQ. Tracker Sprint/Cycle terminology does not replace SPQ lifecycle state.

Linear specifics

Linear differs from the other remote backends in three ways worth knowing before you configure it:

  • Sprints are Cycles. Linear cycles carry a native integer number, so there is no sprint_milestone_prefix and no name parsing. Cycle numbers are team-lifetime-monotonic and never restart, so a team already at cycle 47 has no "cycle 1" for Sprint 1 to match. Binding resolves in order: an existing SPRINT-N entry in tracker-id-map.json, then a cycle whose number matches, then an explicit SprintInfo.tracker_id, then the earliest unbound, unfinished cycle — which is how a fresh Synaptory project adopts a team that is already mid-cadence. The pairing is recorded on first bind and is stable thereafter.
  • Epics are labels. An epic is an issue tagged hc:epic plus its EPIC-001 id label, and a story joins that epic by carrying the same EPIC-001 label — not a parent relation and not a Linear Project. This keeps parent/child free for real sub-tasks and leaves Projects available as a multi-spec discriminator.
  • Statuses resolve in three tiers. Linear teams define their own WorkflowState names, so the adapter tries your status_map override, then the built-in name, then the state's type (backlog / unstarted / started / completed / canceled). A fully custom workflow — Icebox → Up Next → Building → Peer Review → Shipped — normally needs no status_map at all. Add one only when the type-based fallback picks the wrong column.

When a team has no "Awaiting Acceptance" column, AWAITING_ACCEPTANCE lands on the review state plus an awaiting-acceptance label, and read-back uses the label to tell the two apart. This matches the Teamwork behavior.

Migration — tracker.backend: markdown was removed. Earlier versions accepted markdown as an alias for local. It is no longer valid: config load now fails fast with guidance. Set tracker.backend: local instead — the local backend already stores canonical content as ID-named Markdown artifacts under docs/requirements/ (with a compact JSON index), so no content moves.

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

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

Legacy Scrum/Kanban surface. SPQ uses native Cycle identity and ignores SYNAPTORY_ACTIVE_SPEC. Do not create specs[] as a substitute for an SPQ source region.

When a top-level specs: block is present on a legacy project, one tracker project (local / Jira / GitHub repo / Teamwork project) hosts N partitioned backlogs. See the Legacy Multi-Spec guide for the replacement mapping.

Every remote spec carries exactly one backend binding (jira: / github: / teamwork:), matching tracker.backend. Mixed remote bindings are rejected at config-load time. For tracker.backend: local, a spec may use a local: binding or omit the backend block; Synaptory partitions local tracker state by spec id under .synaptory/.orchestrator/specs/<id>/.

KeyTypeDescription
specs[].idstringkebab-case spec id (used in --spec flags, directory names).
specs[].namestringHuman-readable label for the spec.
Local binding
specs[].local.requirements_dirstringOptional spec-specific Markdown artifact root, e.g. docs/venue-agent/requirements.
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: "h3tech-ai/example-app"
specs:
  - id: "platform"
    name: "Multi-tenant Platform"
    github:
      repo: "h3tech-ai/example-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"

Do not migrate a new single-spec project into this legacy surface. Model new parallel delivery as concurrent SPQ Cycles with non-overlapping source regions, and follow Migrate to SPQ for an existing project.


spq.*

Read only when build_mode: spq.

This section changed shape at SPD-194. spq.workstreams[], the 24 spq.sync.* keys and spq.coordination.* are gone with the Workstream and the Coordination Cycle. spq.runtimes is unaffected. See ADR-035.

Also gone: spq.sync.accept_unverified_events. It was documented here and named in two refusal messages, and nothing ever read a config value into it -- the toggle was advertised and inert. Of the two ways to make that honest, this is the stricter one: an unverified claim never unblocks downstream work, and there is no setting. Wiring the key would have added a documented route to weaken an evidence gate in order to make a docs page true.

KeyTypeDescription
spq.source_region[]listRepository-relative path prefixes this project's Cycles may address (C-08). Overlapping regions are refused at declaration, which is what lets two Cycles run concurrently without either inspecting what the other admits
spq.trunk_refstringThe one shared branch a Cycle integrates into at its Checkpoint (C-05). A Cycle that closes having integrated nothing anyone else can see has not closed
spq.regression_scriptpathCommitted script proving the barrier's regression_green criterion
spq.cycle.scope_definedboolCycles end on admitted scope, not a clock. No timer may force an unverified close -- a Cycle that cannot finish cuts instead
spq.runtimes.*objectRetained unchanged. See runtimes.*
spq:
  source_region:
    - "api/"
    - "web/"
  trunk_ref: "refs/heads/dev"
  regression_script: "scripts/cycle-regression.sh"
  cycle:
    scope_defined: true

There is no parallelism switch, and its absence is the design. C-07 and SC-MTH-010 make concurrency a consequence of the path_scope each Work Unit declares, so the retired parallelism.story_parallelism and the isolation: worktree|shared distinction have no replacement key:

  • intersecting scopes are refused at Commit unless each declares a distinct

execution_order; they then run sequentially in one Cycle;

  • a concurrent dispatch onto an intersecting scope is refused at dispatch with

scope_collision;

  • disjoint work proceeds with nothing to enable.

parallelism.max_concurrent_subagents survives as a resource ceiling. The distinction is worth keeping: a ceiling limits how much runs at once and can never make colliding work legal, while the retired switch decided whether the collision was looked for at all. Under build_mode: spq the effective policy reports that ceiling plus governed_by: "declared path scope (C-07)".

Per-Cycle rather than per-project. The declaration seals the source region, the trunk, the barrier criteria and the admitted set at Commit, so these config keys are defaults a Cycle is opened from, not the authority the barrier reads. The authority is the sealed declaration.

runtimes.*

Optional governed runtime selection for SPQ. The selector is inert when this section is absent, disabled, invalid, or used with Scrum/Kanban.

KeyTypeDescription
runtimes.versionintPolicy schema; currently 1. Unknown versions fail closed.
runtimes.enabledboolExplicit opt-in
runtimes.allowed_profileslistAuthority ceiling for every selection mode
runtimes.allowed_placementslistPermitted placements such as local or managed-laptop
runtimes.preferences.<capability>listPreferred order within the allowed profiles
runtimes.required_capabilities.<capability>listRequired capabilities for analyst/planner/producer/prover dispatch
runtimes.fallback.enabledboolWhether an ineligible preference may reroute
runtimes.fallback.max_reroutesintRetry/reroute ceiling per stage
runtimes.fallback.allow_out_of_order_rerouteboolWhether policy can skip cheaper remediation ordering with a recorded reason

Preferences and capability keys must use analyst, planner, producer, or prover, never a role such as se or qe.

runtimes:
  version: 1
  enabled: true
  allowed_profiles:
    - "claude-local-v1"
    - "codex-local-v1"
  allowed_placements: ["local"]
  preferences:
    producer: ["claude-local-v1"]
    prover: ["codex-local-v1"]
  required_capabilities:
    producer: ["workspace.write", "process.test"]
    prover: ["receipt.v2"]
  fallback:
    enabled: true
    max_reroutes: 2
    allow_out_of_order_reroute: false

allowed_profiles is an authority ceiling, not a claim that a machine can serve what it lists: a profile is only selected if the probe snapshot also reports it available. codex-local-v1 above is allowed and, on the current Codex CLI, never available, because Codex states no exact model id and a receipt from it would name no model. The prover preference in this example is therefore skipped and the dispatch falls through to claude-local-v1. See Hosts and Runtimes.


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. A stack hint for just-in-time tech pack retrieval.
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.*

Legacy Scrum settings. Active only when build_mode: scrum; do not use them to configure an SPQ Cycle.

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 signals used by the shared Work Unit/story pipeline. SPQ adds dispatch binding, Sync, Checkpoint, and Acceptance evidence above these checks. The sprint overlay is legacy Scrum-only configuration.

dod.story -- Per-Work-Unit/story DoD

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

New SPQ project

version: "3.0"
project_id: "reservation-saas"
build_mode: "spq"
engagement_mode: "structured"

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

spq:
  source_region:
    - "api/"
    - "web/"
  trunk_ref: "refs/heads/dev"
  regression_script: "scripts/cycle-regression.sh"
  cycle:
    scope_defined: true

brownfield:
  coverage_ratchet: true
  context_packages: true
  characterization_tests: true

Legacy 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

Legacy brownfield API (Kanban)

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 · 28

Commands Reference

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

Synaptory has two public command surfaces:

  1. the host entry point used inside Claude Code, Codex, or Cursor; and
  2. the synaptory CLI used for authentication, diagnostics, policy, and runtime operations.

Lifecycle state is advanced by Synaptory through the host adapter or MCP tools. Files and Python modules under plugin hook directories are implementation details, not user commands.


Host entry points

HostEntry pointNotes
Claude Code/synaptoryInstalled from the Synaptory Claude marketplace.
Codex$synaptoryInstalled as a Codex plugin. Standard non-regulated SPQ requires Codex 0.147.0 or newer.
Cursor IDEStart the synaptory agent or ask it naturallyProject rules, skills, subagents, hooks, and MCP configuration are installed together.
Cursor headlesscursor-agent with the Synaptory project configurationRun the MCP preflight before starting governed work.

You can follow the entry point with an operation, for example:

Start an SPQ Cycle for the account recovery feature.
Show the current Cycle and its evidence gaps.
Run Checkpoint for WU-014.
Prepare Acceptance for the current Cycle.
Resume the active Cycle.
Run Synaptory doctor.

The host interprets natural language, reads canonical state, dispatches the appropriate lifecycle agents, and pauses at required human gates. See SPQ Delivery and Routing.


Common CLI commands

Install the CLI once per machine; see Install the CLI.

Identity and health

CommandPurpose
synaptory loginSign in through the browser.
synaptory login --deviceSign in from a headless environment.
synaptory logoutRevoke the cached session and clear the keychain entry.
synaptory whoamiShow the cached identity, token expiry, and plugin version.
synaptory statusShow authentication, cache, and outbox health.
synaptory versionShow the installed CLI version.
synaptory updateCheck for and install an available CLI update.

Skills and policy

CommandPurpose
synaptory skills syncRefresh the governed skill cache.
synaptory skills listList cached skills.
synaptory skills get <name>Print one cached skill, fetching it on cache miss.
synaptory config fetch --if-staleRefresh the cached control-plane policy when needed.
synaptory config envShow the active policy summary.

Projects, activity, and support

CommandPurpose
synaptory projects listList visible control-plane projects.
synaptory projects currentResolve the current project from the workspace.
synaptory projects show <slug-or-id>Show project detail and membership.
synaptory costShow local session token usage and estimated cost.
synaptory activityInspect recorded activity.
synaptory outbox listInspect queued telemetry.
synaptory outbox flushRetry delivery of queued telemetry.
synaptory report submitSubmit a support report through the control plane.

Administrative project and membership subcommands are visible only to callers with the corresponding control-plane authority. Run synaptory <command> --help for the exact flags supported by your installed version.


Runtime Bridge

Runtime federation is optional and SPQ-only. Installing Synaptory in several hosts does not enable it automatically. Configure runtimes: in .synaptory.yaml, then use these commands to inspect the effective capacity.

Machine capacity: synaptory runtimes

CommandPurpose
synaptory runtimes listList certified adapter profiles, placements, pinned versions, capability profiles, and capability ceilings.
synaptory runtimes doctorProbe every configured profile and report whether this machine can serve it. An unavailable profile is reported, not hidden.
synaptory runtimes doctor --profile <profile-id>Probe one profile.
synaptory runtimes registerProbe every configured profile and register this machine with the control plane, advertising only the probe-ready ones. Refuses if none are ready.

The pilot profile IDs are:

  • claude-local-v1
  • codex-local-v1
  • cursor-local-readonly-v1
  • claude-managed-standard-v1

register advertises what this machine can execute, not what the pilot certifies. A missing runtime binary, a version outside the profile's pin, or a machine that is not configured for the profile's placement is neither advertised nor claimable, and if nothing is ready the command refuses rather than registering an empty set (the control plane reads an empty supported_profiles as a wildcard). Because register is one-shot, its answer is a snapshot: re-run it after installing, removing, or upgrading a runtime. synaptory runtime worker is the continuous form of the same probe. It re-probes on a freshness window and re-registers whenever the ready set changes.

A profile appearing in runtimes list means the combination is recognized. It does not mean the runtime binary is installed or ready; use runtimes doctor to establish that.

One attempt: synaptory runtime

CommandPurpose
synaptory runtime execute --envelope <path>Validate a dispatch envelope and run one attempt through its named adapter. Use --envelope - for stdin.
synaptory runtime status --attempt <id>Read the recorded state of one attempt.
synaptory runtime explain --attempt <id>Show the attempt's authority ceiling and supervision timeline.
synaptory runtime cancel --attempt <id> --reason "…"Request cancellation and record why. Output states whether the request reached the control plane or only the local record.
synaptory runtime workerRun the lease-holding worker. This is an operator surface, not a normal delivery command.

The Runtime Bridge executes an already-authorized envelope. It does not select the runtime, expand authority, approve evidence, or advance a Work Unit. The SPQ dispatch and advance kernels retain those responsibilities.


Read-only questions vs state changes

These requests are safe lookups:

Show Synaptory status.
Which stage is the current Cycle in?
Explain attempt <id>.
What evidence is missing for WU-014?

These requests can change canonical lifecycle state and therefore run through the active host adapter, with confirmation at human gates:

Start a Cycle.
Accept this Cycle's Checkpoint on its integrated trunk revision.
Accept the current Cycle.
Release the accepted Cycle.
Cancel this runtime attempt.

Do not invoke hook scripts or lifecycle Python modules directly to force a transition. Doing so bypasses authority checks, append-only history, idempotency, and receipt validation.


Legacy commands

The CLI may expose compatibility surfaces such as specs and the transitional migrate command. synaptory migrate migrates a supported hiro-crew consumer setup; it is not the Scrum/Kanban-to-SPQ migration workflow.

For an existing Scrum or Kanban project, follow Migrate to SPQ. Keep legacy lifecycle state read-only for audit and resume new governed work as a fresh SPQ Cycle.


Maintainer-only repository script

The repository-root ./synaptory script builds and deploys Synaptory itself. It is for Synaptory maintainers, not for projects consuming the product. Run ./synaptory help from this repository for its current command surface.


What's next?

Reference · 29

Routing Reference

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

Synaptory routes a request in two steps: first to the configured lifecycle, then to the role or focused operation best suited to the request. Canonical project state and explicit identifiers take precedence over loose keywords.


Routing order

  1. Explicit operation — a request such as “run Checkpoint for WU-014” wins over inferred intent.
  2. Active canonical state — if a Cycle is active, Synaptory resumes the stage or gate recorded there.
  3. Configured lifecycle — build_mode: spq routes delivery work through SPQ.
  4. Bound identifier — a Cycle, Work Unit, ticket, or attempt ID narrows scope.
  5. Focused intent — debug, review, security, architecture, documentation, testing, and similar operations choose a specialist role while staying bound to the active Work Unit when applicable.
  6. Clarification — if two materially different state-changing routes remain possible, Synaptory asks rather than guessing.

Conversation history is supporting context, not the source of truth for current lifecycle state.


SPQ lifecycle routing

Request intentRouteExpected result
“Start SPQ delivery for …”DiscoveryEstablish intent, boundaries, the source region, risk, and a proposed baseline.
“Resume the current Cycle”Current canonical stage/gateRe-read state and continue the next allowed operation.
“Approve the baseline”Discovery gateRecord the explicit human baseline decision.
“Open this Cycle”CommitAdmit the approved non-empty set of ready Work Units and seal the manifest.
“Implement WU-014”Cycle Execution / producerDispatch the bounded implementation attempt.
“Test WU-014”Cycle Execution / proverDispatch verification without changing the Work Unit's authority.
“Close the Cycle”CheckpointRun the barrier over the admitted set minus recorded cuts, integrate to the trunk, and record the close.
“Clear Sync”Sync clearanceRecord explicit human clearance only after the integration verdict is green.
“Run Checkpoint”CheckpointDemonstrate the integrated Cycle and choose another Cycle or Acceptance.
“Prepare Acceptance”AcceptanceSummarize outcome, evidence, exceptions, and residual risk for a human decision.
“Release the accepted Cycle”ReleaseRun release checks and pause at the Release gate.

Discovery, Commit, Cycle Execution, Sync, Checkpoint, Acceptance, and Complete are lifecycle states. Commit, Sync, and Checkpoint are SPQ method events mapped onto Synaptory's stage/gate spine; a request cannot skip an unmet prerequisite.


Focused operations

Focused operations may run inside an SPQ Work Unit or as bounded standalone assistance. When a Cycle is active, the result should be attached to the relevant Work Unit as evidence instead of creating a parallel lifecycle.

IntentTypical lead roleExamples
Diagnose an active failureSE or relevant specialist“Debug the failing login test.”
Review code or a diffCR“Review the changes for WU-014.”
Create or strengthen testsQE“Add regression tests for this Work Unit.”
Security or compliance assessmentCE“Run a STRIDE review for the new endpoint.”
Architecture or contract designSA“Design the event schema for this Cycle's source region.”
DocumentationTW“Document the accepted API behavior.”
Reliability, operations, or performancePE, with CR as needed“Investigate the latency regression.”
Research or option explorationRA“Compare the supported migration approaches.”
Project configuration/healthOrchestrator/doctor“Validate the Synaptory setup.”

These operations do not approve human gates and do not advance a Work Unit merely because a specialist completed.


Important tiebreakers

AmbiguityResolution
Build vs debugA concrete failure routes to debug; a new outcome routes to the active lifecycle.
Test vs debugA failing behavior routes to debug; proactive coverage routes to test.
Review vs securitySecurity, audit, threat-model, OWASP, or STRIDE intent routes to compliance/security review; general code quality routes to CR.
Work Unit ID vs general requestThe bound Work Unit wins and limits scope.
Release wording inside an unaccepted CyclePrepare Acceptance or explain the missing prerequisite; do not jump to Release.
Runtime preference vs policyPolicy and capability requirements win. A user preference cannot expand authority or select an uncertified profile.
Chat recollection vs canonical stateCanonical state wins; state is re-read before action.

Legacy routing

Projects already configured as scrum or kanban may continue through the compatibility path, but that path is planned for retirement. New delivery work should use build_mode: spq.

Runtime federation is inert for legacy modes. If a legacy request would start substantial new work, Synaptory should recommend migrating to SPQ instead of expanding the legacy lifecycle.


Diagnosing an unexpected route

  1. Run synaptory status and ask the host to show the active canonical Cycle.
  2. Confirm .synaptory.yaml contains build_mode: spq.
  3. Include the Cycle or Work Unit ID in the request.
  4. State the operation explicitly: Discovery, approve baseline, Commit/open Cycle, Sync entry, clear Sync, Checkpoint, or Acceptance.
  5. If the host cannot read canonical state or MCP tools are missing, stop and fix integration health first.

See Troubleshooting for host-specific checks.


What's next

Reference · 30

Rules Reference

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

Rules are host-facing guardrails, not lifecycle authority. They remind an attempt how to work safely, while the dispatch envelope, receipt validator, advance kernel, and human gates enforce what the attempt may do.

The Claude Code package currently ships eleven rule entry points in plugin-claude/rules/. Codex and Cursor express equivalent outcomes through their own instructions, skills, hooks, and MCP integration; they do not pretend to implement Claude Code's exact hook surface.


Claude Code rules at a glance

RuleScopePurpose
synaptory-boundary-safetyAlwaysPrevents framework abstractions from crossing boundaries they do not own.
synaptory-conflict-resolutionAlwaysPreserves single ownership when artifact responsibilities overlap.
synaptory-flaky-testsTests and CITreats nondeterministic tests as a pipeline correctness problem.
synaptory-freshness.synaptory/**Requires volatile external facts to be refreshed before use.
synaptory-guard.synaptory/**Detects governed work when normal session bootstrap was unavailable.
synaptory-loop-reactions.synaptory/**Maps lifecycle notifications to fail-closed recovery behavior.
synaptory-receipt-protocol.synaptory/**Defines the proof-of-completion record expected from a bounded attempt.
synaptory-secrets-scanSecrets, environment, CI, and infrastructure pathsPrevents secret-shaped material from entering tracked artifacts.
synaptory-uxAlwaysKeeps decisions explicit, option-oriented, and attributable to the user.
synaptory-visual-identityAlwaysKeeps host output concrete, stateful, and information-dense.
synaptory-welcomeFirst eligible useGuides a new project into initialization and its first governed request.

These names describe packaged guidance. They are not SPQ states, capability profiles, or permission grants.

Receipt rule

The receipt rule requires an attempt to verify first and record evidence afterward. For an SPQ pipeline receipt, validation binds the record to:

  • the Cycle, Work Unit, attempt, and dispatch;
  • the selected role and any stage_profile / capability_profile copied from

the runtime envelope;

  • the exact artifacts and allowed paths;
  • the runtime identity and execution result; and
  • executed verification commands, findings, and Definition of Done signals.

A capability label confers no authority. Authority comes from the immutable dispatch envelope. Missing required evidence keeps the gate blocked or incomplete; it never becomes a pass.

Receipt filenames and role wire values remain implementation contracts. Do not invent a receipt or copy one from another attempt. Use the governed host action that created the dispatch and let validation derive the expected binding.

Loop and recovery rule

Loop reactions are deliberately fail-closed:

  • a blocked Work Unit is classified before another attempt is dispatched;
  • a failed criterion is remediated with evidence rather than marked complete;
  • a depth or no-progress guard stops further delegation;
  • state drift makes the local projection untrusted until it is re-read through

the public Synaptory surface; and

  • a rejected receipt is corrected or replaced by a newly authorized attempt,

never bypassed by editing lifecycle state.

The kernel remains the only legal writer of governed lifecycle state.

Host mapping

Governance outcomeClaude CodeCodexCursor
Project guidancePlugin rules and skillsAGENTS.md, plugin skills, and agent profilesProject rules, skills, and subagents
Start/stop enforcementNative hooksPlugin hooks plus MCP/CLI boundaryCursor hooks plus MCP boundary
Governed operations/synaptory$synaptorySynaptory agent or natural-language entry
Canonical stateRepository and advance kernelSameSame

Host-native conversation state is never the delivery record. Unsupported host capabilities fail closed instead of silently weakening a rule.

Reference · 31

Host Integration Reference

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

Synaptory integrates with Claude Code, Codex, and Cursor using the mechanisms each host actually provides. The hosts do not expose identical hook events, so Synaptory preserves the same governance outcomes with different adapters.

Hooks, rules, bootstrap instructions, and MCP tools are internal integration surfaces. Users normally interact through the host entry point and the public synaptory CLI.


Shared governance outcomes

Every supported host integration must preserve these invariants:

  • canonical SPQ state is read before work begins;
  • dispatch is bound to a Cycle, Work Unit, selected role, and

budget;

  • runtime output is reduced to governed events and evidence;
  • receipts are validated before a Work Unit can advance;
  • human gates remain human decisions;
  • retries are idempotent and append-only history is preserved;
  • unsupported capabilities fail closed instead of silently weakening governance.

Host-native conversation or session state is never canonical lifecycle state.


Integration matrix

ConcernClaude CodeCodexCursor
User entry/synaptory$synaptorySynaptory agent / natural language
Project instructionsPlugin commands, skills, agents, rulesAGENTS.md, plugin skills, agentsProject rules, skills, subagents
Lifecycle toolsHost/plugin adapterSynaptory MCP serverSynaptory MCP server
Session bootstrapNative session hooksProject instructions plus supported hooks/MCP bootstrapProject rules plus supported hooks/MCP bootstrap
Agent completion checksNative subagent hooksDeterministic receipt validation through Synaptory dispatchAgent/hook completion plus receipt validation
Context refreshNative compaction/session hooksRe-read canonical state through bootstrap and MCPRe-read canonical state through rules, hooks, and MCP
Supported SPQ scopeFullStandard non-regulated onlyFull, subject to environment and policy
Important preflightCLI/auth/plugin healthCodex >=0.147.0; four total threads including parentHeadless: MCP tool discovery before work

The exact host event names are implementation details and can change as a host evolves. The invariant is the outcome, not an assumption that one host's hook taxonomy exists everywhere.


Claude Code adapter

The Claude distribution uses native plugin capabilities and hooks for session bootstrap, rule injection, subagent protocol injection, receipt verification, pre-compaction re-anchoring, and end-of-session snapshots.

Typical event flow:

session start/resume
  → authenticate and refresh policy/skills
  → load canonical lifecycle context
  → dispatch lifecycle agent
  → validate receipt and verification evidence
  → snapshot resumable state

Receipt or verification failure blocks structured execution. Interactive execution surfaces the failure and asks the human how to proceed without pretending that the gate passed.


Codex adapter

Codex uses project instructions, skills/agents, supported hooks, and the Synaptory MCP server. It does not rely on Claude-specific plugin events.

Requirements for the currently certified standard, non-regulated SPQ path:

  • Codex 0.147.0 or newer;
  • the Synaptory plugin installed and enabled;
  • the Synaptory MCP server visible to the session;
  • no more than four total live threads, including the parent thread;
  • no cross-host dispatch or handoff.

When an MCP lifecycle call succeeds, re-read canonical state before reporting progress. Do not infer a transition from prose or from an agent finishing its task.


Cursor adapter

Cursor uses project rules, skills, subagents, hooks where supported, and the Synaptory MCP server. IDE and headless execution have different preflight needs.

For headless cursor-agent work:

  1. verify that the Synaptory MCP tools are discoverable;
  2. stop if discovery fails;
  3. confirm the environment's network and privacy policy;
  4. start or resume the Cycle only after the preflight passes.

Healthcare HC0 execution is allowed only when the organization's Enterprise/BAA, Privacy Mode, and eligible model requirements are all satisfied. A local configuration flag cannot manufacture those guarantees.


Runtime federation is a separate layer

The host adapter governs the lifecycle conversation. An optional runtime adapter executes one dispatch envelope on Claude Code, Codex, or Cursor according to a certified profile.

host adapter
  → SPQ dispatch kernel
  → authorized envelope
  → runtime adapter
  → supervised events + receipt
  → SPQ advance kernel

Installing all three host integrations does not cause them to collaborate. Runtime federation requires explicit runtimes: policy and is intentionally unavailable to legacy Scrum/Kanban flows.


Failure behavior

FailureRequired behavior
Authentication or policy cannot be establishedStop before governed mutation; explain remediation.
Canonical state cannot be readStop; do not reconstruct state from chat history.
MCP lifecycle tools unavailableStop host-driven advancement; Cursor headless must fail preflight.
Runtime profile unavailableKeep the Work Unit pending or select another policy-approved profile.
Receipt invalid or evidence missingDo not advance the Work Unit.
Runtime dies or exceeds budgetRecord the terminal attempt and require governed retry/recovery.
Human gate not approvedRemain at the gate.

Internal implementation files

Host packages contain shell scripts, Python libraries, rules, skills, and MCP wiring. Their paths are intentionally excluded from the public command contract. They may be inspected by maintainers, but users should not run them to create or transition lifecycle state.

For supported operations, use:

  • the host entry point for SPQ lifecycle work;
  • synaptory status for general health;
  • synaptory runtimes doctor for runtime readiness; and
  • synaptory runtime explain --attempt <id> for attempt authority and evidence.

What's next?

Reference · 32

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/*, /cycles, /attempts, /operations, /agents, /activity, /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)
https://synaptory.h3t.co/docs/getting-started.htmlStandalone multi-host onboarding guideAnyone signed in (gated by Caddy if needed)

The legacy /console/* and /portal/* URL trees return 404. There are no redirects — bookmarks pointing at the v1.0 surfaces must be updated.


Plugin distribution

URLPurpose
https://github.com/h3tech-ai/marketplacePublic git catalog and supported source for new installations.
https://synaptory.h3t.co/marketplace.gitCompatibility git catalog for existing Claude Code installations; release-mirrored to GitHub.
https://synaptory.h3t.co/marketplaceDiscoverability landing page. Not the marketplace transport.

New users run /plugin marketplace add https://github.com/h3tech-ai/marketplace. Existing users on the .git compatibility URL do not need to change it.


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/cycles/*Authorized project membersCanonical SPQ Cycle operations, plus the two records that must sit outside the executing agent's reach: /v1/cycles/regions/* (the source-region registry, reserved atomically across clones) and /v1/cycles/decisions (the append-only authority-decision store).
/v1/runtime/*Authorized project members and registered runnersGoverned dispatch attempts, leases, supervision events, cancellation, and reconciliation.
/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/marketplaceDiscoverability landing (local). Install from ./web/dist/marketplace or GitHub.
http://localhost:8080/cli/*The local web/dist/cli/
http://localhost:8080/docs/user-guide.htmlThe local web/dist/docs/
http://localhost:8080/docs/getting-started.htmlStandalone onboarding from the 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 · 33

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/sessions/revoke-all and revokes every active session for the caller's UPN.

What's next

Reference · 34

Permissions Reference

Diataxis category: Reference — information-oriented.

Two axes determine what you can do: whether your Entra identity carries the global synaptory-admins role and your project-level role on each project (member / admin). The legacy synaptory-users group is not a sign-in gate.

For the conceptual model and where checks happen, see Identity and access.


Entra group → platform-level capabilities

CapabilitySigned-in non-adminsynaptory-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✗✓

Any valid tenant identity can sign in. synaptory-admins adds global administration; project data still follows server-side project scope.


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 · 35

Glossary

Diataxis category: Reference — information-oriented.

This glossary uses the current SPQ-first vocabulary. Scrum and Kanban terms remain only where compatibility behavior still exists.


Lifecycle and hierarchy

TermDefinition
SPQThe proper name of Synaptory's primary governed delivery method. Its lifecycle is four stages -- Discovery, Cycle, Acceptance, Complete -- and Commit / Sync / Checkpoint are recorded events, not stages.
ProjectThe durable product or service boundary governed by one Synaptory configuration.
EngagementOne project's whole delivery: the approved baseline, the shared trunk, and every Acceptance. Ended by the final Acceptance and nothing else.
CycleThe SPQ delivery unit and the only unit of parallelism: a scope-defined set of Work Units sealed at Commit, executed and proved, integrated to the shared trunk at its barrier, and demonstrated at Checkpoint. One Engineering Lead, one Crew, one repository.
Work UnitThe smallest governed unit of delivery. It carries its own dispatch, attempts, evidence, acceptance state, and its declared path scope.
DiscoveryRequest, analysis, and the first planning work that produces a proposed baseline. It ends at human baseline approval, which includes a measured calibration sample -- a git sha and a boolean do not satisfy it.
CommitThe event that opens a Cycle by sealing a non-empty admitted set. The seal is what closes the set, not the event: nothing joins a Cycle afterwards.
SyncThe event recording that one Cycle waited on a result from another and how it cleared. It has zero or more occurrences and blocks nothing. What blocks a Work Unit is an unsatisfied dependency. This entry previously read "the cross-workstream integration barrier", which is exactly what SPD-194 retires.
BarrierThe all-or-nothing mechanical condition a Cycle must meet to close, evaluated over the admitted set minus recorded cuts. Its criteria are published at Commit from one constant. It lives at Checkpoint, not at Sync.
CheckpointThe event recording the demonstration, the barrier verdict, the integrated trunk revision and the cut list.
CutThe one valve. Withdrawing unfinished work from a Cycle with an explicit reason, a backlog return and a key a later Commit can name. It never moves the approved baseline.
Source regionThe repository-relative paths a Cycle may address. Overlapping regions are refused at declaration, which is what lets concurrent Cycles stay independent.
Path scopeThe paths one Work Unit may change. Required at admission. Intersecting scopes are refused unless each declares a distinct execution_order; disjoint work proceeds with no enablement.
CrewThe people and agents seated on one Cycle. It grants nothing and is re-seatable between Cycles without changing a single barrier admission.
Engineering LeadThe accountable human named per Cycle. A role decides who may be named and confers no reach.
TrunkThe one shared branch a Cycle integrates into at its Checkpoint. A Cycle that closes having integrated nothing anyone else can see has not closed.
AcceptanceA go-live: its own evidence package and its own human decision. Repeatable -- delivery continues in another Cycle meanwhile. Only the final Acceptance closes the engagement and records the handover.
ReleaseA governed promotion. A human gate, not an automatic consequence of Acceptance.
Scrum / KanbanLegacy compatibility lifecycles. Existing projects may finish or migrate, but new guidance and runtime federation target SPQ.

Retired terms

Recorded rather than deleted, because they appear in receipts, gate events and sealed declarations from before SPD-194 and a reader of an archived record needs to know what they meant and what replaced them.

Retired termMeantRead instead
WorkstreamA durable lane within a Cycle, with its own branch and readiness recordNothing. The Cycle is the unit; a Work Unit's path scope carries what the lane's file ownership carried, and a Crew carries the staffing without the durability
Coordination CycleA parent grouping child Cycles, pinning each child's SHA and composing release readinessNothing. It existed only because integration was deferred; with the barrier integrating to trunk at Checkpoint there is nothing downstream to gather
Cycle of CyclesFolk term for the same parent layer. Never entered the methodNothing
Integration seat / integration workstreamA barrier seat outside the delivery quorumNothing. There is one board per Cycle and one barrier over it
Sync as barrierThe all-or-nothing integration gateThe barrier at Checkpoint. Sync is a record of a dependency having cleared

Hosts and runtimes

TermDefinition
HostThe interactive coding environment in which the user invokes Synaptory: Claude Code, Codex, or Cursor.
Host adapterThe integration that maps a host's instructions, skills, hooks, agents, and MCP support onto Synaptory governance.
RuntimeAn agent execution engine used for one governed attempt. A runtime may be the same product as the current host or a different approved engine.
Runtime federationOptional SPQ-only routing of Work Units across certified runtime profiles. It must be explicitly configured.
Runtime familyThe underlying execution product, such as claude-code, codex, or cursor.
PlacementWhere a runtime executes, currently local or managed-laptop in the pilot profiles.
Adapter profileA certified combination of runtime family, placement, pinned version, capability profiles, and capability ceiling.
Capability profileA skill-composition label—analyst, planner, producer, or prover. It grants no authority.
Stage profileOne of the seven obligation locations: admitting, analysing, planning, producing, verifying, releasing, or operating.
Capability ceilingThe maximum tools, network scope, filesystem access, and other authority a runtime attempt may receive.
Dispatch envelopeThe immutable, validated instruction for one attempt: identity, lifecycle binding, role, profile, budget, authority ceiling, required evidence, expiry, and receipt path.
AttemptOne execution of a Work Unit through a runtime adapter. Retries create distinct attempts without rewriting history.
RunnerA registered machine able to serve one or more runtime profiles under a lease.
Lease / fencingControl-plane mechanisms that grant temporary ownership of work and reject stale workers after ownership changes.

Governance and evidence

TermDefinition
Canonical stateThe authoritative lifecycle record. Conversation text and runtime-native session state are not canonical.
ReceiptStructured evidence returned by an agent or runtime attempt, including artifacts, verification commands, metrics, identity, and completion metadata.
EvidenceVerifiable proof required by a Work Unit or gate: tests, commands, artifacts, reviews, approvals, or policy-specific records.
Definition of Done (DoD)Project-level quality requirements that are incorporated into SPQ evidence policy. Legacy modes also use story/sprint DoD terminology.
Dispatch kernelThe governance boundary that validates state, policy, authority, runtime eligibility, and idempotency before issuing an envelope.
Advance kernelThe governance boundary that validates the attempt and its evidence before advancing a Work Unit. A runtime cannot advance itself.
Human gateA decision that automation may prepare but cannot approve: baseline approval, the admitted set at Commit, a cut, the Checkpoint close, and Acceptance / completion. Sync is not one -- it records a dependency having cleared and authorizes nothing.
IdempotencyRepeating the same authorized request does not create duplicate canonical transitions.
Append-only historyPrior lifecycle events and attempts remain auditable rather than being overwritten.
Fail closedIf authority, policy, state, or evidence cannot be established, Synaptory stops instead of silently weakening the rule.

Product and identity

TermDefinition
PluginA host-specific Synaptory distribution. Claude Code, Codex, and Cursor packages share lifecycle semantics but use host-native integration mechanisms.
CLIThe standalone synaptory binary used for authentication, policy/skill sync, diagnostics, telemetry, and the Runtime Bridge.
Control PlaneThe Synaptory web application and API for projects, Cycles, Acceptances, attempts, supervision, policy and administration -- plus the two records that must sit outside the executing agent's reach: the source-region registry and the authority-decision store. A process-local lock cannot be atomic across clones.
MCPModel Context Protocol. Codex and Cursor use Synaptory MCP tools for governed lifecycle operations.
UPNUser Principal Name from the configured Entra identity.
Tracker adapterAn optional integration for local or remote issue/project tracking. Trackers mirror delivery work; they do not replace canonical SPQ state.
Engagement modestructured or interactive; controls how much autonomy Synaptory uses between required human gates.
Healthcare mode (HC0)A regulated operating profile that requires the relevant enterprise agreement, BAA coverage, privacy settings, eligible models, and policy. It is not enabled by a local flag alone.

Compatibility role abbreviations

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

See Agents for how roles participate in SPQ.

Reference · 36

Troubleshooting

Start with the smallest read-only check that can identify the failing layer. Do not edit canonical lifecycle files or invoke internal hook/state-machine modules to force progress.


Fast triage

Run from the project root:

synaptory whoami
synaptory status
synaptory runtimes doctor

Then ask the active host:

Run Synaptory doctor and show the current canonical Cycle.

Interpret the layers independently:

LayerHealthy signal
CLI and identitywhoami shows the expected UPN and an unexpired session.
Projectprojects current resolves the expected project.
Host integrationThe Synaptory entry point loads and lifecycle tools are visible.
Canonical lifecycleThe host can read the current Cycle, stage, gates, and Work Units.
Runtime federationEvery required profile is ready; optional profiles may be not-ready.

Installation and host issues

The Synaptory entry point is missing

  • Claude Code: confirm the marketplace and plugin are installed, then restart the session.
  • Codex: confirm the plugin is installed/enabled and Codex is 0.147.0 or newer.
  • Cursor: confirm project rules, skills, agents, hooks, and MCP configuration were installed into the project.

Re-run the relevant steps in Getting Started.

Claude Code starts but hooks cannot find the CLI

Run:

command -v synaptory
synaptory version

Restart Claude Code after installing or updating the CLI so its environment sees the new PATH.

Codex cannot run the SPQ lifecycle

Check all of the following:

  • Codex version is at least 0.147.0;
  • the Synaptory plugin is enabled;
  • the Synaptory MCP server is visible;
  • no more than four total live threads exist, including the parent;
  • the request is standard non-regulated SPQ work.

Codex is not currently a certified host for regulated SPQ or cross-host handoff.

Cursor headless cannot start governed work

Treat missing MCP tools as a failed preflight. Do not continue from remembered chat state. Fix MCP configuration/tool discovery and start a new governed attempt.

For HC0 work, also verify the organization's Enterprise/BAA, Privacy Mode, network, and eligible-model requirements. A successful local command does not prove compliance.


Authentication and project access

Browser sign-in did not open

Use device flow:

synaptory login --device

Session expired or sign-in is requested repeatedly

synaptory login
synaptory whoami

If the cached identity is not the intended account, run synaptory logout and sign in again.

Project not found or access denied

synaptory projects list
synaptory projects current

Confirm the project_id in .synaptory.yaml and ask a project administrator to verify membership. Authentication proves identity; project membership is authorized per request.

Skills or policy are stale

synaptory skills sync
synaptory config fetch --if-stale
synaptory config env

Restart the host session after a material plugin or policy update.


SPQ lifecycle issues

No active Cycle exists

First confirm the project is configured for SPQ:

schema_version: "1.0"
build_mode: spq

Then ask the host to start a Cycle with a bounded outcome. Initialization and Cycle creation are separate operations.

The Cycle appears stuck

Ask for the canonical state and the exact unmet prerequisite:

Show the current Cycle, stage, open gate, pending Work Units, and missing evidence.

Common legitimate pauses are:

  • Shape is waiting for Sync approval;
  • a dependency prevents a Work Unit dispatch;
  • Checkpoint evidence is incomplete or invalid;
  • Acceptance is waiting for a human decision;
  • Release has not been explicitly approved.

Do not edit .synaptory/ state files or run internal transition scripts. Correct the evidence or make the required human decision through the host adapter.

A Work Unit failed repeatedly

Inspect the attempt rather than overwriting it:

synaptory runtime status --attempt <attempt-id>
synaptory runtime explain --attempt <attempt-id>

Identify whether the cause is a capability refusal, missing dependency, budget ceiling, runtime death, invalid receipt, verification failure, or human decision. A governed retry creates a new attempt and preserves the prior evidence.

Receipt or Checkpoint validation fails

The failing report should name missing fields, artifacts, or verification evidence. Re-run the bounded producer/prover work or correct the artifact, then run Checkpoint again. Switching engagement mode may change how the problem is presented; it does not turn invalid evidence into valid evidence.

Canonical state and host conversation disagree

Canonical state wins. Start a fresh turn/session, re-read the Cycle through the host adapter, and resume from the recorded stage. Never reconstruct lifecycle state from a summary or manually “catch up” the files.


Runtime federation issues

A profile is listed but not-ready

runtimes list shows recognized profiles; it does not prove the underlying runtime is installed. Run:

synaptory runtimes doctor --profile <profile-id>

Follow the reported version, executable, placement, or policy remediation. Keep optional profiles optional; do not lower the Work Unit's capability requirement merely to make a runtime eligible.

Runtime policy has no effect

Confirm all three conditions:

  1. build_mode: spq is active;
  2. .synaptory.yaml contains a valid runtimes: block; and
  3. the relevant capability profile maps to a certified adapter profile.

Runtime routing is deliberately inert in Scrum and Kanban compatibility modes.

Cancellation says “recorded locally only”

The local attempt record was updated, but the command could not prove delivery to the control plane/worker. Do not claim that the remote runtime stopped. Check supervision state, restore connectivity, and issue a governed follow-up from the machine or control-plane surface that owns the lease.

Runtime output exists but the Work Unit did not advance

Runtime success is not lifecycle acceptance. Check the receipt, required evidence, manifest binding, and Checkpoint result. Only the advance kernel can complete the Work Unit.


Configuration issues

Configuration is not detected

Confirm .synaptory.yaml is at the project root from which the host was opened:

ls -l .synaptory.yaml
synaptory projects current

Unexpected Scrum or Kanban behavior

The compatibility default may still apply when build_mode is omitted. Set it explicitly:

build_mode: spq

For an existing legacy project, follow Migrate to SPQ instead of rewriting its historical state.

Tracker updates fail

Confirm the provider credentials and project/team identifiers documented in Configuration. A tracker is a projection of delivery work; a tracker outage must not be repaired by fabricating a canonical SPQ transition.

For GitHub, distinguish network failure from credential rejection before re-authenticating: remove accidental GH_TOKEN/GITHUB_TOKEN overrides, verify connectivity, then treat only a real GitHub 401 Bad credentials response as an authentication failure.


Control Plane and telemetry

Control Plane data looks stale

synaptory outbox list
synaptory outbox flush

Then refresh the relevant Cycle or attempt. A queued outbox affects observability; it does not authorize a local lifecycle transition.

A control did not complete

Read the UI result carefully. If the page says the request was not sent or not confirmed, assume no state change occurred. Re-read canonical state before retrying so idempotency keys and lease ownership remain valid.


Legacy project issues

Scrum and Kanban remain compatibility paths while retirement is planned. Existing project troubleshooting is preserved in the legacy guide pages, but new Work Units and runtime federation should move to SPQ.


Reporting a product issue

Capture:

  • host and version;
  • synaptory version and synaptory status output with secrets removed;
  • project and Cycle/Work Unit/attempt identifiers;
  • the exact failed operation;
  • the displayed error and whether canonical state changed;
  • synaptory runtimes doctor output when runtime federation is involved.

Then ask Synaptory to submit a support report or use synaptory report submit. Do not attach tokens, runtime credentials, or sensitive source content.

If the report fails to send

The control plane relays the report to GitHub, so a submit can fail for reasons on our side: an expired credential, a GitHub incident, an unreachable control plane, or a session that needs synaptory login. Your text is not lost. A failed submit writes it to ~/.synaptory/.failed-reports/ (or ~/.synaptory-local/.failed-reports/ for the local build) and the error names the two files it wrote:

  • <timestamp>-<project>-<title>.md is the report body on its own, ready to

open or attach to an email;

  • <timestamp>-<project>-<title>.json is the whole request, which you can

replay once the relay is back:

synaptory report submit --json ~/.synaptory/.failed-reports/<file>.json

Nothing deletes these files, and nothing retries them in the background. They stay until you file the report or remove them yourself. If the error says the report could not be preserved, copy it out of your terminal before closing the session.

If retrying keeps failing, send the .md file to support@h3t.co. Do not try to file the issue on GitHub yourself: the issues repository is private, which is the reason the control plane relays reports in the first place.

H3T staff only. You do have filing rights, but not through a bare gh. The local identity guard refuses a mutation on an h3tech-ai repository with exit status 13. Filing a defect is the "Prove" authority class, so hand the saved body to the role-bound wrapper:

h3t-gh-tester issue create --repo h3tech-ai/synaptory-v1 \
--title "<title from the .json>" \
--body-file ~/.synaptory/.failed-reports/<file>.md

Note this loses the server-side UPN / project / session stamp the relay adds, so say in the body who hit it and on which project.