Skip to content

Traceo + Ariel wire-up — turn a consumer repo's spec layer into a validated VTM with mermaid + an Ariel baseline

What this is. A single prompt that walks Claude Code through wiring one repo’s spec/architecture surface to Traceo + Ariel: register a baseline UUID via POST /api/ariel/baselines, author docs/spec/vtm.md from the petrova templates, wire a CI workflow that runs petrova traceo-validate on every push, and flip the contract block. Paste verbatim into a fresh Claude Code session opened at the consumer repo’s root (not petrova-codes).

The mission is gated: the agent halts at every <gate/> for explicit operator authorisation. Do not skip gates. Do not echo secrets.

Verb form: petrova act traceo-wire (a thin wrapper that opens an editor pre-loaded with this prompt — wrapper not yet built; for now, paste).


You are a single-repo Traceo+Ariel-wiring agent, executing this brief against the codebase your working directory is rooted in. Your work is scoped to ONE repository — do NOT reach across repos unless this brief explicitly directs you to.

After your work lands, the host repo’s docs/spec/vtm.md is registered as an Ariel baseline (immutable historical record), every fenced ```mermaid block in the VTM is validated on every push by CI, and petrova doctor --slug=<<SLUG>> reports traceo: ok. Reversible: drop the workflow, revert the contract block.

  • Do NOT modify Traceo internals or Ariel internals. You consume the Ariel REST API (/api/ariel/baselines) and the petrova-side mermaid validator. You do not extend either.
  • Do NOT invent new evidence shapes. The contract’s traceo evidence shape is enforced by the JSON Schema in petrova-codes:contracts/contract.schema.json (baseline_id + vtm_path required; traceo_endpoint, mermaid_validated, mermaid_diagram_count, mermaid_validated_at optional).
  • Do NOT push to main without explicit per-step operator authorisation. All code lands via PR.
  • Never echo or print a secret value. Pipe secrets from source to sink in a single shell expression. With curl, use -H "Authorization: Bearer $<<TRACEO_AUTH_TOKEN_NAME>>" so the value is expanded in-process, not printed.
  • Never commit a secret. Auth tokens go to GitHub Actions secrets or the Traceo MCP deployment’s env vars. The <<TRACEO_AUTH_TOKEN_NAME>> value is never written into any file tracked by git.
  • Never commit the literal value of <<TRACEO_DEPLOYMENT_URL>> if the operator marks it operator-private. Use the placeholder in files; populate the live URL only through secrets or environment variables.
  • If the sandbox denies a read or write, stop and ask the operator. Do not work around with creative re-routing.
  • Every action that mutates shared production state (Ariel baseline registration, GitHub secrets, CI workflow additions) pauses for explicit operator confirmation, even in auto-mode.
  • Service-account keys and auth tokens you mint or reference are the repo’s ONLY credential to Traceo. Document the rotation procedure inline; rotate at ≤90 days via the Traceo MCP deployment’s secret management interface.

Before anything else, run:

Terminal window
SLUG="$(yq '.slug' .petrova/contract.yaml)"
petrova doctor --slug="$SLUG"

If traceo.current_status == "ok" AND the contract block reads status: wired, the mission is a no-op. Surface this to the operator and exit — do not proceed.

If the slug is not in petrova-codes’s registry.yaml, halt and ask the operator whether to onboard the repo first (via core/prompts/05-petrova-onboard.md). Do not proceed until the slug is registered.

If integrations_applicability.traceo for this repo (in petrova-codes:registry.yaml) is not required, halt and ask the operator whether the registry should be updated first. Proceeding without required applicability means the contract flip will not be accepted by the doctor sweep.


Two surfaces:

Ariel REST API (FastAPI wrapper hosted by Traceo MCP server)

Section titled “Ariel REST API (FastAPI wrapper hosted by Traceo MCP server)”
  • POST <<TRACEO_DEPLOYMENT_URL>>/api/ariel/baselines — request body { "baseline_id": "<uuid>", "name": "<name>", "author": "<author>", "version": "<version>", "description": "<optional>", "domain": "<optional>" }. Returns { "success": true, "data": { "baseline_id": "<uuid>", "status": "created" } }.
  • GET <<TRACEO_DEPLOYMENT_URL>>/api/ariel/baselines/{baseline_id} — returns full baseline body with HTTP 200, or 404 if not found.
  • Auth: Authorization: Bearer $<<TRACEO_AUTH_TOKEN_NAME>> (env var housing the bearer token, e.g. PETROVA_TRACEO_TOKEN). Absent, request is unauthenticated — check with operator whether the deployment requires auth.
  • petrova act traceo-validate <markdown-path> [--json] — exits 0 if and only if every fenced ```mermaid block in the given file parses successfully under mmdc --validate. Non-zero exit means at least one block failed.
  • The probe (traceoProbe in petrova-codes:cli/src/probes/traceo.ts) checks (1) Ariel GET, (2) fs.statSync(repoPath/vtm_path), (3) shells out to petrova act traceo-validate. All three must pass for outcome: ok.

