2026-05-14-prompt-service-architecture
title: Prompt service architecture — eva-hq authors, petrova.host serves, consumers fetch via MCP date: 2026-05-14 status: ratified mr_compliance: [MR-7, MR-12] supersedes:
- parts of 2026-05-13-petrova-onboarding-flow-v2.md (the “core/prompts/00-bootstrap.md (canonical in eva-hq)” sourcing claim) superseded_by: none — current
Context
Section titled “Context”Operators onboarding new consumer repos kept hitting the same friction: the bootstrap
agent inside a freshly-installed consumer (e.g. asgard) would try to “emit a
chosen_prompt”, fail to find a local prompts/ directory, and halt with a
ground-truth-style refusal. The CLAUDE.md in petrova-codes told a story where
eva-hq was canonical for prompts, but the bodies themselves lived in the
core/prompts/ submodule (downstream of petrova-codes/prompts.git), and a
re-vendored copy of META-RULES.md + 00-bootstrap.md lived in-tree at
core/playbook/ for installer convenience. Three surfaces, manual sync,
inconsistent authoring story. The dashboard’s /console/prompts page
additionally looked like a fourth duplicate even though it was a live view.
Trigger: operator screenshot (“seeing prompts in three places, pick a strategy and lock it in”), 2026-05-14.
Decision
Section titled “Decision”eva-hq authors. petrova.host serves. consumers carry only the boot kit and fetch the rest via Fleet MCP.
Concretely:
eva-hq/prompts/{slug}/is the sole authoring surface. Each prompt directory holdsmeta.yml,prompt.xml(eva wrapper),body.md(canonical markdown body, new this ADR — 11 bodies migrated from the retiredprompts.gitmirror), and optionalguard.sh/verify.sh.petrova.host/console/promptsandeva.re/catalogare views, not copies. Both read eva-hq live viapetrova.prompts.list/petrova.prompts.get(EvaSourceinhost/src/sources/eva.ts). The dashboard page header is relabelled “catalog · N prompts · live from eva-hq” to make this visible.- Consumer
.petrova/playbook/is the runtime boot kit only:META-RULES.md,00-bootstrap.md, partials, schemas. Six files. It is not the catalog. Consumer agents fetch every other prompt on demand via Fleet MCP (petrova.prompts.list/get). The asgard-style “no prompts/ directory exists” error is the symptom of an agent that hasn’t internalised this split, and the bootstrap text now carries an explicit consumer-contract callout to prevent it. petrova-codes/core/playbook/prompts/is an in-tree mirror of the 11 paste-prompts, refreshed every 6 hours from eva-hq by.github/workflows/sync-playbook-from-eva.yml. This exists sopetrova_install_playbookand the docs pipeline can read prompts without a network round-trip; it is machinery, not a parallel authoring surface.core/prompts/submodule is retired, along with thepetrova-codes/prompts.gitrepo it pointed at.
Alternatives considered
Section titled “Alternatives considered”- Consolidate everything into petrova-codes (move 58 prompts from eva-hq → petrova-codes/prompts-catalog/) — reverses the current ownership model, requires eva-hq to become a downstream consumer, bigger refactor, no clear win since eva-hq’s wrapper/verb tooling is more mature for prompts than petrova-codes’s.
- Keep the three-surface status quo, just document it harder —
doesn’t address the operator confusion or the synthetic-duplication
appearance on
/console/prompts, and leaves the manualcore/playbook/sync drift footgun in place.
Consequences
Section titled “Consequences”For code:
eva-hq/prompts/{slug}/body.mdadded for 11 prompts (commita3e0cc8in eva-hq).petrova-codes/core/prompts/submodule removed (9501345).petrova-codes/core/playbook/prompts/populated; installer +scripts/sync-docs.mjs+codes/scripts/pull-content.tsrepointed.- New CI workflow
.github/workflows/sync-playbook-from-eva.ymlmirrors every 6h;repository_dispatcheventeva-playbook-changedavailable for on-demand triggers. - New CI workflow
.github/workflows/petrova-notify-state.ymldeposited bypetrova_install_playbookinto consumer.github/workflows/, firesrepository_dispatch petrova-state-staleat petrova-codes on phase verb merges. state-sweep.ymlcron tightened from 6h to 30m, acceptsrepository_dispatch petrova-state-stale, runs forced on Node 24.- New RPC
petrova.sweeps.trigger(rate-limited 60s) + browser-facing proxy at/api/sweeps/trigger;▶ trigger sweepbutton on/console/sweeps. Companionpetrova.sweeps.last_runsurfaces workflow-level health distinct from per-repo data freshness. - Bot commits authored as
petrova-bot <ops@devarno.cloud>to unblock Vercel auto-deploys (previously rejected on synthetic noreply email).
For docs:
CLAUDE.md“Where the playbook lives” section rewritten as a three-row surface table.- New
/concepts/prompt-service/page on petrova.blog (docs/site/concepts/prompt-service.md) is the canonical reader-facing explanation;/concepts/control-plane-vs-source-of-truth/links it. core/playbook/README.mdrelabelled “boot kit — not the catalog”.- Both root-level and installed
00-bootstrap.mdcopies carry the consumer-contract callout (MCP fetch, do not look local). docs/runbooks/onboard-repo.mddocuments thePETROVA_DISPATCH_TOKENsetup (fine-grained PAT,Actions: read & write+Contents: read & writeon petrova-codes/petrova).
For in-flight phases:
- No phase impact in petrova-codes (control-plane self-entry is
pre-phase by design). Consumer-side: existing repos with
.petrova/playbook/already installed need a re-run ofpetrova_install_playbookwithoverwrite: trueto receive the notify workflow (separate ADR-tracked task).
For invariants:
- No MR changes. This decision operates within MR-12 (control plane vs source-of-truth split) — extended to prompts as a separate surface type.
Deferred / known-stale references:
- Append-only ADRs and historical specs/plans under
docs/decisions/,docs/superpowers/specs/,docs/superpowers/plans/retain literalcore/prompts/strings as historical fact (MR-7). Not swept. META-RULES.mdis not in eva-hq today — it still flows through thecore/templates/submodule pointer bump. Tracked separately; ADR updates CLAUDE.md to acknowledge this rather than overclaiming eva-hq’s canonical scope.
References
Section titled “References”- petrova-codes commits:
97e5a26,9501345,6a5c877,47e7806,0eefcdf,52638f2,cd61f32,ad655cb,a9e8840,5542931,d118aee,d1ecd1f. - eva-hq commit:
a3e0cc8. - Related:
docs/decisions/2026-05-13-petrova-onboarding-flow-v2.md— the bootstrap step in that flow now reads fromcore/playbook/prompts/00-bootstrap.md(in-tree mirror) instead ofcore/prompts/00-bootstrap.md(retired submodule). - Concept page:
/concepts/prompt-service/.