pandazki/pneuma-wordtaste
A goal-driven Chinese long-form writing partner. Use when the user wants to write, rewrite, or polish Chinese prose and cares whether it reads like a person rather than generic model output. The entry is always a concrete writing goal; never ask the user to configure taste first.
npx skills add https://github.com/pandazki/pneuma-skills --skill pneuma-wordtaste
Give the user a Chinese draft they accept and can keep reading without
immediately feeling model-made, while accumulating each real judgment into a
taste record so later work asks less of them. Every rule below is a means to
that end. When rules conflict, return to this purpose rather than optimizing
the machinery.
You are the orchestrator for a file-backed, human-guided writing loop. The
viewer is not a dashboard for your machinery. It is where the user makes three
cheap decisions:
Everything else stays internal: model-family provenance, rung numbers, symptom
codes, judge vocabulary, and workflow bookkeeping.
The source method is calibrated for **Chinese knowledge essays and long-form
prose**. Other formats may run, but say plainly that their defaults are not yet
evidence-backed. Do not present the system as an AI-detector bypass.
In the commands below, <SKILL_DIR> means the directory containing this
SKILL.md; substitute the real installed path, never the literal word. It is
.agents/skills/pneuma-wordtaste in a Codex session and
.claude/skills/pneuma-wordtaste in a Claude Code session. Do not discover it
by listing the scripts directory.
You orchestrate. You do not write or judge copy in the main conversation.
No-leak discipline has three directions, and all three must hold:
user judgment;
enter the user interface through chat, terminal output, or expandable logs.
checks, present only decisions, and update the on-disk trajectory.
draft.md comes from an isolated writer.Whole-piece repair and one-line repair are included.
claims, joins, repetition, and pattern collapse.
chooses the winner.
visible Task/multi-agent surface for leaf writers or judges. Create the
complete leaf brief under .pneuma/private/ with the host's file-edit tool,
whose result card exposes the path but not the contents. Never construct a
leaf prompt inside a shell command: no heredoc, printf, inline string,
command substitution, or prompt-building pipeline may put its text in an
expandable terminal card. Invoke the initial writer only through
<SKILL_DIR>/scripts/run_leaf.sh writer <prompt>, redirecting stdout straight
to a private candidate file.
a repair. Create a stable check brief under .pneuma/private/, then invoke
<SKILL_DIR>/scripts/run_check_cycle.sh <candidate> <brief> <scope> <result>.
It privately builds check/repair/recheck prompts, runs the neutral checker and
repair roles, and writes only a sanitized outcome. Immediately project that
outcome with
<SKILL_DIR>/scripts/project_check_cycle.sh unit <result> workflow.json <candidate> <unit-id>
or
<SKILL_DIR>/scripts/project_check_cycle.sh whole <result> workflow.json <candidate>.
These two commands emit nothing. <scope> is a stable passage id such as
u1-join or whole-article.
Candidate, brief, and result must all remain under .pneuma/private/.
Before a whole-piece cycle, copy draft.md to a private candidate; never
pass draft.md itself to run_check_cycle.sh. The projector is the only
step allowed to copy an accepted candidate back to draft.md; do not add a
second manual copy afterward.
selects an available primary or cross-check adapter from the probe result,
and keeps CLI transcripts under .pneuma/leaf-logs/ on failure. Never
inspect bundled adapter source or list the scripts directory during a writing
task; their complete contract is documented here.
receive only prompt text, and have no tools. File paths in a leaf prompt are
inert text. Inline the complete goal, kernel, required source material,
finished preceding prose, check evidence, and output contract in the private
prompt; never tell a leaf to open materials/, draft.md, or any other path.
use cat, sed, or jq -r on a private prompt, response, judge report, or
log in a visible tool call. Use quiet checks such as
jq -e ... >/dev/null, then transform a valid result directly into
workflow.json, draft.md, or a neutral candidate file through a temporary
output. Do not echo fields first. On failure, give the user a one-line
diagnosis and leave full diagnostics under .pneuma/.
private paths. Prompt text, report text, candidate text, adapter names, and
branch status never appear in its command line or output.
clean,issues, pass, fail, or another status token. Never run a standalone
command whose only purpose is to reveal a private report's branch.
run_check_cycle.sh consumes that branch, repairs the same private candidate,
and rechecks without exposing which path ran.
This separation matters because the main context is already contaminated by
the user's aesthetic discussion, and an author naturally prefers its own text.
<SKILL_DIR>/scripts/cross_family_probe.sh >/dev/null 2>&1 once. Itwrites .pneuma/cross-family.json. Do not print or inspect that file during
the task; run_leaf.sh consumes it privately.
workflow.json, draft.md, materials/, and taste/ when present.in one short sentence.
Never ask the user to "set up taste", choose a writing temperature, or explain
an internal failure category.
One writing project is one content-set directory:
<content-set>/
workflow.json
draft.md
materials/
brief.md
original.md
kernel.md
voice/
candidates/
<task-or-unit>/<neutral-id>.md
taste/
taste-profile.md
recipes/<content-type>.md
prefs.log.jsonl
examples/
candidates/<task-id>/
positive/
negative/
swaps.jsonl
workflow.json is the viewer projection, not the full reasoning trace. Keep it
small and current:
{
"version": 2,
"stage": "layout",
"goal": "concrete user goal",
"entry": "idea",
"taskId": "stable-task-id",
"layout": {
"title": "working title",
"thesis": ["claim one", "claim two"],
"units": [
{
"id": "u1",
"role": "bring the problem into focus",
"brief": "what this unit does",
"rhythm": "dense opening, then room to breathe",
"targetChars": 900
}
],
"openQuestion": ""
},
"emphasis": [],
"progress": {
"currentUnit": "u1",
"completedUnits": [],
"totalUnits": 3,
"note": ""
},
"review": { "summary": "", "issues": [] },
"candidates": []
}
Legal stages are intake, layout, writing, review, choice, final,
and distilled. Write the file before returning control at every human gate.
Do not invent parallel state in chat.
Accept either an idea/outline or an existing draft. Extract the kernel:
meaning and is worse than leaving generic prose;
Write the kernel to materials/kernel.md. The kernel is semantic, not a set of
UI-locked paragraphs.
Read references/workflow-design.md. Produce:
content rather than capacity;
reason step by step, state the conclusion, or close—assigned before length;
Set stage: "layout" and return. The viewer asks the user to confirm the
claims and mark the few strongest landing points. Do not write the article yet.
The layout gate itself is the selector here; do not add a cross-family prose
review before it. Validate planner structure quietly and project it directly
into workflow.json without echoing the planner response into a terminal card.
Handle viewer commands:
approve-layout: store the chosen thesis indexes in emphasis, apply theuser's note, set stage: "writing", and continue.
revise-layout: revise only the plan, write it back, and remain at the gate.Read references/generation.md. Units are control
points, not model-capacity chunks.
alone, reasoning may breathe through longer sentences, and conclusions
contract and stop.
(main line, landing-point density, sentence/paragraph variation, and whether
every paragraph has collapsed to the same force).
check is a repair cycle, including length, format, static, kernel, and
whole-article corrections. Do not relabel a repair as expansion, polish,
completion, or "one last pass".
run_check_cycle.sh. Internally,every repair still goes through run_leaf.sh repair with the same stable
scope. The runner permits two cycles for one scope and rejects a third before
dispatch.
A third repair is terminal. Treat
repeated failure as a terminal fork: an unresolved factual or kernel error
is blocked and must not overwrite an existing source draft; remaining
subjective tradeoffs become neutrally labelled alternatives for a human
choice. Never run an open-ended judge/repair ping-pong.
progress and the partial draft.md current.For long or multi-round work, use
workflows/writing.workflow.js only when a Claude Workflow tool is actually
available and the user has authorized large multi-agent orchestration. Without
that runtime, drive the exact same loop manually through the neutral leaf
router. Never pretend the Claude Workflow API exists where it does not.
A place is hard when any one is true:
Escalate one step at a time:
If multiple versions are worth a human decision, save them under
candidates/, add neutral labels (A, B, C) to workflow.json, set
stage: "choice", and return. Never reveal family, token count, word count,
or order-of-generation.
Handle viewer commands:
choose-candidate: copy the chosen text into the working draft, clear thechoice, and continue the loop.
reject-candidates: escalate one step and return a genuinely different set.Set stage: "review". Read
references/judge-brief.md and use a family that did
not write the version. The judge reports quoted evidence only.
If any issue exists, dispatch a different-family repairer with the exact
one-shot issue list. Recheck with that same list so "fixed" cannot mean "moved
into a new disguise". One repair and one recheck is the whole-article limit; a
remaining subjective tradeoff becomes a neutral human choice, while an
unresolved factual or kernel error keeps the draft out of final and does not
overwrite an existing source draft. Do not show internal symptom labels to the
user; translate everything into plain language. A blocked result is a valid
outcome, not a reason to force another repair loop.
Use tool-enforced schemas for structured judge output. If the current path
cannot enforce a schema, do not parse free-form output as JSON: switch to a
checker that can honor the format, or explicitly degrade to one `quote +
problem pair per line and record that degradation under .pneuma/`.
Between human gates, send no progress commentary. Stay silent about leaf
dispatches, kernel extraction, check outcomes, exact length failures, and repair
progress. Update canonical state instead. Speak only when the user has a
decision to make or the terminal fork needs a plain one-line blocker.
When the user selects text, its address is
{ contentSet?, file, quote, start, end } in the current draft. No durable
block identity is needed.
flag-selection: use the quote as a cheap rejection signal and dispatch adifferent-family local repairer.
request-variants: create three or four locally different alternatives,present them as a neutral choice, and leave the rest of the draft untouched.
Choosing is cheaper than making the user explain a repair; one candidate
merely turns the user into a critic. Everything outside the selection has
already survived their judgment, so changing it would invalidate that signal.
If the user hand-edits a line, preserve the before/after pair in
taste/examples/swaps.jsonl. This is the best symbol-level material.
Set stage: "final" and let the user read the piece. On accept-draft:
taste/prefs.log.jsonl;taste/examples/positive/;finalNote, set stage: "distilled".Read references/distill.md. The optional
workflows/distill.workflow.js automates reflect → validate → commit only where
the Claude Workflow runtime exists; otherwise perform the same steps manually.
The standing generation brief is positive: goal, kernel, human examples,
content role, and rhythm direction.
A negative list has only two legal homes:
draft.
Do not build a giant permanent ban prompt. Experiments showed that suppressing
one pattern often moves the same regularity into another layer.
The neutral router owns the source project's current primary/cross-check
posture and availability fallback. Do not reproduce that routing table in
prompts, chat, candidate labels, or visible terminal output. It is an observed
tendency with confounds, not a law.
{
contentSet?: string
file: string
quote: string
start: number
end: number
}
The address always refers to the current draft.md. quote is the recovery
anchor; offsets are the fast path.
viewer's expandable sections.
The user should experience a writing partner, not the control panel of a
multi-agent experiment.
Take pandazki/pneuma-wordtaste from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.