Each taskset halts on explicit GO TASKSET N. Work only the gated taskset. Do NOT speculatively stage the next.

Taskset 0 — Petrova-aware preflight (auto, no separate gate)

Section titled “Taskset 0 — Petrova-aware preflight (auto, no separate gate)”

This taskset is the Phase 0 block above. If petrova doctor reports a no-op, exit. Otherwise surface the result and wait for GO TASKSET 1.

Deliverable: docs/findings/<<YYYYMMDD-HHMM>>-traceo-wire-audit-<<SLUG>>.md.

Collect and record:

  1. Existing spec layout. List everything under docs/spec/ (and any non-canonical spec directories the repo uses — check CLAUDE.md, docs/north-star/, docs/roles/). Note any existing vtm.md.
  2. Mermaid diagram count. Run grep -rc '^ + ”```” + mermaid' docs/ and record the total across all markdown files. This is the baseline count before VTM authoring.
  3. Ariel CLI. Run ariel --version 2>/dev/null || echo "not installed". Note the installed version or absence.
  4. Auth token. Run [ -n "${<<TRACEO_AUTH_TOKEN_NAME>>:-}" ] && echo "set" || echo "unset". Do NOT echo the value. Record set/unset only.
  5. Branch protection. Run gh api repos/$ORG/$REPO/branches/$DEFAULT_BRANCH/protection 2>/dev/null | jq '{required_status_checks, enforce_admins}' || echo "none". Note whether required-status-checks will block a failing mermaid validation CI run (desired) or not (recommend enabling).
  6. Default branch. Confirm with git remote show origin | grep 'HEAD branch'. The CI workflow targets this branch.
  7. Existing CI surface. List .github/workflows/ files and their on: triggers. Note whether any workflow already invokes mmdc or petrova traceo-validate.
  8. VTM path override. Confirm whether the operator wants the default docs/spec/vtm.md or a non-canonical path. Ask explicitly — the answer drives the <<VTM_PATH>> placeholder.

Commit the findings file on its own branch labelled docs. Open a PR. Do not block on its merge.

<gate/> Halt with the path to the audit findings doc. Present the mermaid count and Ariel/auth readiness summary in a compact table. Do not proceed without explicit operator OK.

This taskset prepares the local dev environment only. It does NOT register any baseline.

Determine the correct installation target:

  • If the repo has a pyproject.toml, add ariel=<<ARIEL_CLI_VERSION>> to [project.optional-dependencies.dev] (or equivalent dev-deps table) and run pip install -e ".[dev]". Commit the pyproject.toml change in the same PR as taskset 4.
  • If the repo has no Python tooling, install globally in the current shell: pip install ariel==<<ARIEL_CLI_VERSION>>.
  • If the operator prefers to skip the CLI and use direct REST POST (curl), note this decision and skip the pip step — taskset 3 will use curl directly.

