# Harness Pulse

> Harness Pulse

- Skill: `intense-visions/harness-pulse` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add intense-visions/harness-pulse`
- Raw SKILL.md: https://api.skillmd.com/api/skills/intense-visions/harness-pulse/raw
- Safety review: PASS (external: skill-scanner WARNING, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Intense-Visions (https://skillmd.com/u/intense-visions)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/intense-visions/harness-pulse

---

# Harness Pulse

> Single-page time-windowed product pulse. **Phase 3 ships the first-run interview only**: it converts vague intent into a concrete `pulse:` block in `harness.config.json`, refuses read-write DB credentials, and seeds from `STRATEGY.md` when present. The actual `harness pulse run` (Phases 2-4 of the runtime) is deferred to spec Phase 4.

## When to Use

- Manually, when a project wants to start receiving daily pulse reports
- When `harness.config.json` has no `pulse:` block and the user invokes `/harness:pulse`
- NOT for ad-hoc one-off metric queries (that's the analytics tool's job)
- NOT for replacing dashboards (pulse is a single-page summary, not a metrics platform)
- NOT for projects that have not yet decided what their key metrics are (run `harness-strategy` first to write `STRATEGY.md`; pulse seeds from it)

## Process

### Iron Law

**No PII reaches `harness.config.json` and no read-write DB credential is accepted.** Both are interview-time gates; both are hard refusals (no warnings, no overrides without an explicit user-typed escape).

---

### Phase 0: ROUTE BY CONFIG STATE

1. Read `harness.config.json`.
2. If `pulse.enabled` is set (true OR false), skip directly to "Phase 2: RUN" — **deferred to spec Phase 4**. For now, surface "pulse already configured; the run path ships in Phase 4" and stop.
3. Otherwise enter Phase 1.

---

### Phase 1: FIRST-RUN INTERVIEW

Read `references/interview.md` for the SMART pushback rules and the READ-WRITE-DB rejection rule. Both are mandatory.

1. **Seed from STRATEGY.md.** Call `seed_pulse_from_strategy({ path: process.cwd() })` on the harness MCP server. Capture `{ name, keyMetrics, warnings }` — the server does the file read and bullet extraction internally. Fallback when the MCP server is unavailable: `node -e "import('@harness-engineering/core').then(m => console.log(JSON.stringify(m.seedFromStrategy({}))))"` — only works when `@harness-engineering/core` is resolvable from the project.
   - Surface `warnings` to the user verbatim.
   - If `name` is non-null, confirm it as the product name; otherwise prompt.
   - For each `keyMetric`, walk it through the SMART bar in step 4.

2. **Pick the lookback default.** Ask in plain text — present numbered options `["24h", "7d", "30d", "custom"]` and wait (do NOT use `emit_interaction`/`AskUserQuestion`; the human won't see it — it renders only to the model and the client collapses the call to "Called harness"). Default `24h` per spec.

3. **Identify the primary engagement event** (e.g. `session_started`). Apply the SMART bar. If the user can't name one, set `null` and add a pending entry. Record the event name in `primaryEvent`.

4. **Identify the value-realization event** (e.g. `plan_completed`). SMART bar applies. Record in `valueEvent`.

5. **Identify completion events** (zero or more). SMART bar per item. Record in `completionEvents`.

6. **Quality scoring (optional).** Ask whether the user wants quality sampling on a single dimension (e.g. "did the plan deliver value"). Default off. If enabled, set `qualityScoring: true` and record `qualityDimension`.

7. **Wire data sources.** Ask which providers are available:
   - `analytics`: posthog, amplitude, mixpanel, custom — or null
   - `tracing`: sentry, datadog, custom — or null
   - `payments`: stripe, custom — or null
   - `db`: opt-in only, with the **READ-WRITE-DB rejection rule** active
     For each non-null choice, check `getPulseAdapter(name)`. If absent, surface the "Phase 4 will ship the adapter" warning from `references/interview.md`.

8. **Walk every STRATEGY.md key metric** through SMART. Map to an event when wired; otherwise append to `pendingMetrics` (or `excludedMetrics` if explicitly skipped). Cite `STRATEGY.md` when seeding so the user understands provenance.

9. **Confirm the assembled config.** Show the user the proposed `pulse:` block; ask for confirmation.

10. **Write the config.** Call `write_pulse_config({ path: process.cwd(), config })` on the harness MCP server. The `config` argument is the assembled `PulseConfig` JSON. The MCP tool validates against `PulseConfigSchema` and refuses to touch disk on schema failure; passing the config as a JSON parameter (not through a shell) means user-supplied prose never crosses the shell tokenizer — no quoting, backtick, or `$VAR` hazard. The writer preserves all other config keys and writes `harness.config.json.bak` on first call.

    Fallback for environments without the MCP server (only works when `@harness-engineering/core` is resolvable from the project): `echo '<json-blob>' | node -e "import('@harness-engineering/core').then(m => m.writePulseConfig(JSON.parse(require('fs').readFileSync(0, 'utf-8')), { configPath: 'harness.config.json' }))"`.

11. **Offer to register the `product-pulse` maintenance task.** Deferred: Phase 6 of the spec wires it. For now, surface "the daily 8am `product-pulse` task will be registered automatically once Phase 6 of the feedback-loops spec ships; you can also run pulse on demand with `/harness:pulse [window]` once Phase 4 ships."

12. **Run `harness validate`** to confirm the new `pulse:` block parses.

---

### Phase 2: RUN — deferred to spec Phase 4

Stub: when `pulse.enabled === true`, this phase will dispatch analytics/tracing/payments queries in parallel, run the SanitizeFn for each provider's response, and stash sanitized results for Phase 3. NOT YET IMPLEMENTED. The skill exits early with a "deferred to Phase 4" message if it reaches this phase.

### Phase 3: ASSEMBLE — deferred

### Phase 4: SAVE — deferred

---

### Question-File Mode (opt-in)

The default is the interactive first-run interview above. **Question-file mode** is an opt-in variant for **async, team-reviewable** pulse configuration — useful when the metric/event decisions need review from data owners before the `pulse:` block is written. The skill writes its questions to a durable file, the human fills them in over time, and the skill reads them back. Enter it only when the human asks; never automatically. The full convention — file location, the `[Answer]:` tag, the read-back ritual, context hygiene — lives in `references/question-file-mode.md`; this section states only how it maps onto the pulse interview.

1. **WRITE.** Assemble the same questions Phase 1 would ask (lookback window; primary engagement event; value-realization event; completion events; quality-scoring opt-in; data-source wiring; and one question per `STRATEGY.md` Key metric when seeded) into `docs/pulse/interviews/pulse-questions.md` — a pulse-scoped home next to the pulse config it produces (no per-change slug) (or `.harness/sessions/<slug>/interviews/pulse-questions.md` when a session slug is known), each with an empty `[Answer]:`. **Never write a DB connection string into the file** — collect any `db` credential interactively so the READ-WRITE-DB rejection rule runs on a value that is not persisted to a committable file. Report the path and stop.
2. **READ-BACK.** On the next run, re-read the file from disk and treat each filled `[Answer]:` as that question's answer. Apply the SMART bar to every proposed metric/event exactly as in interactive mode, flagging failures **in the file** under the question. Unanswered questions route to `pendingMetrics`/`null` per the normal skip handling.
3. **CONTRADICTION PASS.** Run the cross-answer contradiction pass (see `references/interview.md` and `references/question-file-mode.md`) over the filled answers — most importantly the **metric ⇄ approach** category: a Key metric whose data source was never wired (e.g. "p95 latency" with no tracing source) is a contradiction, not merely a pending metric. Surface it; never auto-resolve.
4. **PROCEED.** Continue to the unchanged Phase 1.9 confirm → `write_pulse_config` path. File mode changes only how answers are gathered — the PII gate, the READ-WRITE-DB rejection, schema validation, and `.bak` behavior are identical.

## Harness Integration

- **`harness validate`** — Run after `write_pulse_config`; the existing pulse-schema validator catches malformed blocks.
- **Harness MCP tools consumed by this skill** (canonical execution path — no project-local `@harness-engineering/core` required):
  - `seed_pulse_from_strategy({ path })` — defensive STRATEGY.md reader; returns `{ name, keyMetrics, warnings }`.
  - `write_pulse_config({ path, config })` — atomic config update with .bak. Validates against `PulseConfigSchema`.
- **`@harness-engineering/core`** primitives the MCP tools wrap (only directly relevant when developing inside the monorepo or when the MCP server is unavailable):
  - `writePulseConfig(config, { configPath })`, `seedFromStrategy({ cwd })`, `getPulseAdapter(name)` / `listPulseAdapters()` (Phase 4 populates), `PulseConfigSchema` / `PII_FIELD_DENYLIST`.
- **Boundary with `harness-strategy`** — Strategy writes `STRATEGY.md`; pulse reads it to seed. Pulse never writes to `STRATEGY.md`.
- **Boundary with `harness-observability`** — Observability designs _what_ to instrument; pulse is the read-side companion that surfaces what was instrumented.
- **Decision 6 (read-only)** — Pulse refuses read-write DB credentials. Documented in `references/interview.md`.
- **Decision 7 (PII contract)** — Every provider source must have a registered `SanitizeFn` adapter. Phase 3 ships the registry; Phase 4 ships the adapters.

## Success Criteria

- On a project with no `pulse:` block, the interview produces a valid `pulse:` block in `harness.config.json` with all non-pulse keys preserved.
- A `harness.config.json.bak` is written before mutation.
- A read-write DB credential is refused; the interview either accepts a read-only credential or sets `sources.db.enabled: false`.
- When `STRATEGY.md` exists, `name` and `Key metrics` seed the interview; missing/malformed STRATEGY.md soft-fails with warnings.
- `harness validate` passes after the interview completes.

## Rationalizations to Reject

These are common rationalizations that sound reasonable but lead to incorrect results. When you catch yourself thinking any of these, stop and follow the documented process instead.

| Rationalization                                                                                      | Why It Is Wrong                                                                                                                                                                                                                            |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| "The user pasted an admin DB connection string, but they clearly know their setup — I'll accept it." | The READ-WRITE-DB rejection is non-negotiable: no flag, no override, no "I know what I'm doing" path. Refuse, cite Decision 6, and set `sources.db.enabled: false`. A pulse report never needs write access.                               |
| "'Engagement' is a bit vague, but I know what they mean — I'll record it without SMART pushback."    | SMART pushback is mandatory on every proposed metric/event. Silently accepting a vague name pollutes the config and produces an unmeasurable pulse. Push back until the metric names a concrete, measurable event.                         |
| "It's just one field — I'll hand-edit the `pulse:` block into `harness.config.json` directly."       | `write_pulse_config` is the only sanctioned write path: it preserves all non-pulse keys, validates against `PulseConfigSchema`, and writes the `.bak`. A hand-edit bypasses the schema gate and can clobber sibling config.                |
| "STRATEGY.md already lists the key metrics — I'll copy them into the config as-is."                  | Every seeded key metric must still clear the SMART bar and be mapped to a wired event. Metrics with no data source belong in `pendingMetrics`, not the live block — copying them wholesale ships a config that silently can't be computed. |
| "The config assembled cleanly — I'll skip `harness validate`."                                       | A malformed `pulse:` block silently breaks the daily `product-pulse` task once the run path ships. Validation is a gate that must pass before exit, not an optional final touch.                                                           |

## Examples

### Example: greenfield (no STRATEGY.md, no existing pulse block)

- Phase 0: route to Phase 1.
- Phase 1.1: `seedFromStrategy` returns `{ name: null, keyMetrics: [], warnings: ['STRATEGY.md not found'] }`.
- Phase 1.2-7: prompt user; collect `lookbackDefault: '24h'`, `primaryEvent: 'session_started'`, `valueEvent: 'plan_completed'`, `sources.analytics: 'posthog'` (with adapter-availability warning), `sources.db.enabled: false`.
- Phase 1.10: `write_pulse_config` writes the block; `.bak` saved.
- Phase 1.12: `harness validate` passes.

### Example: STRATEGY.md present with 3 Key metrics

- Phase 1.1: seed returns `{ name: 'Acme', keyMetrics: ['DAU', 'plans/week', 'p95 latency'] }`.
- Phase 1.8: walk each metric through SMART.
  - "DAU" → mapped to `session_started` count over 24h, accepted.
  - "plans/week" → mapped to `plan_completed` count over 7d, accepted (recorded as a future custom window).
  - "p95 latency" → no tracing source wired yet; lands in `pendingMetrics`.

### Example: user offers an admin DB credential

- Phase 1.7: user pastes `postgresql://admin:pwd@host/db`.
- Skill matches `admin` username against the rejection list; refuses; cites Decision 6.
- User declines to provide a read-only credential; skill writes `sources.db.enabled: false`.

## Gates

- **READ-WRITE-DB rejection is non-negotiable.** No flag, no override, no "I know what I'm doing" path. Refuse and document.
- **SMART pushback is mandatory on every proposed metric/event.** Silently accepting a vague name pollutes the corpus.
- **`write_pulse_config` (or `writePulseConfig` when invoked directly) is the only sanctioned write path.** Do not hand-edit `harness.config.json`. The writer is the layer that preserves non-pulse keys and writes the .bak.
- **`harness validate` must pass before exit.** A malformed `pulse:` block silently breaks the daily task once Phase 4 ships.

## Escalation

- **User insists on read-write DB credentials:** Refuse. Set `sources.db.enabled: false`. Stop.
- **Adapter not registered for a chosen provider:** Warn, record the choice, continue. The runtime gate (Phase 4) refuses to run until the adapter ships.
- **STRATEGY.md frontmatter is malformed but H1 is present:** Use H1 as `name` and surface a warning. If neither is parseable, prompt the user.
- **`write_pulse_config` returns `{ written: false, error }` (or `writePulseConfig` throws directly):** Report the validator error verbatim. Do not retry without user fix.

