Lektorat Auto-Revise
Operationalises spec/project/lektorat-auto-revise/ for the nolte-shared plugin: the autonomous bridge from an existing lektorat audit findings report to a finished, re-verified artefact. It consumes the audit, routes each affected artefact to the author best suited to its type, composes a per-file briefing, lets that author revise, and re-audits until the artefact converges.
This skill binds the spec's contract to an on-disk procedure. It owns no editorial rules of its own — severities, dimensions, scope, audience binding, and semantic-preservation guarantees belong to spec/project/lektorat/; the writing-style and audience rules belong to the dispatched author's bound specs. When this skill and a spec disagree, the spec wins and this skill needs the update.
German trigger phrases
This skill also triggers on equivalent German-language requests, including:
- "arbeite das Lektorat-Audit automatisch ab"
- "lass den passenden Author die Findings abarbeiten"
- "vollautomatische Lektorats-Remediation"
- "revidiere die Audit-Findings automatisch"
User-language policy
Detect the user's language from their message and respond in it. The machine-readable JSON output uses English keys (mirroring spec/project/lektorat/ §Outputs); the human-readable summary.md uses English section headings so downstream tooling can parse it; prose around the report is localised.
Why this is a skill, not an agent
- The blog route's interactive touchpoint is load-bearing:
blog-author is an interactive skill whose briefing inputs (topic-as-thesis, source list, slug, cross-language binding key) can't be reconstructed from findings; surfacing that dialogue back to the operator only fits a skill.
- Externally visible writes: outputs land under
.audits/lektorat-auto-revise/<YYYY-MM-DD-HHMM>/ and the dispatched author edits in-scope artefacts in place; the skill owns the persistent on-disk state.
- Orchestration role: the skill dispatches the
audience-doc-author agent and the blog-author skill, re-runs the lektorat audit for the convergence gate, and stays in the main thread to compose briefings, run the assisted-blog dialogue, and write outputs.
- Counter-dimension considered: the documentation route alone is fire-and-forget and would fit an agent, but consolidating both routes plus the convergence loop behind one entry point keeps the operator's mental model coherent and is where the load-bearing interactivity lives.
Inputs
- Audit report (required): a path to an existing
.audits/lektorat/<YYYY-MM-DD-HHMM>/findings.json, or a directive to run a fresh lektorat-apply audit first and consume its output. The report's shape is spec/project/lektorat/ §Outputs; consume it verbatim and never add, drop, or rename a field.
- Severity floor (optional): inherited from the input run; defaults to addressing every
critical and warning finding. A caller may narrow to critical for a de-noised pass.
- Audience-artefact path (optional): resolved through the same priority chain as
lektorat §Audience binding; a missing artefact stops per-file remediation with the message pointing at audience-identify.
Procedure
Run the steps in order. Each maps to a requirement block in the spec; consult the spec for the authoritative rules rather than relying on this summary.
- Resolve the audit report (§Input contract). Load the
findings.json. Process only the findings array. For any file named in an inventory_findings entry, do not dispatch an author — surface the infrastructure condition to the operator instead.
- Group findings by
file so each artefact is handled once with the full set of its findings.
- Route each file (§Artefact-type routing) into exactly one class before any dispatch:
documentation (MkDocs page under docs/<lang>/, top-level Markdown, or a GitHub Release/Issue/PR body) → audience-doc-author agent.
blog-post (carries the consumer's cross-language binding key, e.g. translationKey, in its frontmatter) → blog-author skill.
rejected (any path lektorat §Scope and applicability excludes — spec/, skills/**/SKILL.md, skills/**/templates/**, skills/**/examples/**, agents/*.md, source, generated config) → hard-reject with a one-sentence message naming the owning flow; dispatch no author.
- A file matching none of the three classes stops the whole run with an operator-facing message; never silently skip it.
- Compose the briefing per file (§Author briefing composition): the file's findings verbatim, the resolved audience set (via the
lektorat priority chain, no other rule), the bound writing-style spec(s), and the target D1–D6 dimensions. For any file with a D1 readability finding, also pass the LIX target inputs per spec/project/readability-lix/ §Iterative improvement loop: the current lix, the resolved corridor (aim/warn/crit for the file's content_mode and language), and the dominant lever (ASL or LWP), so the author's pass targets the right readability lever. Never dispatch an author without both a resolved audience set and a bound writing-style spec — a missing either is a per-file stop condition.
- Dispatch the matching author (§Autonomy and human touchpoints):
- Documentation → dispatch
audience-doc-author fully autonomously (no per-finding approval, no diff gate). Pass the audience-artefact path, the doc-type spec, the prose-style baseline, and the file under revision.
- Blog → run assisted: surface the findings-derived briefing to
blog-author and let its briefing touchpoint stand. Never fabricate the briefing inputs it requires.
- Never rewrite prose in this skill; the rewrite is always the author's.
- Re-audit convergence gate (§Re-audit convergence gate). After each author pass, re-run the
lektorat audit on the revised artefact with the same configuration. A file is converged only when it has no remaining finding at or above the severity floor and its post-revision finding count is ≤ its pre-revision count. A D1 readability finding converges only when the re-audit shows LIX at or below the file's warn corridor (readability-lix §Iterative improvement loop); a LIX drop achieved by a forbidden transformation (decompounding an established term, vaguer-shorter swaps, altering a protected term) is a semantic-preservation failure, not convergence. On non-convergence, re-dispatch the author with the residual findings up to 2 author passes per file, then escalate the residual to the operator — never loop further. Flag any regression (post-count higher than pre-count, or a risen LIX) and never auto-accept it as converged. Treat any semantic-preservation violation (§Semantic preservation) as a failed pass.
- Write the run trail (§Outputs) under
.audits/lektorat-auto-revise/<YYYY-MM-DD-HHMM>/: routing.json, run.json (referencing the source audit run), per-file rewrite diffs with pre/post counts and pass count, and summary.md. List escalated and regressed files first in summary.md so unremediated findings can't be overlooked.
Hard rules
- Never define, re-classify, or re-weight findings, severities, or dimensions; consume the
lektorat report verbatim. The rules live in the spec, not here.
- Never dispatch an author without both a resolved audience set and a bound writing-style spec. "No audience" and "no style spec" are stop conditions, not soft defaults.
- Never rewrite prose in this skill — every rewrite is delegated to the routed author, so the author's audience and writing-style competence applies.
- Never run the documentation route with a human gate, and never run the blog route without
blog-author's briefing touchpoint.
- Never mark a file converged while it has a finding at or above the severity floor or a regression; never loop past 2 author passes — escalate instead.
- Never route or dispatch an author at a
rejected-class path; never widen the routing table to a class lektorat forbids.
- Never silently skip an unroutable file or truncate unremediated findings — stop the run or escalate, and record it.
Gotchas
Per spec/claude/skill-management/ §Gotchas: concrete corrections to non-obvious environment facts the executing agent would otherwise get wrong.
- Finding IDs aren't stable across a rewrite, so convergence is judged by count and severity — never by ID diff. The
findings.json id is a hash of file + dimension + line; once an author rewrite shifts line numbers, the re-audit re-keys every finding. Compare the re-audit's per-file finding count and highest severity against the pre-revision snapshot; matching IDs across passes will spuriously miss both regressions and fixes.
- A lower LIX number is not automatically convergence. A D1 readability finding converges only when the re-audit shows LIX at or below the file's
warn corridor (spec/project/readability-lix/ §Iterative improvement loop) and the drop was earned by a permitted transformation. A LIX reduction achieved by decompounding an established term, a vaguer-but-shorter swap, or altering a protected term is a semantic-preservation failure — treat it as a failed pass, not a win.
- Routing is decided by frontmatter and path, not by reading the prose. A blog post is identified by the consumer's cross-language binding key (e.g.
translationKey) in its frontmatter, not by living under docs/; a file under docs/<lang>/ without that key is documentation. Misrouting a blog post to the autonomous audience-doc-author route skips blog-author's load-bearing briefing touchpoint (topic-as-thesis, source list, slug), which can't be reconstructed from findings.
Examples
- Read
examples/01-documentation-route-autonomous.md when a docs/<lang>/ page with a D1 readability finding routes to the audience-doc-author agent fully autonomously and converges on the LIX corridor.
- Read
examples/02-blog-route-assisted.md when a file carrying the cross-language binding key routes to the blog-author skill and runs assisted, preserving its briefing touchpoint.
- Read
examples/03-rejected-path-and-escalation.md when a finding sits at a rejected-class path (e.g. spec/) or a file fails to converge within 2 passes and must be escalated and surfaced first in summary.md.
Resumability
Per spec/claude/resumable-work/, this skill is resumable: true. State is persisted to .resume/lektorat-auto-revise/<run-id>.yml after every successful per-file convergence and after each named phase boundary. On re-invocation, scan that directory for files with status: in_progress whose inputs: snapshot matches the current invocation; if one matches, prompt the operator with Resume run <run_id> from phase <phase> (last checkpoint <last_checkpoint_at>)? [resume / start-new / discard]. The state-file envelope and fail-closed semantics on schema or YAML errors are defined in the spec; don't duplicate them here.
1---2name: lektorat-auto-revise3description: Autonomously works off a `lektorat audit` findings report by routing each artefact by type — documentation to the `audience-doc-author` agent (fully autonomous), blog posts to the `blog-author` skill (assisted) — composing a per-file briefing that binds the audience artefact and writing-style spec, letting the author revise, then re-auditing until no finding above the severity floor remains and there is no regression. Operationalises `spec/project/lektorat-auto-revise/`. Invoke when the user asks to "arbeite das Lektorat-Audit automatisch ab", "auto-revise the audit findings", "remediate the lektorat findings with the right author", or equivalent EN/DE requests. Don't use for the read-only audit or interactive per-finding fixes (use `lektorat-apply`), or for first authorship (`audience-doc-author`/`blog-author`). Writes to `.audits/lektorat-auto-revise/<YYYY-MM-DD-HHMM>/`. Supports resume per `spec/claude/resumable-work/`.4---56# Lektorat Auto-Revise78Operationalises `spec/project/lektorat-auto-revise/` for the `nolte-shared` plugin: the autonomous bridge from an existing `lektorat audit` findings report to a finished, re-verified artefact. It consumes the audit, routes each affected artefact to the **author best suited to its type**, composes a per-file briefing, lets that author revise, and re-audits until the artefact converges.910This skill binds the spec's contract to an on-disk procedure. It owns **no** editorial rules of its own — severities, dimensions, scope, audience binding, and semantic-preservation guarantees belong to `spec/project/lektorat/`; the writing-style and audience rules belong to the dispatched author's bound specs. When this skill and a spec disagree, the spec wins and this skill needs the update.1112## German trigger phrases1314This skill also triggers on equivalent German-language requests, including:1516- "arbeite das Lektorat-Audit automatisch ab"17- "lass den passenden Author die Findings abarbeiten"18- "vollautomatische Lektorats-Remediation"19- "revidiere die Audit-Findings automatisch"2021## User-language policy2223Detect the user's language from their message and respond in it. The machine-readable JSON output uses English keys (mirroring `spec/project/lektorat/` §Outputs); the human-readable `summary.md` uses English section headings so downstream tooling can parse it; prose around the report is localised.2425## Why this is a skill, not an agent2627- **The blog route's interactive touchpoint is load-bearing**: `blog-author` is an interactive skill whose briefing inputs (topic-as-thesis, source list, slug, cross-language binding key) can't be reconstructed from findings; surfacing that dialogue back to the operator only fits a skill.28- **Externally visible writes**: outputs land under `.audits/lektorat-auto-revise/<YYYY-MM-DD-HHMM>/` and the dispatched author edits in-scope artefacts in place; the skill owns the persistent on-disk state.29- **Orchestration role**: the skill dispatches the `audience-doc-author` agent and the `blog-author` skill, re-runs the `lektorat audit` for the convergence gate, and stays in the main thread to compose briefings, run the assisted-blog dialogue, and write outputs.30- **Counter-dimension considered**: the documentation route alone is fire-and-forget and would fit an agent, but consolidating both routes plus the convergence loop behind one entry point keeps the operator's mental model coherent and is where the load-bearing interactivity lives.3132## Inputs3334- **Audit report** (required): a path to an existing `.audits/lektorat/<YYYY-MM-DD-HHMM>/findings.json`, or a directive to run a fresh `lektorat-apply` audit first and consume its output. The report's shape is `spec/project/lektorat/` §Outputs; consume it verbatim and never add, drop, or rename a field.35- **Severity floor** (optional): inherited from the input run; defaults to addressing every `critical` and `warning` finding. A caller may narrow to `critical` for a de-noised pass.36- **Audience-artefact path** (optional): resolved through the same priority chain as `lektorat` §Audience binding; a missing artefact stops per-file remediation with the message pointing at `audience-identify`.3738## Procedure3940Run the steps in order. Each maps to a requirement block in the spec; consult the spec for the authoritative rules rather than relying on this summary.41421. **Resolve the audit report** (§Input contract). Load the `findings.json`. Process only the `findings` array. For any file named in an `inventory_findings` entry, do **not** dispatch an author — surface the infrastructure condition to the operator instead.432. **Group findings by `file`** so each artefact is handled once with the full set of its findings.443. **Route each file** (§Artefact-type routing) into exactly one class before any dispatch:45 - `documentation` (MkDocs page under `docs/<lang>/`, top-level Markdown, or a GitHub Release/Issue/PR body) → `audience-doc-author` agent.46 - `blog-post` (carries the consumer's cross-language binding key, e.g. `translationKey`, in its frontmatter) → `blog-author` skill.47 - `rejected` (any path `lektorat` §Scope and applicability excludes — `spec/`, `skills/**/SKILL.md`, `skills/**/templates/**`, `skills/**/examples/**`, `agents/*.md`, source, generated config) → hard-reject with a one-sentence message naming the owning flow; dispatch no author.48 - A file matching none of the three classes stops the whole run with an operator-facing message; never silently skip it.494. **Compose the briefing per file** (§Author briefing composition): the file's findings verbatim, the resolved audience set (via the `lektorat` priority chain, no other rule), the bound writing-style spec(s), and the target D1–D6 dimensions. For any file with a **D1 readability finding**, also pass the LIX target inputs per `spec/project/readability-lix/` §Iterative improvement loop: the current `lix`, the resolved corridor (`aim`/`warn`/`crit` for the file's `content_mode` and language), and the dominant lever (`ASL` or `LWP`), so the author's pass targets the right readability lever. Never dispatch an author without **both** a resolved audience set and a bound writing-style spec — a missing either is a per-file stop condition.505. **Dispatch the matching author** (§Autonomy and human touchpoints):51 - Documentation → dispatch `audience-doc-author` **fully autonomously** (no per-finding approval, no diff gate). Pass the audience-artefact path, the doc-type spec, the `prose-style` baseline, and the file under revision.52 - Blog → run **assisted**: surface the findings-derived briefing to `blog-author` and let its briefing touchpoint stand. Never fabricate the briefing inputs it requires.53 - Never rewrite prose in this skill; the rewrite is always the author's.546. **Re-audit convergence gate** (§Re-audit convergence gate). After each author pass, re-run the `lektorat audit` on the revised artefact with the same configuration. A file is **converged** only when it has no remaining finding at or above the severity floor **and** its post-revision finding count is ≤ its pre-revision count. A D1 readability finding converges only when the re-audit shows LIX at or below the file's `warn` corridor (`readability-lix` §Iterative improvement loop); a LIX drop achieved by a forbidden transformation (decompounding an established term, vaguer-shorter swaps, altering a protected term) is a semantic-preservation failure, not convergence. On non-convergence, re-dispatch the author with the residual findings up to **2 author passes** per file, then **escalate** the residual to the operator — never loop further. Flag any **regression** (post-count higher than pre-count, or a risen LIX) and never auto-accept it as converged. Treat any semantic-preservation violation (§Semantic preservation) as a failed pass.557. **Write the run trail** (§Outputs) under `.audits/lektorat-auto-revise/<YYYY-MM-DD-HHMM>/`: `routing.json`, `run.json` (referencing the source audit run), per-file rewrite diffs with pre/post counts and pass count, and `summary.md`. List escalated and regressed files **first** in `summary.md` so unremediated findings can't be overlooked.5657## Hard rules5859- Never define, re-classify, or re-weight findings, severities, or dimensions; consume the `lektorat` report verbatim. The rules live in the spec, not here.60- Never dispatch an author without both a resolved audience set and a bound writing-style spec. "No audience" and "no style spec" are stop conditions, not soft defaults.61- Never rewrite prose in this skill — every rewrite is delegated to the routed author, so the author's audience and writing-style competence applies.62- Never run the documentation route with a human gate, and never run the blog route without `blog-author`'s briefing touchpoint.63- Never mark a file converged while it has a finding at or above the severity floor or a regression; never loop past 2 author passes — escalate instead.64- Never route or dispatch an author at a `rejected`-class path; never widen the routing table to a class `lektorat` forbids.65- Never silently skip an unroutable file or truncate unremediated findings — stop the run or escalate, and record it.6667## Gotchas6869Per `spec/claude/skill-management/` §Gotchas: concrete corrections to non-obvious environment facts the executing agent would otherwise get wrong.7071- **Finding IDs aren't stable across a rewrite, so convergence is judged by count and severity — never by ID diff.** The `findings.json` `id` is a hash of file + dimension + line; once an author rewrite shifts line numbers, the re-audit re-keys every finding. Compare the re-audit's per-file finding count and highest severity against the pre-revision snapshot; matching IDs across passes will spuriously miss both regressions and fixes.72- **A lower LIX number is not automatically convergence.** A D1 readability finding converges only when the re-audit shows LIX at or below the file's `warn` corridor (`spec/project/readability-lix/` §Iterative improvement loop) *and* the drop was earned by a permitted transformation. A LIX reduction achieved by decompounding an established term, a vaguer-but-shorter swap, or altering a protected term is a semantic-preservation failure — treat it as a failed pass, not a win.73- **Routing is decided by frontmatter and path, not by reading the prose.** A blog post is identified by the consumer's cross-language binding key (e.g. `translationKey`) in its frontmatter, not by living under `docs/`; a file under `docs/<lang>/` without that key is `documentation`. Misrouting a blog post to the autonomous `audience-doc-author` route skips `blog-author`'s load-bearing briefing touchpoint (topic-as-thesis, source list, slug), which can't be reconstructed from findings.7475## Examples7677- Read `examples/01-documentation-route-autonomous.md` when a `docs/<lang>/` page with a D1 readability finding routes to the `audience-doc-author` agent fully autonomously and converges on the LIX corridor.78- Read `examples/02-blog-route-assisted.md` when a file carrying the cross-language binding key routes to the `blog-author` skill and runs assisted, preserving its briefing touchpoint.79- Read `examples/03-rejected-path-and-escalation.md` when a finding sits at a rejected-class path (e.g. `spec/`) or a file fails to converge within 2 passes and must be escalated and surfaced first in `summary.md`.8081## Resumability8283Per `spec/claude/resumable-work/`, this skill is `resumable: true`. State is persisted to `.resume/lektorat-auto-revise/<run-id>.yml` after every successful per-file convergence and after each named phase boundary. On re-invocation, scan that directory for files with `status: in_progress` whose `inputs:` snapshot matches the current invocation; if one matches, prompt the operator with `Resume run <run_id> from phase <phase> (last checkpoint <last_checkpoint_at>)? [resume / start-new / discard]`. The state-file envelope and fail-closed semantics on schema or YAML errors are defined in the spec; don't duplicate them here.