witness — Claude Code skill: what it does, how to install
Signs fix manifests with Ed25519 and tracks regressions using code markers. It detects reverted bug fixes before code ships to production.
npx skills add ruvnet/ruflo --skill witness -a claude-codeWhat witness does
The skill monitors documented fixes by scanning for distinctive code substrings. You register each resolved issue inside witness-fixes.json with a file path and a marker string. If someone accidentally deletes or reverts the patch, verification flags the issue as regressed immediately.
Signing manifests requires the @noble/ed25519 npm package. By default, witness derives its signing seed from git commit hashes to check file integrity. Setting RUFLO_WITNESS_SEED and RUFLO_WITNESS_PUBLIC_KEY turns this check into verified release authorship.
Release state is recorded in verification-history.jsonl. The history CLI lets you pinpoint which commit caused a specific marker to disappear. Running verification with --strict forces a non-zero exit if file hashes shift even when markers stay intact.
What it helps with
- detect reverted bug fixes using file substrings
- sign release manifests with Ed25519 keys
- pinpoint the exact commit that introduced a regression
- block CI pipelines when a documented fix goes missing
Example prompts for the agent
- Check active code markers using witness verify
- Regenerate the witness manifest for this release
- Find when bug fix F1 regressed with witness history
How to install witness
1Skills CLI (Vercel)
npx skills add ruvnet/ruflo --skill witness -a claude-code2Manually: put the files in place
~/.claude/skills/witness/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/witness/
1Skills CLI (Vercel)
npx skills add ruvnet/ruflo --skill witness -a codex2Manually: put the files in place
.agents/skills/witness/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add ruvnet/ruflo --skill witness -a cursor2Manually: put the files in place
.cursor/skills/witness/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install ruvnet/ruflo witness2Manually: put the files in place
.github/skills/witness/SKILL.md1Skills CLI (Vercel)
npx skills add ruvnet/ruflo --skill witness -a gemini-cli2Platform CLI
gemini skills install https://github.com/ruvnet/ruflo --path plugins/ruflo-core/skills/witnessManually: put the files in place
.devin/skills/witness/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add ruvnet/ruflo --skill witness -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about witness
How to install witness in Claude Code?
Run npx skills add ruvnet/ruflo --skill witness -a claude-code. The files will be placed in ~/.claude/skills/witness/SKILL.md.
What does witness do?
It creates signed Ed25519 manifests tracking documented fixes against marker substrings. When a marker disappears from the source file, it reports a regression.
What dependencies are needed for signing?
You need to install @noble/ed25519 via npm. Authoring keys can be pinned through the RUFLO_WITNESS_SEED and RUFLO_WITNESS_PUBLIC_KEY environment variables or CLI flags.
Source text
SKILL.md · MIT
---
name: witness
description: Sign, verify, and track fix-marker regressions over time using an Ed25519 witness manifest. The default seed is public-commit-derived (integrity only); set RUFLO_WITNESS_SEED/RUFLO_WITNESS_PUBLIC_KEY for authorship. Works in any project — clone the toolkit, run init, register fixes, regen on each release.
argument-hint: "init|regen|verify|history [...]"
allowed-tools: Bash(node *), Read, Write, Edit
---
# Witness — tamper-evident fix-regression tracking
The witness toolkit lets you ship every release with a *signed* manifest
that lists every documented fix in your codebase along with a sha256 +
marker substring. By default the signing seed is derived from the public
git commit, so anyone can reproduce the signature: this is an integrity
checksum, not proof of authorship. For authenticity, sign with a 32-byte
`RUFLO_WITNESS_SEED` and verify with a pinned `RUFLO_WITNESS_PUBLIC_KEY`.
A temporal history (JSONL) tracks how the fix population evolves across
releases — so when a regression appears, you can pinpoint *the commit
that introduced it*, not just "it's broken now."
This skill works two ways:
1. **Inside ruflo** — used by ruflo's own CI to gate publishes (see
`.github/workflows/v3-ci.yml` job `witness-verify`).
2. **In your own project** — copy `plugins/ruflo-core/scripts/witness/`
into your repo, run `init.mjs`, register your fixes in
`witness-fixes.json`, and call `regen.mjs` from your release pipeline.
## Quick start (any project)
```bash
# One-time bootstrap — creates verification.md.json,
# verification-history.jsonl, and witness-fixes.json template
node plugins/ruflo-core/scripts/witness/init.mjs --root .
# Edit witness-fixes.json: add { id, desc, file, marker } per fix.
# A "marker" is a distinctive substring that MUST appear in `file`
# while the fix is present. If someone reverts the fix, the marker
# disappears and `verify` reports it as `regressed`.
# Regenerate the manifest (signing requires @noble/ed25519)
npm i @noble/ed25519
node plugins/ruflo-core/scripts/witness/regen.mjs \
--manifest verification.md.json \
--history verification-history.jsonl \
--fixes witness-fixes.json
# Verify markers are present in the live tree
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json
# Or authenticate the manifest and check source markers in a clean clone.
# Generated dist/ entries are explicitly reported as skipped.
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json --source-only
# For a CI hash tripwire, also fail when a file changes but its marker remains.
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json --source-only --strict
# Authenticity: pin a release public key (the flag wins over the env var).
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json --public-key <64-hex-public-key>
```
Without `--strict`, marker-preserving SHA drift is reported but exits 0.
`--strict` makes that drift exit 1 without changing signature or missing-file checks.
## Temporal queries (ADR-103)
```bash
# Latest snapshot vs. previous
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl summary
# For each currently-regressed fix, find the commit that introduced it
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl regressions
# Status timeline for a specific fix
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl timeline --id F1
# Machine-readable for CI
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl summary --json
```
`summary` exits non-zero if any fix newly regressed since the last
snapshot — drop it in CI as a soft pre-merge gate.
## Anti-patterns
- **Hand-editing `verification.md.json`** — always regenerate via `regen.mjs`,
otherwise the signature breaks.
- **Markers that are too generic** (`'function'`, `'import'`) — pick something
unique enough that `grep` doesn't false-positive against unrelated code.
- **Skipping the history append** — without `--history`, you lose the
ability to bisect when a regression was introduced.
- **Committing one without the other** — `verification.md.json` and
`verification-history.jsonl` belong in the same commit; the JSONL is
what lets future you verify the signed manifest is the latest in the line.
## Files
- `scripts/witness/lib.mjs` — shared regenerate / history logic.
- `scripts/witness/regen.mjs` — CLI: sign + append history.
- `scripts/witness/history.mjs` — CLI: query the temporal log.
- `scripts/witness/init.mjs` — CLI: bootstrap into a fresh project.
- `scripts/witness/verify.mjs` — CLI: validate signature + markers.
## In ruflo's CI
`v3-ci.yml` job `witness-verify` runs after the behavioral smoke tests
and before `publish`. Failure modes:
| Failure | Cause |
|---|---|
| `signatureValid: no` | manifest hand-edited; re-run regen |
| `regressed: > 0` | a documented fix lost its marker since issuance |
| `missing: > 0` | a cited dist file no longer exists; rebuild or remove the entry |
| `scope: source-only` | signature + source markers checked; generated entries intentionally skipped |
© ruvnet · MIT · ruvnet/ruflo