# cabinet-verify

Walkthrough verification runtime for Claude Cabinet. Cucumber + Playwright
scenarios driven through user-flow walkthroughs, with a human-in-the-loop
verdict pause for subjective checks. Originally lifted from de[sic]ify's
`e2e/support/` and generalized.

This package is the **runtime** half. The orchestration (skill files,
phase definitions, `/verify learn` bootstrap flow) lives in the
`templates/skills/verify/` upstream of Claude Cabinet. The runtime is
installed by the CC installer to `~/.claude-cabinet/verify/<version>/dist/`
and referenced by consuming projects via a `file:` dependency.

See `CONVENTIONS.md` for the frozen contracts:

- Verdict Ledger Schema (`VerdictRow`, JSONL ledger format)
- Verdict Chars (`P` / `I` / `S` / `N`)
- Cost Tags, Role Tags
- Env-Var Prefix (`CABINET_VERIFY_*`)
- pathHash Spec (content-aware cache key)
- Install Dir, Tarball Install Pattern
- npm Scripts (consuming project), CheckId Convention, Version Resolution

## Running headless / in CI

Most checks are programmatic, but subjective checks call `askHumanVerdict`,
which needs an answer. What happens depends on the run context:

- **Interactive terminal (TTY):** prompts on stderr for `P`/`I`/`S`/`N`.
- **Non-TTY with an orchestrator** (the `/verify` skill, Mode E): writes
  `.verdict-pending.json` and polls `.verdict-response.json` for up to
  **10 minutes per check**, then auto-skips. The skill reads those files
  and answers in-conversation.
- **Unattended / CI / a background run with no responder:** nothing
  writes the response file, so each subjective check waits the full
  10 minutes before skipping. Set the escape hatch below — otherwise the
  suite *appears* to hang.

**`CABINET_VERIFY_AUTO_SKIP_HUMAN=1`** auto-records every subjective check
as `human:S` (skip) so the full suite runs end-to-end without a human. Use
it ONLY to prove a *programmatic* scenario green (structural smoke); it
does NOT verify subjective checks. Example:

```bash
CABINET_VERIFY_AUTO_SKIP_HUMAN=1 npm run verify
```

Other behavior-affecting env vars (all `CABINET_VERIFY_*`; full contract in
`CONVENTIONS.md`):

| Var | Effect |
|---|---|
| `CABINET_VERIFY_AUTO_SKIP_HUMAN=1` | auto-skip every human verdict (smoke only) |
| `CABINET_VERIFY_SKIP_FRESH_PASSES=1` | short-circuit checks already passed at the same code (records `human:S`) |
| `CABINET_VERIFY_AUTO_OPEN_SCREENSHOTS=1` | open each screenshot in Preview (TTY runs) |
| `HEADLESS=1` | Playwright headless (Playwright's own convention — no prefix) |

For Claude to answer subjective checks instead of a human, use the
`/verify run --auto-verdict` skill flag (not an env var).

## Public API

```ts
import {
  startRun,
  endRun,
  recordVerdict,
  setScenarioContext,
  autoCheck,
  loadFixture,
  out,
  type VerdictRow,
  type RunSummary,
} from 'cabinet-verify';
```

(Additional exports — `askHumanVerdict`, `walkManualChecklist`, `preflight`,
`world` lifecycle hooks — land in Phases 2–3.)

## Build

```bash
npm install
npm run build
npm test
```

`npm test` runs the smoke test for the verdict recorder.

## Status

- Phase 1 — cleanly-generic lifts (verdict-recorder, output, auto-check,
  fixture-loader) ✓
- Phase 2 — pathHash + human-verdict + manual-runner + fresh-pass-cache
- Phase 3 — world lifecycle, preflight, CLI bins (report-last,
  report-status, preflight)
