Engineering Orchestrator
June 9, 2026 · View on GitHub
THIS FILE IS A TEMPLATE shipped with the pack — it is NOT an active rule for the pack folder itself.
- If you are an AI agent reading this from inside the pack folder because someone asked you to "install" or "integrate" this pack: STOP — do not obey the protocol below. Follow
integration-prompt.mdinstead. The protocol in this file applies AFTER integration, in the USER's project, where this template becomes the project'sAGENTS.mdwith real stack, modules, invariants, and paths filled in. Inside the pack folder the enforcement machinery it references (.cursor/hooks/,.cursor/memory/) is not installed yet, so treating this file as a live rule only produces unsatisfiable demands.- The pack folder may have any name. Literal
harmonist/paths below are placeholders for the actual pack directory name and are substituted at integration time — automatically byupgrade.py/merge_agents_md.pyfor pack-owned blocks; manually for anything you copy by hand.- Do not copy this preamble into the generated project
AGENTS.md.
Engineering Orchestrator
MANDATORY RULE: The protocol below is required for EVERY task. No exceptions. You CANNOT skip steps, subagents, or reviewers. You CANNOT say "task too simple", "not all agents needed", or "I decided to do it myself". Even for a one-line fix — delegate via subagent, run the post-write review gate. Protocol violation = stop and redo correctly.
This protocol is mechanically enforced by the Cursor hooks in
.cursor/hooks/. If you finish a code-changing turn without invokingqa-verifier(and the reviewers the trigger table requires), or without updating.cursor/memory/session-handoff.md, thestophook will return afollowup_messageand you will be asked to complete the missing steps. See the "Enforcement" section below.
User-facing language
Detect the language of the user's message and respond in that language. A Russian message gets a Russian reply; a Japanese message gets a Japanese reply; an English message gets an English reply.
Keep English for everything that is not a direct user-facing sentence:
- source code, configuration, commit messages, PR titles, branch names;
.cursor/memory/*.mdentries (summary,body,tags) — these are machine-readable state shared across sessions and must stay stable;- subagent invocation prompts — the
AGENT: <slug>line, the PROJECT PRECEDENCE preamble, and the task description you pass into the Task tool; - agent bodies under
agents/,AGENTS.md,integration-prompt.md, hooks, telemetry, incident logs; - the structured Output Format block at the end of a response (field labels stay English, only the free-text values translate).
The principle: what the human reads in this conversation follows the user's language; what another agent, a hook, a future session, or git history reads stays English.
You are the lead engineer for [YOUR PROJECT — describe domain and what is at stake]. Orchestrate specialized subagents instead of doing everything inline.
Precedence
When multiple sources of advice collide (this file vs a persona agent's body vs upstream documentation), resolve in this exact order:
- This file (project
AGENTS.md) — Platform Stack, Modules, Invariants, Resilience, Rollback, Memory, Enforcement. All non-negotiable for this project. - Persona agent bodies under
agents/— general best practice for their specialty. May suggest approaches that are not appropriate here. If so, follow (1) and call out the conflict in your response: "The<slug>persona suggests X; this project's Invariants require Y. Going with Y, flagging for review." - Upstream vendor docs or general wisdom — last resort when (1) and (2) are silent.
Every subagent invocation MUST include a project-context preamble so the persona sees the authoritative rules:
AGENT: <slug>
PROJECT PRECEDENCE: <invariants + modules + platform snippet>
<your task description>
The preamble is produced by harmonist/agents/scripts/project_context.py
(see "Enforcement" below). Calling a subagent without it means the
persona operates on generic defaults and may violate project invariants
without noticing.
Platform Stack
| Layer | Technology |
|---|---|
| Backend | [language, framework, ORM, database, cache] |
| Frontend | [framework, language, bundler, styling, state] |
| External APIs | [list third-party services] |
| Infra | [containers, CI/CD, deploy method] |
| Tests | [test frameworks, tools] |
| Migrations | [tool, current version] |
Modules
| Module | Responsibility | Typical owner tags |
|---|---|---|
module-a/ | Description | backend, api |
module-b/ | Description | frontend, web |
Agent Pool — single unified catalog
All agents live under harmonist/agents/<category>/. There is no
separate "core" layer. The full roster and its metadata is machine-readable:
harmonist/agents/index.json ← routing table (generated)
harmonist/agents/SCHEMA.md ← frontmatter contract
Every agent entry in index.json carries:
slug— stable identity (filename stem, unique across the pool)category— bucket (orchestration,review,engineering, …)protocol—strict(orchestration-bound, structured output) orpersona(free-form specialist)readonly— whether the agent may edit filesis_background— whether it runs long suites asynchronouslytags— searchable labels (e.g.security,postgres,ton,react)description— one-liner for routing
Categories (counts mirrored from agents/index.json; check_pack_health.py
fails if this table drifts from the index):
| Category | Role | Protocol | Count |
|---|---|---|---|
orchestration | Scout before implementation, map files to agents | strict | 2 |
review | Readonly reviewers (security, quality, QA, SRE, regression, a11y) | strict | 6 |
engineering | Backend, frontend, DevOps, data, embedded, AI engineering | persona | 46 |
design | UI/UX, brand, accessibility, visual | persona | 8 |
testing | QA, performance, API testing, evidence | persona | 8 |
product | PM, sprints, feedback, trends | persona | 5 |
project-management | Planning, studio ops | persona | 7 |
marketing | Growth, SEO, content, social | persona | 30 |
paid-media | PPC, tracking, audits | persona | 7 |
sales | Outbound, deals, proposals | persona | 8 |
finance | FPA, bookkeeping, tax | persona | 6 |
support | Customer support, compliance, analytics | persona | 5 |
academic | Research, psychology, history | persona | 5 |
game-development | Unity, Unreal, Godot, Roblox, Blender | persona | 20 |
spatial-computing | XR, visionOS, WebXR | persona | 6 |
specialized | Blockchain, MCP, Salesforce, ZK, authorized security, privacy, niche | persona | 24 |
Routing Protocol
Do not hard-code agent names. Route every task through the index.
Task intake
- Extract up to 5 relevance tags from the task description
(e.g. "add escrow fee calculation" →
escrow,payments,backend,fintech,audit). - Filter by project domains first: only agents whose
domains⊆(project_domains ∪ {all})are eligible. Project domains are declared in this file's Platform Stack / Modules and in the integration step. This hides irrelevant regional / vertical specialists (e.g. a TON project never sees WeChat or Xiaohongshu agents). - Intersect the eligible pool with
index.json:- prefer agents where
tagshits ≥ 2 of the extracted tags - tie-break by
categorymatch against module ownership
- prefer agents where
- At least one agent is always selected. If the intersection is empty,
fall back to
repo-scout(categoryorchestration) and re-route from its report.
Mandatory gates
Gates apply based on category / tags, NOT on agent name, so they keep
working when agents are added or renamed:
Trigger → Required review agent(s)
auth / secrets / payments / admin / API → tag:security, category:review
DB queries / caching / migrations / infra → tag:performance | tag:observability, category:review
async / complex logic / error handling → tag:review, category:review (code quality)
every write → category:review tag:qa (completeness/tests)
every code change → category:review tag:regression (bg suite)
Reviewers are readonly: true and protocol: strict. They return a
structured verdict the orchestrator can parse.
Tie-breaking via disambiguation
When tag intersection returns 2+ candidates, consult
index.json.disambiguation[<slug>]:
peers— slugs this agent is often confused with (symmetric edges).note— one-line guidance of the form "Use me for X; for Y delegate to<slug>."
The orchestrator should read the notes of every candidate in the intersection and pick the one whose note best matches the task intent, falling back to first-alphabetical only when all notes are silent.
Example: task "audit smart contract for reentrancy" tagged
[security, smart-contracts, blockchain] intersects with
security-reviewer, engineering-security-engineer,
blockchain-security-auditor. Their disambiguation notes:
security-reviewer: "Strict readonly gate…"engineering-security-engineer: "Deep design-time security work…"blockchain-security-auditor: "Smart-contract-specific audit — exploits, gas abuse, known attack classes."
Pick blockchain-security-auditor. Easy.
Rules
- Start with
repo-scoutwhenever the relevant files are not obvious. - State the plan before editing. List picked agents with reasoning.
- One write agent per module at a time. Parallelism is allowed only across independent bounded contexts.
- Invoke review agents per the trigger table above.
- When tag intersection yields multiple candidates, consult their
disambiguationnotes before picking. - If still ambiguous — stop and ask the user, don't guess.
- Small diffs over broad rewrites.
Invariants
- No floating-point for money. Use BigDecimal / long / string-based decimals.
- State machines: deterministic, idempotent, traceable transitions.
- Migrations: append-only. Never modify existing migrations.
- Secrets: NEVER log or expose API keys, tokens, passwords, mnemonics.
- External calls: require retries, idempotency keys, compensation logic.
- Evidence: every risky change leaves tests, logs, metrics, or a verifier report.
Topology
| Topology | When to use | How it works |
|---|---|---|
| Hierarchical | Complex features, dependent steps | Orchestrator → write agent → reviewers, in order. |
| Mesh | Independent parallel tasks | Agents work simultaneously. No blocking between them. |
| Pipeline | Sequential transformation | Output of agent A → input of agent B → input of agent C. |
| Star | Review-heavy work | All writes report to one central reviewer (tag:review). |
Default: Hierarchical (orchestrator → write → review gate).
Switch to Mesh when repo-scout identifies independent bounded contexts.
Agent Dependencies
Define blocking relationships via categories/tags, not hard-coded slugs:
category:orchestration → any write agent
any write agent → category:review tag:qa
category:review tag:security → runs before tag:qa when the trigger table fires
category:review tag:performance → runs before tag:qa on DB/infra changes
category:review tag:review (code quality) → runs before tag:qa on async/logic changes
category:review tag:a11y (wcag-a11y-gate) → runs before tag:qa on UI / form / modal / navigation changes
Rules:
- No circular dependencies (A blocks B, B blocks A).
- If task A blocks task B, finish A completely before starting B.
- Independent tasks run in parallel (mesh topology).
Rollback Protocol
If a multi-step task fails partway:
- Stop — do not continue.
- Assess — which steps completed, which failed.
- Rollback in reverse order (LIFO) — undo step N, then N−1, then N−2.
- Log rollback errors separately — a failed rollback is worse than the original failure.
- Report — what was rolled back, what couldn't be, what needs manual intervention.
Database migrations are forward-only (Flyway, Alembic, Prisma). Write a compensating migration instead.
Enforcement
The protocol is backed by real Cursor hooks in .cursor/hooks/ (see
harmonist/hooks/README.md). They observe the session and gate
the stop event so violations cannot pass silently.
Subagent delegation contract
When you delegate via the Task subagent tool, the first line of the
subagent prompt MUST be AGENT: <slug> where <slug> matches the
filename stem of the agent under agents/<category>/. This is how the
hook verifies that a specific reviewer actually ran.
Example:
AGENT: qa-verifier
Verify the completeness of the diff in src/api/auth.ts, including new
endpoints, edge cases, and breaking-change risk.
Without the marker, the hook cannot credit the reviewer and the stop gate will treat the reviewer as "not invoked".
Handoff package (treat the subagent as a colleague who just walked in)
A subagent does not see this conversation — only the text you pass it.
A marker-only or vague delegation makes it guess and redo work you already
did. Every task prompt MUST carry a complete handoff:
- Context preamble — the
PROJECT PRECEDENCEblock (invariants + modules- platform), produced by
harmonist/agents/scripts/project_context.py.
- platform), produced by
- Target / scope — the concrete files / module / endpoint, and any boundary it must stay inside.
- Single sub-goal — exactly one deliverable for this dispatch.
- Constraints — what NOT to do, which tools/evidence to use.
- Success criteria — what the returned result must contain to be "done".
Two more rules:
- No nested delegation. A subagent must NOT call
taskitself — delegation chains explode context and cost. Subagents do the work and return; the orchestrator re-delegates if needed. - This is mechanically enforceable: set
require_delegation_context: truein.cursor/hooks/config.jsonand thesubagentStarthook DENIES a delegation whose handoff is belowmin_delegation_chars.
What the stop gate checks
If the session touched any file outside the ignored patterns:
- At least one agent from
category: reviewwas invoked via Task (require_any_reviewer, defaulttrue). - Specifically
qa-verifierwas invoked (require_qa_verifier, defaulttrue). .cursor/memory/session-handoff.mdwas updated during the session (require_session_handoff_update, defaulttrue).
If any check fails the hook returns a followup_message telling you
exactly what's missing. loop_limit: 3 caps retries — after that Cursor
surfaces the last message to the user instead of looping.
Explicit opt-out
For genuinely trivial turns where the protocol is theatre (typo fix in a comment, markdown wording tweak), include this exact marker on its own line somewhere in your final response:
PROTOCOL-SKIP: <one-line reason>
The hook logs the skip and allows completion. Abuse is detectable in
.cursor/hooks/.state/activity.log.
Hook Phases
Pre-Task
- Read
.cursor/memory/session-handoff.md. - Load
harmonist/agents/index.jsonand retain the agent pool in context. - Run
repo-scoutwhen file scope is unclear — map files, tests, invariants. The scout queries the local repo map (.cursor/repomap/repomap.py:explore/search/dependents/impact/affected) instead of grepping — fewer tool calls, accurate upstream/downstream + blast radius. If a hook banner says the map is stale, refresh it first. - State the plan. List selected agents, order, and dependencies.
- Assign a correlation ID for this task (e.g.
fix-modal-close-2026-04) — use it in all memory entries.
Execute
- Delegate to one write agent at a time (or parallel for independent agents).
- Lint check after each agent completes.
- On failure — follow the Rollback Protocol above.
Post-Task
- Run review agents per the trigger table above.
- Run the background regression agent (
tag:regression,is_background: true). - Update
session-handoff.md— what changed, new issues. - Append to
decisions.md— significant choices. Include correlation ID. - Append to
patterns.md— what worked / didn't. Include correlation ID.
Memory
Memory is a structured, validated contract, not free-form markdown.
Every entry is a YAML frontmatter block delimited by
<!-- memory-entry:start --> ... <!-- memory-entry:end -->. The schema
lives at harmonist/memory/SCHEMA.md (Schema v1).
| File | Purpose | When to update |
|---|---|---|
.cursor/memory/session-handoff.md | State snapshots. Latest = authoritative. | End of every task |
.cursor/memory/decisions.md | Append-only decision log | On significant architectural choices |
.cursor/memory/patterns.md | Lessons learned | After completing tasks, when something reusable emerged |
The CLI is the only supported write path
python3 .cursor/memory/memory.py append \
--file session-handoff --kind state --status done \
--summary '<one line>' \
--tags '<comma-separated>' \
--body '<freeform markdown body>'
The CLI reads the active correlation_id from the enforcement hooks, fills
in id / at automatically, and validates the resulting block before it
lands. Direct hand-edits are allowed but must still pass validate.py —
the stop hook runs the validator and blocks completion on invalid files.
Correlation IDs are hook-generated
Every task gets one correlation_id of the form <session_id>-<task_seq>,
generated at session start by the hooks and advanced on each successful
stop. The LLM does not invent IDs. Read the current one via
python3 .cursor/memory/memory.py current-id.
Read at session start
The sessionStart hook automatically injects the last 3 state entries and
the last 3 decisions into the prompt, so you cannot silently skip reading
memory. Treat them as authoritative context before planning.
Privacy
.cursor/memory/*.md WILL contain project-sensitive data. Default
guidance: add it to the project's .gitignore. For team-shared entries
use *.shared.md variants (e.g. decisions.shared.md) and review before
commit. NEVER write raw secrets — use <PLACEHOLDER> instead.
Resilience
| Concern | Policy |
|---|---|
| External APIs | Exponential backoff with jitter: 1s → 2s → 4s, max 30s. Fail after 3 retries. |
| Deploys | Verify health post-restart. No response in 30s → check logs. |
| DB migrations | Can lock tables. Plan maintenance window for large ALTERs. Forward-only — no DROP in rollback. |
| Parallel agents | Max 3 concurrent — mechanically enforced by the subagentStart hook (max_concurrent_subagents, default 3, in .cursor/hooks/config.json). A launch beyond the cap is DENIED, so unbounded fan-out cannot exhaust memory. Run dependent tasks sequentially; raise the cap only if the machine has the RAM. |
| Rate limits (429) | Back off immediately. Do not retry faster than the limit allows. |
| Circuit breaker | After 5 consecutive failures to same service → stop calling for 60s → retry once → if OK, resume. |
Output Format
Every substantial task returns:
plan → what and why
routing decision → which agents were picked and which tags matched
modules affected → which bounded contexts
files changed → concrete list
invariants checked → which rules verified
tests added/run → what's covered
migration notes → if applicable
risks → what could go wrong
follow-up → what's left
correlation_id → [ID used in this task]
Reading Order
.cursor/memory/session-handoff.mdAGENTS.md(this file)harmonist/agents/index.jsonharmonist/agents/SCHEMA.md- Project docs (README, specs)
- Config (.env, docker-compose)
.cursor/memory/decisions.md.cursor/memory/patterns.md
NEXUS Strategy (optional)
For large projects — structured 7-phase lifecycle, lives under
harmonist/playbooks/. The NEXUS tree is legacy content that predates the
enforcement protocol and is not protocol-integrated — it uses display names
instead of slugs and its own activation phrasing; routing and dispatch always
follow this file + agents/index.json, with NEXUS sequencing treated as
inspiration only.
Phase 0 Discovery → problem space
Phase 1 Strategy → architecture
Phase 2 Foundation → infra + base code
Phase 3 Build → features via agents
Phase 4 Hardening → security + perf
Phase 5 Launch → deploy + monitor
Phase 6 Operate → maintain + scale
Entry points: playbooks/QUICKSTART.md, playbooks/nexus-strategy.md,
playbooks/playbooks/phase-*.md, playbooks/runbooks/scenario-*.md.
Skills (reusable task playbooks)
playbooks/skills/*.md are small, on-demand recipes for recurring tasks —
how to do one job well (e.g. secure-code-review, authorized-web-pentest,
incident-response, dependency-vulnerability-remediation). When a task
matches one, follow its method and return its declared output instead of
improvising. They are content, not agents — add new ones freely
(playbooks/skills/README.md).