# Autonovel Grade

> Autonovel manual grading — user-triggered quality report. Runs every mechanical detector (slop_detect, slop_ngrams) plus the sentence-grading pass over a scope ('chapter 7', 'chapters 3-9', 'manuscript') and writes critique/slop_report_<scope>.md: a self-contained report the user can fix by hand or paste into a stronger model. NOT part of the autopilot path — the pipeline never invokes or waits o…

- **Type:** Skill
- **Install:** `agentstack add skill-duketwocan-autonovel-agent-skills-autonovel-grade`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [DukeTwoCan](https://agentstack.voostack.com/s/duketwocan)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [DukeTwoCan](https://github.com/DukeTwoCan)
- **Source:** https://github.com/DukeTwoCan/autonovel-agent-skills/tree/main/skills/creative/autonovel-grade

## Install

```sh
agentstack add skill-duketwocan-autonovel-agent-skills-autonovel-grade
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Autonovel — Grade (user-triggered, manual quality report)

Run every mechanical slop detector plus the sentence-grading pass over a scope and write a self-contained report. This skill is user-triggered only — it is never part of the autopilot path, never invoked or waited on by the pipeline, and never invoked by any other skill.

## When to use this skill

- User says "grade chapter N", "grade the manuscript", "how sloppy is chapter N", or "give me a slop report"
- User is reviewing the `needs_attention` queue in state.json (populated by the drafting skill's surgical-rewrite stall rule — see `autonovel-drafting/references/retry-policy.md`) and wants a detailed report on the flagged chapters before deciding whether to fix them by hand or hand them to a stronger model
- Never invoked automatically — this skill only runs when the user asks for it directly

## Prerequisites

```
!`test -d "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/chapters" && ls "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/chapters" | head`
```

The novel needs at least one drafted chapter.

## Workflow

### Step 1 — Resolve scope

The user supplies a scope: a chapter, a range, or `"manuscript"` for everything. Use `autonovel-prose-review/references/scope-resolver.md` (reference it, don't duplicate its logic) to map natural-language scopes to chapter ranges. If the scope is ambiguous, ask the user to clarify and show your interpretation before proceeding.

### Step 2 — Check state.json for needs_attention

Read `$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/state.json`. If `needs_attention` is non-empty:
- Any entry with a `chapter` number that falls inside the resolved scope must be covered in the report regardless of how it scores mechanically — call it out explicitly in the summary.
- An entry with `"chapter": null` is a systemic pattern note (3+ consecutive chapters stalled during drafting). Surface its `note` text verbatim at the top of the report's Summary section — it usually points at an outline or foundation problem, not chapter-level slop, and the user needs to see it before reading chapter-level findings.
- If the user's scope doesn't include a flagged chapter but `needs_attention` has entries, mention their existence and chapter numbers in passing so the user can re-run with a wider scope.

Also read `genre_context/story-contract.md`,
`genre_context/compiled/evaluation-chapter.md`, and
`genre_context/resolved.json`. The first two supply the story-specific and
selected-pack evaluation criteria for the report; `resolved.json` supplies the
generated pattern bundle and provenance.

Assemble a separate current `PROFILE REQUIREMENTS` block for each chapter in
scope. The assembler reads `profile.rating` and `profile.content_tags` from
`state.json`, normalized tags and literal exclusions from
`genre_context/resolved.json`, the coverage map from `outline.md`, and the
matching rating definition from `../autonovel/references/ratings.md`:

```
!`python ${HERMES_SKILL_DIR}/../autonovel/lib/profile_requirements.py --state "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/state.json" --resolved "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/genre_context/resolved.json" --outline "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/outline.md" --ratings "${HERMES_SKILL_DIR}/../autonovel/references/ratings.md" --chapters `
```

The assembler reads the outline's Content-Tag Coverage Map and includes only
the content tags assigned to that chapter. Use that chapter's block in its
grading call and report section. Keep blocks current if state, outline, or
resolution changes. For manuscript scope, separately audit every state
`profile.content_tags` entry against the complete coverage map and manuscript;
report undelivered coverage as a manuscript-wide finding rather than injecting
all tags into every chapter's block.

### Step 3 — Run the mechanical detectors

Using this skill's own vendored libs (never the ones in a different skill's `lib/`), for each chapter file in scope, in order, run the slop scan:
```
!`python3 ${HERMES_SKILL_DIR}/lib/slop_detect.py "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/chapters/" --genre-context "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/genre_context/resolved.json"`
```
Then run the manuscript-wide repetition scan over ALL chapters (repetitions are manuscript-relative even when grading a single chapter — a phrase repeated in chapters outside the scope still matters if it also occurs inside it). Read `slop.ngram_min_count` from the novel's state.json and pass it explicitly rather than relying on the silent default:
```
!`python3 ${HERMES_SKILL_DIR}/lib/slop_ngrams.py "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/chapters" --min-count `
```
Import both `slop_report` AND `find_spans` from the vendored
`lib/slop_detect.py`, `load_patterns_from_resolved` from the vendored
`lib/genre_patterns.py`, and
`scan_manuscript(texts, min_count=)` from
`lib/slop_ngrams.py`. Load the generated tuple once per Grade run, then pass
that same tuple to both detector functions for each chapter:

```python
from genre_patterns import load_patterns_from_resolved
from slop_detect import find_spans, slop_report

genre_patterns = load_patterns_from_resolved(
    "$AUTONOVEL_WORKSPACE/$NOVEL_SLUG/genre_context/resolved.json"
)
spans = find_spans(chapter_text, genre_patterns=genre_patterns)
report = slop_report(chapter_text, genre_patterns=genre_patterns)
```

`find_spans` gives the exact matched text, position, ±80-char context, and
selected-pattern provenance the report needs; `slop_report` gives the
bounded-metric numbers (opener monotony, suddenly count, adverbed tags, etc.).
Aggregate selected-pattern spans by `(pack_id, pattern_id)` and retain each
pattern's `severity` and allowed `max_count` in its report row. Evaluate the
chapter against the story contract and evaluation packet as a semantic section
of the report; Grade remains read-only.

Note: the `chapter` values in slop_ngrams occurrence records are 0-based indices into the sorted `ch_*.md` file list — convert them to the file's NN chapter number when writing the report.

### Step 4 — Run the sentence-grading pass

Run the grading prompt from `autonovel-drafting/references/sentence-grading.md` on each in-scope chapter. This is the one step in this skill that calls the LLM — it happens at runtime, when the user runs this skill via the Hermes agent, not as part of building or testing this skill. Parse the output with `lib/grading.py` `parse_grades()` and compute `grading_gate(grades, max_weak_ratio, max_cut, expected_count=N)` per chapter — limits from state.json's `slop` config, N = the number of sentences you numbered so the gate fails loudly if the model skipped any — plus `flagged_sentences()` for the WEAK/CUT indices. For chapters over ~4k words use `lib/chunk_text.py` `chunk_by_token_budget` to split the grading prompt (sentence numbering continuous across chunks) (budget per sentence-grading.md's 50k rule).

Prepend the current chapter's dynamic genre inputs to every grading call in
this order:

```
GRADE REVIEW INPUTS

PROFILE REQUIREMENTS:
{PROFILE_REQUIREMENTS}

STORY CONTRACT:
{STORY_CONTRACT}

GENRE EVALUATION:
{GENRE_EVALUATION_BLOCK}
```

Fill the last two placeholders from `genre_context/story-contract.md` and
`genre_context/compiled/evaluation-chapter.md`. The sentence-grading result and
the semantic grade report therefore evaluate the same current restrictions.

### Step 5 — Assemble the report

Write `critique/slop_report_.md` per `references/report-format.md`. Scope slug follows the same convention as prose-review: `ch07`, `ch07-10`, `manuscript`.

### Step 6 — Report to the user

Report the file path and a short summary (chapters graded, findings count, WEAK/CUT ratio, needs_attention count) to the user. Do NOT modify any chapter and do NOT touch state.json.

## Explicit note — read-only, user-triggered only

This skill only READS the manuscript and state.json, and only WRITES the report file. It never edits chapters, never updates state.json (not even to clear `needs_attention` — that queue is cleared by the phase skill that actually fixes the flagged chapter, not by this one), never advances `phase`, and is never invoked by another skill. It is not part of the autopilot path — the pipeline never invokes or waits on this skill.

## Library utilities

- `lib/slop_detect.py` — mechanical slop detection: `slop_report` for the metric breakdown, `find_spans` for exact finding locations with context (no LLM)
- `lib/slop_ngrams.py` — manuscript-wide repeated-phrase scan (no LLM)
- `lib/grading.py` — sentence-grading parse + deterministic acceptance gate
- `lib/chunk_text.py` — for scopes longer than the sentence-grading chunk budget

## See also

- `references/report-format.md` — the report structure
- `autonovel-prose-review/references/scope-resolver.md` — natural-language scope → chapter range mapping
- `autonovel-drafting/references/sentence-grading.md` — the sentence-grading prompt and processing rules
- `autonovel-drafting/references/surgical-rewrite.md` — what generated any mechanical findings still present
- `autonovel-drafting/references/retry-policy.md` — how `needs_attention` entries get written and what their fields mean

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [DukeTwoCan](https://github.com/DukeTwoCan)
- **Source:** [DukeTwoCan/autonovel-agent-skills](https://github.com/DukeTwoCan/autonovel-agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-duketwocan-autonovel-agent-skills-autonovel-grade
- Seller: https://agentstack.voostack.com/s/duketwocan
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