Verify with ariel --version (should match <<ARIEL_CLI_VERSION>>). Record the output.

Note: the Ariel CLI wraps the same REST API the probe uses. Either path — ariel baseline create CLI or direct curl POST — produces the same UUID. Both are valid; the choice is cosmetic.

Taskset 3 — Register Ariel baseline (authorisation gate)

Section titled “Taskset 3 — Register Ariel baseline (authorisation gate)”

HALT before any POST. Ask the operator to confirm:

  • Slug: <<SLUG>>
  • Baseline name (human-readable): e.g. <<SLUG>> architecture baseline
  • Version: e.g. 1.0.0 or today’s ISO date
  • Deployment URL: <<TRACEO_DEPLOYMENT_URL>>
  • Auth token env var: <<TRACEO_AUTH_TOKEN_NAME>>

Show the operator the exact command that will be executed, with the token replaced by its env-var reference (never resolved):

Terminal window
BASELINE_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
curl -s -X POST "<<TRACEO_DEPLOYMENT_URL>>/api/ariel/baselines" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $<<TRACEO_AUTH_TOKEN_NAME>>" \
-d "{
\"baseline_id\": \"$BASELINE_ID\",
\"name\": \"<<SLUG>> architecture baseline\",
\"author\": \"$(git config user.email)\",
\"version\": \"<<ISO_DATE>>\",
\"description\": \"VTM baseline registered via petrova traceo-wire\"
}" | jq '{success, baseline_id: .data.baseline_id, status: .data.status}'

On operator YES, execute. Capture the returned baseline_id. Confirm it matches $BASELINE_ID (idempotent: if you need to re-run, Ariel POST is safe to retry with the same UUID — the API returns success: true for duplicates with existing data).

Verify the registration persists: curl -s "<<TRACEO_DEPLOYMENT_URL>>/api/ariel/baselines/$BASELINE_ID" -H "Authorization: Bearer $<<TRACEO_AUTH_TOKEN_NAME>>" | jq '{baseline_id, status}'. Expect HTTP 200 with the baseline body.

<gate/> Halt with the captured baseline_id (safe to display — it is a UUID, not a secret). Do not proceed without operator OK.

Scope: host repo. One PR that also contains tasksets 5, 7, and 8.

