Skip to main content

project-sync

Sync release-decision experiment state to the web database. Provides the `sync.ts` CLI script that all other skills call to persist state changes (update fields, advance stage, log activities, manage experiment runs). Activate whenever a skill needs to write experiment state to the web DB. Triggers — "sync to web DB", "update experiment state", "push state", "set stage", "add activity", "create run", "start run", "analyze run", "decide run", "archive run", "record decision", "save learning", "get experiment".

Zur Installation springen

Quellinformationen

Repository
featbit/featbit-release-decision-agent
Letzte Quellaktivität
5. Mai 2026 um 08:48
Erkannte Sprache von SKILL.md
Englisch
Sterne
1
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
project-sync
description
Sync release-decision experiment state to the web database. Provides the `sync.ts` CLI script that all other skills call to persist state changes (update fields, advance stage, log activities, manage experiment runs). Activate whenever a skill needs to write experiment state to the web DB. Triggers — "sync to web DB", "update experiment state", "push state", "set stage", "add activity", "create run", "start run", "analyze run", "decide run", "archive run", "record decision", "save learning", "get experiment".
license
Apache-2.0
metadata
{"author":"FeatBit","version":"2.0.0","category":"release-management"}
# Project Sync — CLI Bridge to Web Database This skill provides `sync.ts`, the CLI script that bridges agent skills to the web database. All release-decision skills call this script to persist state changes. **No skill should construct HTTP requests or JSON payloads directly — always use `sync.ts`.** --- ## Script Location **Always invoke with the absolute path** — the bash tool's cwd on sandbox0 VMs is `/workspace`, not the skill directory, so a relative `scripts/sync.ts` will fail with `Cannot find module`. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts <command> [args] ``` > All flag arguments require the `--` prefix (e.g. `--primaryMetric '{...}'`, never bare `primaryMetric '{...}'`). The script will reject or ignore bare-name pairs. ## Environment | Variable | Default | Purpose | |---|---|---| | `SYNC_API_URL` | `https://www.featbit.ai` | Base URL of the web app | | `ACCESS_TOKEN` | _(empty)_ | **Required.** Bearer token (`fbat_…`) sent as `Authorization` header. The web API validates this on every call to `/api/experiments/*` — requests without a valid, non-revoked, project-scoped token are rejected with 401/403. Issue a token from the web UI: `/data/env-settings` → **Agent tokens** → Issue token. | Set `SYNC_API_URL` if the web app is not running at the default `https://www.featbit.ai`. --- ## Failure Modes | Symptom | Cause | Action | |---|---|---| | `Unable to reach sync API` | Web app not running or wrong `SYNC_API_URL` | Start the web app; verify `SYNC_API_URL` | | `ERROR 401` / `403` | Token required but missing or wrong | Set `ACCESS_TOKEN` env var | | `Invalid stage: "..."` | Caller used a non-canonical stage value | Use only: `intent \| hypothesis \| implementing \| measuring \| learning` | | `Invalid activity type` | Non-canonical `--type` value | Use only the values in the Canonical Enums table | | Non-zero exit, no output | Network timeout or unexpected server crash | Check web app logs; retry once | --- ## Canonical Enums These are the only valid values for each enum field. The script and server API **both** enforce them — using any other value will return an error. | Field | Valid Values | |---|---| | `stage` | `intent` \| `hypothesis` \| `implementing` \| `measuring` \| `learning` | | `activity type` | `stage_update` \| `field_update` \| `run_created` \| `run_collecting` \| `run_analyzing` \| `run_decided` \| `run_archived` \| `decision_recorded` \| `learning_captured` | | `run status` | `draft` \| `collecting` \| `analyzing` \| `decided` \| `archived` — **NEVER use `running`, `paused`, `completed` or any other value.** Each status has its own dedicated CLI command — the command name *is* the status. | | `method` | `bayesian_ab` \| `frequentist` \| `bandit` | | `decision` | `CONTINUE` \| `PAUSE` \| `ROLLBACK` \| `INCONCLUSIVE` | | `metricType` (run **and** state JSON) | `binary` \| `continuous` | | `metricAgg` (run **and** state JSON) | `once` \| `count` \| `sum` \| `average` | | `direction` (inside **state** `guardrails` JSON entry) | `increase_bad` \| `decrease_bad` | > **Single canonical vocabulary.** Use the same `metricType` / `metricAgg` values > for *both* run-column writes (`--primaryMetricType`, `--primaryMetricAgg`) and > state-JSON writes (`--primaryMetric`, `--guardrails`). The legacy `numeric` > spelling and the `last` aggregation are gone — use `continuous` and `count` > (or `sum` / `average`) instead. The script accepts the legacy values on read > for back-compat with old experiments but rejects them on write. --- ## Field Format Standards | Field | Format | Example | |---|---|---| | `variants` (on project state) | Pipe-separated `"key (annotation)\|key (annotation)"` | `"standard (control)\|streamlined (treatment)"` | | `primaryMetric` (on project state) | **JSON object** with `{name, event, metricType, metricAgg, description?}` — the web UI renders each field as its own column | `'{"name":"Signup conversion","event":"signup_completed","metricType":"binary","metricAgg":"once","description":"Proportion of visitors that complete a signup — chosen because it directly measures the H1 change."}'` | | `guardrails` (on project state) | **JSON array** of `{name, event, metricType, metricAgg, direction, description?}` — one object per guardrail metric | `'[{"name":"Checkout abandonment","event":"checkout_abandoned","metricType":"binary","metricAgg":"once","direction":"increase_bad","description":"must not rise"},{"name":"Support load","event":"support_chat_open","metricType":"continuous","metricAgg":"count","direction":"increase_bad"}]'` | | `guardrailEvents` (on run) | **Comma-separated** event names — sync.ts converts to JSON array | `"checkout_abandoned,support_chat_open"` | | `inputData` | Valid JSON string — raw metrics snapshot | `'{"metrics":{"control":{"n":1000},"treatment":{"n":1020}}}'` | | `analysisResult` | Valid JSON string — Bayesian output | `'{"decision":"CONTINUE","probability":0.87}'` | --- ## Commands ### get-experiment Read full project state (includes experiment runs, activities, messages). ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts get-experiment <experiment-id> ``` --- ### update-state Push one or more decision-state fields to the web DB. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts update-state <experiment-id> \ --goal "..." \ --intent "..." \ --hypothesis "..." \ --change "..." \ --variants "standard (control)|streamlined (treatment)" \ --primaryMetric '{"name":"Signup conversion","event":"signup_completed","metricType":"binary","metricAgg":"once","description":"Proportion of visitors that sign up."}' \ --guardrails '[{"name":"Checkout abandonment","event":"checkout_abandoned","metricType":"binary","metricAgg":"once","direction":"increase_bad"}]' \ --constraints "..." \ --flagKey "my-flag-key" ``` **Allowed fields:** `goal`, `intent`, `hypothesis`, `change`, `variants`, `primaryMetric`, `guardrails`, `constraints`, `openQuestions`, `lastAction`, `lastLearning`, `flagKey` > **variants format**: must be pipe-separated strings — NOT JSON. Use `"key (annotation)|key (annotation)"`. > > **primaryMetric format**: must be a valid JSON object with fields `name` (short display name), `event` (the instrumented event key, snake_case), `metricType` (`binary` or `continuous`), `metricAgg` (`once`, `count`, `sum`, or `average`), and optional `description` (rationale). The web UI renders `name`/`event`/`metricType`/`metricAgg` as separate table columns — do NOT dump the whole description into `name`. > > **guardrails format**: must be a valid JSON array; each entry is a guardrail object with the same shape as `primaryMetric` plus `direction` (`increase_bad` or `decrease_bad`). Use one entry per guardrail metric, never a single string. --- ### set-stage Advance the project stage. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts set-stage <experiment-id> <stage> ``` **Valid stages:** `intent` | `hypothesis` | `implementing` | `measuring` | `learning` --- ### add-activity Log an activity event. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts add-activity <experiment-id> --type <type> --title "..." [--detail "..."] ``` `--type` and `--title` are required. Use `--detail` for longer technical notes. --- ### create-run Create a new experiment run (status starts as `draft`). ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts create-run <experiment-id> <slug> \ --hypothesis "Adding streamlined checkout will increase purchase_completed" \ --method bayesian_ab \ --primaryMetricEvent purchase_completed \ --primaryMetricType binary \ --primaryMetricAgg once \ --controlVariant standard \ --treatmentVariant streamlined \ --guardrailEvents "checkout_abandoned,support_chat_open" \ --minimumSample 1000 \ --trafficPercent 100 \ --priorProper false \ --priorMean 0.1 \ --priorStddev 0.05 \ --observationStart 2024-01-15T00:00:00Z \ --observationEnd 2024-01-29T00:00:00Z ``` `guardrailEvents` accepts comma-separated event names — sync.ts converts them to a JSON array for storage. --- ### Run status transitions One command per status — **never pass a status string**; pick the command that matches the target state. There is intentionally no generic `set-run-status` command. | Command | Writes status | |---|---| | `start-run <experiment-id> <slug>` | `collecting` | | `analyze-run <experiment-id> <slug>` | `analyzing` | | `decide-run <experiment-id> <slug>` | `decided` | | `archive-run <experiment-id> <slug>` | `archived` | ```bash # Begin collecting data for an existing draft run npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts start-run <experiment-id> <slug> # Move to the analysis phase npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts analyze-run <experiment-id> <slug> # Record that a decision has been reached npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts decide-run <experiment-id> <slug> # Archive a run that is no longer in play npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts archive-run <experiment-id> <slug> ``` --- ### save-input Save the raw metrics snapshot collected for this run. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts save-input <experiment-id> <slug> \ --inputData '{"metrics":{"control":{"n":1000,"conversions":87},"treatment":{"n":1020,"conversions":104}}}' ``` `--inputData` must be a valid JSON string. --- ### save-result Save the Bayesian analysis output for this run. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts save-result <experiment-id> <slug> \ --analysisResult '{"decision":"CONTINUE","probability":0.87,"rope":{"low":0.0,"high":0.01}}' ``` `--analysisResult` must be a valid JSON string. --- ### record-decision Record the human/agent decision for this run. ```bash npx tsx $HOME/.claude/skills/project-sync/scripts/sync.ts record-decision <experiment-id> <slug> \ --decision CONTINUE \ --decisionSummary "Roll out streamlined checkout to 100% of users" \ --decisionReason "Treatment shows 87% probability of beating control; ROPE analysis clear" ``` `--decision` must be one of: `CONTINUE | PAUSE | ROLLBACK | INCONCLUSIVE` `--decisionSummary` is required (plain-language recommended action).
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen