Skip to content
Back to skills

Voice Critic

ASecurity

filter-tells detects "sounds like a machine". This critic detects two different failures: "doesn't sound like Petar" and "went too far". The rubric is `writing-voice/voice-constitution.md` — discovered by the standard walk-up, refused when absent, because the critic's taste is that file, not anything built in. Rates come from `idiolect.yaml`, the single source of truth the constitution itself defers to. **Read-only is the contract.** `scripts/voice_critic.py` takes a document and produces a r...

  • 5 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 3, 2026
ai-agentspythongobash

Works with

  • terminal

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 3, 2026

npx -y skills add petar-djukic/writing-skills --skill voice-critic --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Voice Critic?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Voice Critic
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/petar-djukic-voice-critic/badge)](https://www.skillsdirectory.com/skills/petar-djukic-voice-critic)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
<!-- Copyright (c) 2026 Petar Djukic. All rights reserved. SPDX-License-Identifier: MIT -->
---
name: voice-critic
description: >-
  Cold, read-only gatekeeper against writing-voice/voice-constitution.md:
  five per-dimension verdicts with flagged spans — stance, theory-of-mind
  device, disproportion (locked-span check), computed marker profile
  against idiolect targets, and a snark audit on the constitution's L0-L5
  scale with receipt-first, safe-enemy, and per-form density-cap hard
  rules. Never edits; flags route to the author gate. Triggers: voice
  critic, does this sound like me, snark audit, constitution check, voice
  gate, critique voice, off-voice check.
---

# Voice Critic (read-only gatekeeper)

filter-tells detects "sounds like a machine". This critic detects two
different failures: "doesn't sound like Petar" and "went too far". The
rubric is `writing-voice/voice-constitution.md` — discovered by the
standard walk-up, refused when absent, because the critic's taste is that
file, not anything built in. Rates come from `idiolect.yaml`, the single
source of truth the constitution itself defers to.

**Read-only is the contract.** `scripts/voice_critic.py` takes a document
and produces a report; it never modifies the input, and the tests assert
input bytes unchanged. That is why it may run after the terminal
inject-vernacular stage — its home is the caller's review phase (GH-208),
after critic-panel — and equally at any earlier gate; nothing in it
assumes pipeline position. It is not a stage of the humanize chain.

**The critic flags; the author adjudicates.** It replaces self-monitoring
with a checklist, not with enforcement: over-ceiling snark is flagged,
never auto-deleted, and every flag carries the quoted span and line range
so the gate read is a yes/no per item.

## The five dimensions

| dimension | how | what it asks |
|---|---|---|
| stance | judged | Expert-watching, curiosity not contempt (§1)? At the bench, not the balcony? |
| tom-device | screened + judged | Model stated → predictions derived → tested against the artifact (§2)? The deterministic screen finds candidate evidence for each of the three parts; the judge (or the author) says whether the device is executed. |
| disproportion | computed | One declared overrun present and protected? Span locks are the declaration mechanism, so this reads the drivers' lock report. |
| marker-profile | computed, never judged | idiolect.yaml regex rates against essay targets, ±30% tolerance — the same arithmetic inject-vernacular applies as operators, run here as a check. |
| snark-audit | judged instances, computed rules | Every instance scored L0–L5; then the three hard rules run mechanically over the instances. |

## Snark scale and hard rules (constitution §4)

Levels: L0 none · L1 dry aside · L2 pointed irony with receipt · L3 open
mockery of an artifact (polemic only) · L4 contempt for a class · **L5
ridicule of a person — never**, always a violation.

Hard rules, checked mechanically over judge-identified instances:

1. **Receipt-first.** A receipt (number, percentage, citation, quoted
   material) must appear before the joke — earlier in the same paragraph,
   or anywhere in the preceding one (the factual-run-then-verdict shape).
2. **Safe-enemy only.** Allowed targets: artifact, institution, category,
   the dead, past self. A person target is a violation.
3. **Density caps** per 1000 words by form, counting L1 and above:
   how-to 1, essay 2, polemic 3 (`--form`, default essay).

Any hard-rule violation makes the snark dimension FAIL and the flagged
instances land in the report for the author gate.

## Judged vs computed, and the judge's leash

Computed dimensions are deterministic and run offline. Judged dimensions
use a model **in read-only mode**: it returns verdicts, levels, and exact
quotes — its text is never spliced anywhere. `--judge` wires an Ollama
model (`--model`, `--endpoint`; unreachable-when-requested is a hard
error, no silent fallback). Without a judge, judged dimensions report
`UNJUDGED` with their screen evidence, and the author gate adjudicates —
which is the normal offline mode, not a degraded one.

## The unhedged-prediction work list (for inject-vernacular)

Beside the five verdict dimensions, a judged report carries
`unhedged_predictions`: sentences that state a claim about a mind —
beliefs, motives, future behaviour — with no hedge and no receipt,
identified by the judge and then receipt-filtered mechanically (a
sentence carrying a number or citation is dropped; the bank never hedges
a receipted claim). Each entry has the paragraph index, line range, and
exact quote. It is a work list, not a verdict: feed the report to
`inject_vernacular.py --critic-flags report.json` and its i-think
RESTORE operator applies the hedge deterministically at those spans.
Without a judge the list is empty — the offline mode. The read-only
contract holds: the critic names the spans, the terminal stage does the
writing.

## Scope boundary with filter-tells

- **filter-tells**: machine tells — AI lexicon, structural patterns, CoT
  leakage. Register-generic; a document by any author can fail it.
- **voice-critic**: this author's constitution — stance, method,
  signature-marker rates, snark governance. A flawlessly human text by
  someone else fails it; that is the point.

Run both: they catch disjoint failures, and after GH-57's calibration work
filter-tells reads the same idiolect.yaml so the two never fight over
constructions native to the voice.

## Usage

```bash
# offline: computed dimensions + screens, judged dimensions UNJUDGED
python3 scripts/voice_critic.py draft.md

# full: judged dimensions through a local model (read-only)
python3 scripts/voice_critic.py draft.md --judge                # cohere default (GH-190)
python3 scripts/voice_critic.py draft.md --judge --model gemma4:12b   # keyless/local

# polemic caps, machine-readable report for the gate checklist
python3 scripts/voice_critic.py draft.md --form polemic --json --report out.json
```

Exit 0 when no dimension FAILs, 1 otherwise. Tests:
`scripts/test_voice_critic.py` (offline; stub judges, no network).

Files in this skill

  • SKILL.md6.1 KB
  • scripts/test_voice_critic.py13.6 KB
  • scripts/voice_critic.py22.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.