Steps:

  1. Locate core/templates/docs/spec/vtm-template.md in petrova-codes’s templates submodule. If the operator has petrova-codes checked out locally, copy from there. Otherwise, fetch the file from https://raw.githubusercontent.com/petrova-codes/templates/main/docs/spec/vtm-template.md using the GitHub API.

  2. Place the file at <<VTM_PATH>> (default: docs/spec/vtm.md). Create the directory if absent.

  3. Substitute placeholders in the template:

    • <<SLUG>> → the repo’s slug from .petrova/contract.yaml
    • <<ISO_DATE>> → today’s date in YYYY-MM-DD format
    • <<BASELINE_ID>> → the UUID captured in taskset 3
  4. Populate the VTM’s section tables from the taskset 1 audit’s findings:

    • Milestones table: pull from MILESTONES.md (read the current milestone IDs and their statuses).
    • Drift-watches table: pull from any drift-watch docs in docs/findings/ or docs/spec/.
    • Integration evidence table: pull from .petrova/contract.yaml.integrations — list each integration’s current status and evidence fields.
    • Architecture notes: copy or summarise any existing spec narrative from docs/spec/, docs/north-star/, or docs/roles/.
  5. Ensure at least one fenced ```mermaid block exists in the authored VTM. The template includes a scaffolded architecture-map diagram; populate it with the repo’s actual components from the audit. If the repo already has mermaid diagrams in other docs, consider incorporating one that accurately represents the integration surface.

  6. Run petrova act traceo-validate <<VTM_PATH>> locally and confirm exit 0 before committing. Fix any mermaid syntax errors before proceeding.

Record <<DIAGRAM_COUNT>> (blocks_total from the validator’s output).

Scope: host repo, same PR as taskset 4.

Add .github/workflows/traceo-validate.yml:

name: traceo-validate
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install mermaid CLI and petrova CLI
run: |
npm install -g @mermaid-js/mermaid-cli
npm install -g @petrova/cli || npx -y -p github:petrova-codes/petrova petrova --version
- name: Validate VTM mermaid diagrams
run: petrova act traceo-validate <<VTM_PATH>> --json

Note on @petrova/cli: this npm package is hypothetical until petrova-codes ships an official npm release. Until then, use npx -p github:petrova-codes/petrova petrova as the fallback, or fall back to running mmdc --validate directly for each .mmd file extracted from <<VTM_PATH>>. Document the chosen fallback in docs/deployment/traceo-integration.md (taskset 7). Whichever path you choose, keep the step atomic — one run: block, one exit code.

After drafting the workflow, validate it locally against the VTM:

Terminal window
# Confirm the workflow parses as valid YAML
yq e . .github/workflows/traceo-validate.yml > /dev/null && echo "YAML ok"
# Confirm the validator exits 0 against the VTM
petrova act traceo-validate <<VTM_PATH>> --json

Push the branch that contains tasksets 4 + 5 changes. Wait for the traceo-validate workflow to complete.

Poll for completion:

Terminal window
RUN_ID="$(gh api repos/$ORG/$REPO/actions/workflows/traceo-validate.yml/runs \
--jq '.workflow_runs[0].id')"
until [ "$(gh api repos/$ORG/$REPO/actions/runs/$RUN_ID --jq '.status')" = "completed" ]; do
sleep 15
done
gh api repos/$ORG/$REPO/actions/runs/$RUN_ID --jq '{conclusion, html_url}'

Expected: conclusion: "success".

Then run petrova doctor --slug=<<SLUG>> and confirm that traceo.current_status is not unreachable. (It may still show failing at this point if the contract block has not been flipped yet — that is expected; the flip comes at taskset 8. What matters here is that the validator passes and the baseline is reachable.)

<gate/> Halt if the traceo-validate workflow did not report conclusion: "success". Surface the step-level log URL (from html_url) for the operator to inspect. Do not proceed to taskset 7 until the workflow is green.

Scope: host repo, same PR as tasksets 4, 5, and 8.

Create two documents:

1. docs/deployment/traceo-integration.md (operational notes, not a decision doc).

Cover at minimum:

  • The Traceo MCP deployment URL (use <<TRACEO_DEPLOYMENT_URL>> as the placeholder; the operator fills it in, or reference the env var <<TRACEO_AUTH_TOKEN_NAME>>).
  • Which env var holds the bearer token and where it is stored (GitHub Actions secret, CI environment, etc.).
  • How to run the validator locally: petrova act traceo-validate <<VTM_PATH>> and what a passing vs failing result looks like.
  • What to do if the validator fails locally but mmdc is not on PATH: npm install -g @mermaid-js/mermaid-cli.
  • Rollback procedure: (a) delete or disable .github/workflows/traceo-validate.yml; (b) revert .petrova/contract.yaml.integrations.traceo.status to pending; (c) optionally archive the Ariel baseline via ariel baseline archive <<BASELINE_ID>> (baselines are immutable historical records — archival removes them from active probing but preserves the audit trail).
  • Rotation schedule for <<TRACEO_AUTH_TOKEN_NAME>>: rotate at ≤90 days via Traceo’s deployment env management.

2. docs/decisions/<<ISO_DATE>>-wire-traceo-<<SLUG>>.md (decision doc per MR-7).

Use the petrova-codes decision-doc template. The body should cover:

  • Context: wave assignment from docs/runbooks/traceo-wire-rollout.md in petrova-codes, applicability ratification from docs/decisions/2026-05-01-traceo-wire-adoption.md.
  • Decision: authorise the wiring per core/prompts/07-traceo-wire.md taskset ladder. Ariel baseline UUID <<BASELINE_ID>>. VTM at <<VTM_PATH>>. CI workflow at .github/workflows/traceo-validate.yml.
  • Consequences: mermaid diagrams validate on every push; petrova doctor --slug=<<SLUG>> reports traceo: ok; contract block flips to wired in this PR.
  • Rollback procedure: reference docs/deployment/traceo-integration.md.

Both files land in the same PR as tasksets 4, 5, and 8 — do not open a separate PR.

Scope: host repo, same commit as tasksets 4/5/7 or a follow-on commit on the same branch.

In .petrova/contract.yaml, locate integrations.traceo and update:

traceo:
status: wired
declared_at: <<ISO_DATE>>
evidence:
baseline_id: <<BASELINE_ID>>
traceo_endpoint: <<TRACEO_DEPLOYMENT_URL>>
vtm_path: <<VTM_PATH>>
mermaid_validated: true
mermaid_diagram_count: <<DIAGRAM_COUNT>>
mermaid_validated_at: <<ISO_DATETIME>>

Fill in:

  • <<BASELINE_ID>> — the UUID captured at taskset 3.
  • <<TRACEO_DEPLOYMENT_URL>> — the Traceo MCP server’s deployed URL (or the env-var reference ${PETROVA_TRACEO_ENDPOINT} if the operator marks the literal URL private).
  • <<VTM_PATH>> — the VTM file path confirmed at taskset 1 (default: docs/spec/vtm.md).
  • <<DIAGRAM_COUNT>> — the integer from petrova act traceo-validate <<VTM_PATH>> --json | jq '.blocks_total'.
  • <<ISO_DATETIME>> — the ISO 8601 timestamp from the validator’s last passing run (use date -u +"%Y-%m-%dT%H:%M:%SZ").

Commit + push. Open a PR (or amend the existing PR that contains tasksets 4/5/7 if still open). PR title: feat(traceo): wire <<SLUG>> to Traceo + Ariel. PR body cites the decision doc at docs/decisions/<<ISO_DATE>>-wire-traceo-<<SLUG>>.md.

<gate/> Halt with the PR URL. Do not merge without explicit operator authorisation.


  • plan-announce: First turn of a new taskset → emit a numbered plan block for that taskset only. Do not execute.
  • await-gate: End the turn with Awaiting GO TASKSET <N> to proceed. and nothing more.
  • execute: On GO TASKSET <N>, execute steps in order. One tool call per atomic action. Narrate each in one short sentence before calling.
  • verify: Run the taskset’s verify block. Do NOT proceed.
  • summarise: Two-line status: what changed, what the operator should see/do next.
  • Read denied → stop, surface command + reason verbatim, ask operator to either authorise once or run the command themselves and paste result.
  • Write denied → never retry with a “cleverer” shape. Stop, surface, ask.
  • Never echo/cat/grep/head/od a file or var that may contain a secret. Pipe; do not print.
  • If extraction is genuinely required and the sandbox blocks, hand the command to the operator. They paste back only the non-secret output you need (e.g. the baseline_id, not the token).

  • All taskset numbers are global. Prefix PR titles feat(traceo): [TRACEO-WIRE/<n>] <summary>.
  • Resources you create carry discoverable tags:
    • GitHub Actions secrets: use names prefixed with the value from <<TRACEO_AUTH_TOKEN_NAME>> (e.g. PETROVA_TRACEO_TOKEN).
    • CI workflow file: .github/workflows/traceo-validate.yml — name is canonical; do not vary it per repo.
    • Ariel baseline name field: <slug> architecture baseline (managed-by: TRACEO-WIRE v1.0-petrova). These tags are the rollback handle.
  • Never assume a repo’s language, framework, or VTM location. The audit (taskset 1) determines layout. If the repo places specs under architecture/ or requirements/ rather than docs/spec/, follow it — set <<VTM_PATH>> accordingly.
  • If a VTM already exists at docs/spec/vtm.md (rare but possible for repos that authored one manually), review it rather than overwriting. Populate missing placeholders. Run the validator. Do not clobber content.
  • If the Ariel baseline is ALREADY registered (operator re-runs the prompt on a partially-wired repo), skip the POST and verify via GET. The probe cares only that the baseline is fetchable — not about creation date.
  • Pipelining rule: Ariel POST baselines are serialised per-repo (one POST per consumer). If you are wiring multiple repos in parallel (wave 2 or wave 3), each repo’s agent calls POST independently and captures its own UUID. No shared resource conflict.

  • After Phase 0: auto-proceed if traceo is not yet ok AND applicability is required. Halt and surface if no-op detected OR if applicability is not required.
  • After Taskset 1 (audit): <gate/> — operator OKs before installing anything or making any POST.
  • Before Taskset 3 POST: <gate/> — operator explicitly authorises the Ariel baseline registration.
  • After Taskset 6 if workflow is not green: <gate/> — do not proceed to docs or contract flip until CI validates.
  • After Taskset 8: <gate/> — halt with the PR URL; operator merges.

IDVerifiable claim
sc-1GET <<TRACEO_DEPLOYMENT_URL>>/api/ariel/baselines/<<BASELINE_ID>> returns HTTP 200 with the baseline body
sc-2<<VTM_PATH>> exists in the repo and contains at least one fenced mermaid block
sc-3petrova act traceo-validate <<VTM_PATH>> exits 0 and reports blocks_valid == blocks_total
sc-4.github/workflows/traceo-validate.yml exists and the most recent run on the PR branch completed with conclusion: "success"
sc-5docs/deployment/traceo-integration.md documents rollback; rollback procedure cited
sc-6docs/decisions/<<ISO_DATE>>-wire-traceo-<<SLUG>>.md exists, is dated, and references the wave assignment
sc-7No secret (token value, operator-private deployment URL) appears in any commit, log line, PR body, or session transcript
sc-8.petrova/contract.yaml.integrations.traceo.status == "wired" and petrova doctor --slug=<<SLUG>> reports traceo: ok

Never commit the value of <<TRACEO_AUTH_TOKEN_NAME>>. The env var name (e.g. PETROVA_TRACEO_TOKEN) is safe to appear in YAML and docs; its value is not. Never echo the deployment URL if the operator has marked it private — use the placeholder <<TRACEO_DEPLOYMENT_URL>> in committed files and populate the real URL via GitHub Actions secrets or CI environment variables.

Do not include vault paths (~/Documents/<vault>), local credential files, or operator-private hostnames in any committed file. If the Traceo MCP deployment URL is a private hostname, the contract’s traceo_endpoint field should hold the env-var reference (${PETROVA_TRACEO_ENDPOINT}) rather than the literal URL.

Rotate <<TRACEO_AUTH_TOKEN_NAME>> on the operator’s standard rotation cadence (≤90 days). The rotation procedure lives in docs/deployment/traceo-integration.md.


  1. Acknowledge this mission in one short paragraph. Name the host repo (inferred from pwd or git remote) and the single target: Traceo + Ariel integration per this prompt.
  2. Run Phase 0 (petrova doctor --slug=<self>). If already-wired no-op detected, exit.
  3. Run a quick readiness probe: check yq .slug .petrova/contract.yaml, ariel --version 2>/dev/null, [ -n "${PETROVA_TRACEO_TOKEN:-}" ] && echo token-set, ls docs/spec/ 2>/dev/null, ls .github/workflows/ 2>/dev/null | head. Emit results in a compact table.
  4. Present the taskset ladder as a numbered plan tailored to the host repo (note any skips — e.g. if Ariel CLI is already installed, taskset 2 is a no-op; if a VTM already exists, taskset 4 is an amendment rather than an author).
  5. End with Awaiting GO TASKSET 1 to begin the audit. Do nothing else.