Agents
An agent is a single, ephemeral Claude Code worker — claude -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>
- Fetches the ticket from Jira and builds a brief prompt.
- Moves the ticket to In Progress.
- Runs the worker in the workspace:
claude -p --setting-sources project,local --permission-mode acceptEdits "<brief>". - Commits only the files the worker changed, to the local
devbranch of each owned repo. - 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:
coreagent →https://core-dev.syntec-one.nl/api/v1/mcp/structurecrmagent →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 atomic — manifest.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.