Skip to content

Agents

An agent is a single, ephemeral Claude Code workerclaude -p (headless) — launched by agent-run inside a project workspace to carry out one Jira ticket. It edits files, and (when the ticket needs it) authors platform structure via an MCP. It never pushes; agent-approve does that after a human approves.

How a worker runs

agent-run <PROJECT_KEY> <ISSUE_KEY>
  1. Fetches the ticket from Jira and builds a brief prompt.
  2. Moves the ticket to In Progress.
  3. Runs the worker in the workspace: claude -p --setting-sources project,local --permission-mode acceptEdits "<brief>".
  4. Commits only the files the worker changed, to the local dev branch of each owned repo.
  5. Moves the ticket to In Review and posts the Slack Approve/Reject card.

Isolation from interactive sessions

The same claude user also runs interactive Claude Code sessions (with a full plugin set: superpowers, claude-mem, and more). Those plugins' hooks would otherwise fire in every headless run too. The worker avoids that with --setting-sources project,local, which loads only project/local settings and skips the user-level plugins — keeping automated runs lean and deterministic while preserving auth. (The --bare flag is not used: in the current build it also drops the OAuth credentials.)

Authoring platform structure (the structure MCP)

Tickets that change platform metadata — add an entity, field, view, form, or menu item — shouldn't be hand-written DDL. agent-run gives the worker a per-environment structure MCP:

  • core agent → https://core-dev.syntec-one.nl/api/v1/mcp/structure
  • crm agent → https://crm-dev.syntec-one.nl/api/v1/mcp/structure

It's wired with --mcp-config + --strict-mcp-config (only that one MCP loads) and --allowedTools mcp__syntec-structure (so the tools run without a prompt). The service token is minted per environment with bin/agent-structure-token <project> (1-year JWT, stored at state/structure-token-<project>.jwt).

From the DB to git (the export bridge)

The structure MCP writes the live dev database. Git only tracks the package's JSONL files, so a metadata change has to be exported to become committable. After the worker runs, agent-run runs:

syntec:package:export <package>     # core → base, crm → crm

and its normal commit step picks up the resulting JSONL diff.

The drift guard

A package is atomicmanifest.json hashes every file together — so a clean commit is only possible when the dev DB matches the committed package. If the export diff touches non-structure config/data files (syntec_config, syntec_config_lng, syntec_email_template — runtime values the structure MCP never authors), agent-run treats it as dev-DB drift: it reverts the whole export and flags it in the review rather than committing unrelated changes. Keep dev databases in sync with their committed package, or structure tickets get skipped-and-flagged.

What the reviewer sees

The Jira comment and Slack card summarise the worker's output and list the local commits (repo, short SHA, files). Approving pushes them; rejecting reverts them. Nothing is on origin/dev until you Approve.