asciidoc-pubkit 0.9.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@
8
8
  - Explain metaphorical operations from evidence
9
9
  - Distinguish instructions, behavior, and capabilities
10
10
  - Make relationships explicit
11
+ - Compare structure before and after revision
11
12
  - Keep claims within their evidence and purpose
12
13
  - Remove generated-prose patterns without flattening the meaning
13
14
  - Preserve exact technical terminology
@@ -155,6 +156,21 @@ instruction when that fits the document's voice. Do not change `〜します` to
155
156
  optional capability are different claims. Name the actor when context does not
156
157
  identify it, without repeating an already clear subject in every sentence.
157
158
 
159
+ Distinguish advice, obligations, plans, and evaluations as well, including when
160
+ different functions occur in adjacent sentences or clauses. A paragraph can
161
+ combine advice with an explanation of actual behavior; that alone is not an
162
+ ending inconsistency. Do not turn advice into a policy, a plan into a completed
163
+ action, or an evaluation into an implementation goal. Sequence words such as
164
+ `まず` and `次に` establish order, not whether the action is advice or actual
165
+ behavior. When the function or actor is unresolved, retain the uncertainty and
166
+ record what needs confirmation.
167
+
168
+ Preserve plain or polite style unless the author requests a change or the book's
169
+ explicit style requirements call for one. A technical topic alone does not
170
+ require polite style. Resolve unintended style mixing separately from each
171
+ sentence's function; changing `する` to `します` must not change advice into
172
+ an asserted operation. Do not vary endings just to make these functions uniform.
173
+
158
174
  ## Make relationships explicit
159
175
 
160
176
  Inspect a sentence when it:
@@ -177,6 +193,40 @@ Use prose for a sequence in which one event causes or conditions the next; use
177
193
  a list when the items are genuinely parallel. Do not turn a causal explanation
178
194
  into disconnected bullets or impose an order on independent items.
179
195
 
196
+ ## Compare structure before and after revision
197
+
198
+ Before replacing words, identify the subject and predicate, each modifier and
199
+ its target, and each referring expression and its referent. Trace conditions,
200
+ exceptions, negation, parallel relationships, quantities and their targets,
201
+ and required order. After revising, compare those relationships with the source,
202
+ including passages without candidates. Keep naturally clear wording when no
203
+ relationship needs repair. Supply missing actors or objects only from evidence;
204
+ leave an unresolved relationship pending rather than inventing one.
205
+
206
+ Use these checks when splitting, joining, or rearranging sentences:
207
+
208
+ - Keep a condition or exception attached to the same operations. Joining an
209
+ unconditional audit-log statement to a conditional data-save statement must
210
+ not make logging conditional on authentication success.
211
+ - Preserve what each quantity counts and whether it is a total, per-item limit,
212
+ minimum, maximum, or exact count. `各ワーカーは最大3回再試行します` does not
213
+ mean `全ワーカーで合計3回まで再試行します`, although the numeral is unchanged.
214
+ - Preserve required order and distinguish it from independent parallel work.
215
+ Stopping processing, changing settings, and restarting in that order is not
216
+ equivalent to changing settings before stopping. Do not invent an order or
217
+ success prerequisite for independent validation steps.
218
+ - Keep modifiers attached to their original targets after replacing verbs or
219
+ changing word order. In `圧縮されたログを送信するサーバーを監視します`, the
220
+ logs are compressed and the server is monitored.
221
+ - Preserve the scope and direction of purpose, reason, contrast, and emphasis.
222
+ A purpose applying to two operations must still apply to both after splitting;
223
+ necessary contrast or priority must not become simple addition or equality.
224
+
225
+ Adjust punctuation when it obscures these relationships, not merely to reduce
226
+ comma counts. Keep a colon that maps a label to a value, such as `状態: 正常`,
227
+ and distinguish it from an ornamental ending. Preserve inline syntax and edit
228
+ scope; prose review does not authorize rewriting labels in protected blocks.
229
+
180
230
  ## Keep claims within their evidence and purpose
181
231
 
182
232
  State whether a claim comes from an implementation, a test, a cited study, or
@@ -304,6 +354,9 @@ condition, cause, and effect.
304
354
  Assess readability and meaning preservation separately. Compare the source and
305
355
  revision for both missing information and unsupported additions, including
306
356
  conditions, negation, numbers, actors, causes, and implementation requirements.
357
+ Include modifier targets, quantity targets, required order, exception scope,
358
+ sentence functions, and requested style in that comparison. Unchanged numbers
359
+ or words do not establish unchanged relationships.
307
360
  For example, removing a unique constraint from a duplicate-message check can
308
361
  lose a concurrency requirement even when the revised paragraph sounds clearer.
309
362
  Record unresolved evidence and keep necessary repetition or qualifications.
@@ -0,0 +1,264 @@
1
+ # How review and scoring work
2
+
3
+ ### Features
4
+
5
+ - **Structure-aware AsciiDoc parsing.** Asciidoctor parses local includes,
6
+ conditionals, attributes and section hierarchy before review targets are
7
+ selected. Prose selection distinguishes paragraphs from lists, tables,
8
+ quotations and code blocks; supported inline constructs are masked rather
9
+ than treated as ordinary prose.
10
+ - **Separate heading and prose review.** Each scan selects one
11
+ scope with its own rules, prompt and edit permissions. Heading review uses
12
+ the outline and body as context while protecting body text; prose review
13
+ protects headings. Mixed heading forms are accepted by default. See
14
+ [Heading review](review-workflow.md#heading-review).
15
+ - **Source-aligned static analysis.** Candidates identify the original source
16
+ file, line and one-based Unicode column, with a rule ID and review question.
17
+ Source text is checked against parser locations; unresolved mappings produce
18
+ coverage notices instead of guessed edit targets. Matches locate passages
19
+ for review, not proven defects.
20
+ - **Japanese morphological analysis.** MeCab with UTF-8 IPADIC recognizes
21
+ configured inflected predicates and adjectives, retaining original surfaces,
22
+ dictionary forms and negative-form information in morphological prose
23
+ findings. Literal matching is available only through explicit selection.
24
+ - **Contextual review in one prompt.** A single Markdown file carries saved
25
+ criteria, settings, candidates and manuscript evidence. All selected prose
26
+ paragraphs appear once, including those without candidates, with heading and
27
+ neighboring context. The reviewer records decisions and checks meaning;
28
+ generating the prompt does not edit the manuscript or invoke a model.
29
+ - **Book-specific rules and terminology.** Strict YAML rule sets, a glossary,
30
+ allow lists and exclusions adapt candidate detection to the manuscript.
31
+ Heading rules can express a book's preferred form while allowing justified
32
+ exceptions. Resolved rules and criteria are saved with each session.
33
+ - **Baseline-based preservation checks.** Source snapshots and artifact hashes
34
+ make the review baseline reproducible and detect stale or altered evidence.
35
+ Verification checks protected content, source membership, structure and
36
+ analyzer identity after external edits. It keeps `meaning_verified: false`;
37
+ semantic correctness remains a review judgment.
38
+ - **Local analysis and distinct scoring paths.** Default analysis runs locally
39
+ without a model call. Prose scoring reports candidate density; explicit
40
+ `review score --agent` optionally invokes an installed Codex or Claude CLI
41
+ for readability ratings. Candidate density, model judgments and development
42
+ benchmark accuracy remain separate measures.
43
+
44
+ ### Concept
45
+
46
+ The goal is Japanese technical prose that readers can understand, use, and
47
+ verify, with claims bounded by evidence and technical meaning preserved.
48
+ Clarity includes a paragraph's purpose, concrete operations and referents,
49
+ actors and objects, conditions and consequences, logical connections, and its
50
+ relationship to headings, figures, tables, and code. "Who does what" is one
51
+ part of that goal. Clear prose also retains precise terminology, necessary
52
+ negation, uncertainty, and implementation constraints.
53
+
54
+ The toolkit supports that goal through shared writing criteria, contextual
55
+ review prompts, source-aligned candidate detection, baseline verification,
56
+ and distinct scoring and development evaluation paths. Mechanical rules locate
57
+ passages to inspect; the reviewer judges their meaning from context and source
58
+ evidence. The writing and review prompts guide a human or external agent in
59
+ planning and revising complete paragraphs. They do not automatically reconstruct
60
+ subjects and objects or rewrite manuscripts. Model-based readability evaluation
61
+ is available only through explicit `review score --agent`.
62
+
63
+ The table identifies both implemented mechanisms and guidance carried by the
64
+ prompts. A criterion in a prompt is a review instruction, not a guarantee that
65
+ the code can detect or verify it.
66
+
67
+ | Supported principle or behavior | How it is realized | Implementation or criteria |
68
+ | --- | --- | --- |
69
+ | Write for a technical purpose and the reader's decisions | Shared criteria ask what a paragraph explains and what an engineer can decide or verify; writing prompts include those criteria | [Paragraph purpose](../data/writing/ja/criteria.md#start-with-the-paragraphs-technical-purpose), [Writing](../lib/asciidoc_pubkit/writing.rb) |
70
+ | Make actors, objects, actions, conditions, and results recoverable | Review instructions ask the reviewer to resolve omitted elements from context, while allowing unambiguous omission | [Paragraph revision](../data/writing/ja/criteria.md#revise-the-complete-paragraph), [Review prompt](../lib/asciidoc_pubkit/session.rb) |
71
+ | Replace vague abstraction, weak predicates, and metaphors with concrete explanations | Rules locate limited terms and inflected predicates; the criteria require identifying the actual referent, operation, policy, or effect before revising | [Concrete referents](../data/writing/ja/criteria.md#replace-abstraction-with-the-thing-being-discussed), [Metaphor criteria](../data/writing/ja/criteria.md#explain-metaphorical-operations-from-evidence), [Rules](../lib/asciidoc_pubkit/rules.rb) |
72
+ | Distinguish reader instructions, actual behavior, and available capabilities | The shared criteria preserve the difference between requests, automatic execution, and optional operations | [Instructions, behavior, and capabilities](../data/writing/ja/criteria.md#distinguish-instructions-behavior-and-capabilities) |
73
+ | Connect claims into coherent paragraphs | Prompts include all selected paragraphs and neighboring context; criteria require explicit referents, comparisons, causal relationships, and complete paragraph revision | [Relationships](../data/writing/ja/criteria.md#make-relationships-explicit), [Review prompt](../lib/asciidoc_pubkit/session.rb) |
74
+ | Keep claims within their evidence and preserve meaning | Review guidance asks for implementation, test, or primary-source evidence and checks omissions and unsupported additions; unresolved facts remain unresolved | [Evidence and scope](../data/writing/ja/criteria.md#keep-claims-within-their-evidence-and-purpose), [Paragraph revision](../data/writing/ja/criteria.md#revise-the-complete-paragraph) |
75
+ | Preserve technical distinctions, terminology, and justified prose choices | Criteria protect identifiers, values, conditions, negation, and necessary repetition; glossary rules, allow lists, and contextual questions support project terminology | [Terminology](../data/writing/ja/criteria.md#preserve-exact-technical-terminology), [Packaged rules](../data/review-rules.ja.yml), [Settings](../lib/asciidoc_pubkit/settings.rb) |
76
+ | Review generated-prose patterns without mechanical deletion | Framing, contextual phrases, style, and repeated-ending checks produce candidates; shared criteria reject fixed sentence-length targets and needless synonym changes | [Generated-prose patterns](../data/writing/ja/criteria.md#remove-generated-prose-patterns-without-flattening-the-meaning), [Rules](../lib/asciidoc_pubkit/rules.rb) |
77
+ | Keep headings, illustrations, tables, and code consistent with the explanation | Writing criteria address scope, comparisons, identifiers, and conceptual simplifications; review prompts constrain edits to the selected scope and protect other elements | [Headings, figures, and code](../data/writing/ja/criteria.md#headings-and-the-relation-to-figures-and-code), [Review scope](../lib/asciidoc_pubkit/session.rb) |
78
+ | Make detection traceable and coverage explicit | Asciidoctor source mapping, offset-preserving inline masking, and MeCab/IPADIC produce source-aligned evidence; ambiguous or excluded passages have coverage notices | [Document](../lib/asciidoc_pubkit/document.rb), [Morphology](../lib/asciidoc_pubkit/morphology.rb), [Rules](../lib/asciidoc_pubkit/rules.rb) |
79
+ | Preserve a reproducible and safe review baseline | Sessions save source snapshots, resolved rules, criteria, and analyzer identity; integrity checks and verification protect content outside editable prose | [Session](../lib/asciidoc_pubkit/session.rb), [Rule validation](../lib/asciidoc_pubkit/rule_set.rb) |
80
+ | Keep manuscript indicators, readability judgments, and detector accuracy distinct | Default scoring measures candidate density; optional local CLI evaluation judges readability; annotated development benchmarks measure detection and evaluate preservation separately | [Score](../lib/asciidoc_pubkit/score.rb), [Local evaluator](../lib/asciidoc_pubkit/local_evaluator.rb), [Development benchmark](../benchmark/prose.rb) |
81
+ | Make automation explicit and its limits visible | Default analysis runs locally with no model call; only explicit scoring requests invoke an external CLI. Manuscripts are not edited, and verification retains `meaning_verified: false` | [CLI](../lib/asciidoc_pubkit/cli.rb), [Local evaluator](../lib/asciidoc_pubkit/local_evaluator.rb), [Session](../lib/asciidoc_pubkit/session.rb) |
82
+
83
+ This section explains the implementation independently of command syntax.
84
+ [Review workflow](review-workflow.md#review-workflow) covers commands and session handling;
85
+ [Score an AsciiDoc manuscript](scoring.md#score-an-asciidoc-manuscript) covers scoring options.
86
+ The diagrams use GitHub-supported Mermaid fenced blocks.
87
+
88
+ ### Shared components and prose selection
89
+
90
+ Both paths resolve the same settings and parse the AsciiDoc entry file with
91
+ Asciidoctor, including local includes. `Document` selects running-prose paragraphs
92
+ and maps them back to their source files. Ambiguous mappings become coverage
93
+ notices; the analyzer does not guess locations. Headings provide context, while
94
+ code, tables, quotations, lists, and protected blocks are excluded from prose
95
+ analysis. Inline code, quoted spans, links, and other protected constructs are
96
+ masked with spaces that preserve character offsets and newlines.
97
+
98
+ ```mermaid
99
+ flowchart TD
100
+ A["AsciiDoc entry and local includes"] --> D["Document: parse and map running prose"]
101
+ C["Settings: options, configuration, resolved rules"] --> D
102
+ D --> P["Paragraphs with source locations and headings"]
103
+ D --> N["Coverage notices and parser diagnostics"]
104
+ P --> M["Rules: mask protected inline content"]
105
+ C --> M
106
+ M --> F["Candidate detection"]
107
+ F --> R["Session: review baseline and evidence"]
108
+ F --> S["Score: manuscript indicators"]
109
+ P -->|"Original prose and headings"| S
110
+ N --> R
111
+ N --> S
112
+ ```
113
+
114
+ `Settings` resolves rule precedence as command-line `--rules`, configuration
115
+ `review.rules`, then packaged defaults. A custom rule file replaces the whole
116
+ set. `Rules` returns review candidates with one-based Unicode line and column
117
+ positions; a match does not establish a defect. `Session` saves evidence for a
118
+ later review, while `Score` returns a report directly without creating a session.
119
+ Parser diagnostics must be resolved before scanning or scoring.
120
+
121
+ ### Review: collect, judge, and verify
122
+
123
+ Scanning freezes the source baseline, resolved settings and rules, analyzer
124
+ identity, and writing criteria. The session consists of `manifest.json`,
125
+ `document.json`, `findings.json`, and `baseline/`. Prompt generation checks
126
+ artifact integrity and rejects sources changed since the scan. It emits one
127
+ Markdown file containing the saved criteria, context, every selected paragraph
128
+ in document order, and its candidate evidence, including paragraphs with no
129
+ candidates. Generating that prompt requires no analyzer or model invocation.
130
+
131
+ ```mermaid
132
+ sequenceDiagram
133
+ actor Reviewer as Human or external agent
134
+ participant CLI as pubkit CLI
135
+ participant Sources as Manuscript files
136
+ participant Session as Saved review session
137
+ Reviewer->>CLI: review scan FILE
138
+ CLI->>Sources: Parse prose and detect candidates
139
+ CLI->>Session: Save evidence and source baseline
140
+ Reviewer->>CLI: review prompt SESSION
141
+ CLI->>Session: Check integrity and read saved evidence
142
+ CLI->>Sources: Check sources still match scan
143
+ CLI-->>Reviewer: One Markdown review prompt
144
+ Reviewer->>Sources: Judge context and edit prose externally
145
+ Reviewer->>CLI: review verify SESSION
146
+ CLI->>Session: Read original baseline and settings
147
+ CLI->>Sources: Reparse and compare protected content
148
+ CLI-->>Reviewer: Mechanical result, notices, remaining candidates
149
+ ```
150
+
151
+ The reviewer decides whether to keep or revise each paragraph and checks source
152
+ evidence before adding claims. `scan`, `prompt`, and `verify` never invoke an AI
153
+ CLI or edit manuscripts. Verification compares the included source set, content
154
+ outside reviewed prose, protected inline tokens, document structure, and analyzer
155
+ identity against the saved baseline. Numeric changes produce manual-review
156
+ notices; remaining candidates alone do not fail verification. A passing result
157
+ means these mechanical checks passed, with `meaning_verified: false`.
158
+
159
+ ### Detection: contextual rules and token boundaries
160
+
161
+ MeCab with UTF-8 IPADIC is the default analyzer. It supplies surfaces, dictionary
162
+ forms, part of speech, and source-aligned token spans. Explicit literal mode
163
+ matches configured surface strings; there is no silent fallback. Both modes
164
+ apply glossary, configured prose style, and sentence-ending checks.
165
+
166
+ ```mermaid
167
+ flowchart TD
168
+ P["Masked running prose"] --> B{"Selected tokenizer"}
169
+ B -->|"mecab, default"| T["MeCab and IPADIC tokens with source offsets"]
170
+ T --> L["Lemma rules with allow lists and contextual overlap checks"]
171
+ T --> X["Four enabled contextual predicate patterns"]
172
+ B -->|"literal, explicit"| E["Exact configured terms"]
173
+ P --> Q["Exact framing and contextual phrases"]
174
+ L --> F["Candidate findings"]
175
+ X --> O["Prefer most specific phrase; apply allow lists"]
176
+ E --> O
177
+ Q --> O
178
+ O --> F
179
+ P --> G["Glossary, style, and repeated endings"]
180
+ G --> F
181
+ ```
182
+
183
+ Morphological rules match configured noun and adjective lemmas, canonical verb
184
+ forms, adjacent compound nouns, and sahen nouns followed by `する` or `できる`.
185
+ Predicate spans extend through adjacent auxiliaries, dependent verbs, and
186
+ supported connective particles. Negative auxiliaries preserve polarity;
187
+ negative-only rules require that evidence. Unknown tokens are not guessed.
188
+
189
+ The four contextual patterns combine an exact prefix (`地味に`, `静かに`,
190
+ `時間を`, or `側に`) with a known independent verb lemma (`効く`, `壊れる`,
191
+ `溶かす`, or `倒す`). The canonical phrase must be enabled in the resolved rules.
192
+ For example, `地味に効かなかった` is collected as one complete candidate with
193
+ lemma `地味に効く` and `negative: true`. Protected text and paragraph boundaries
194
+ cannot bridge the pattern. Longer contextual phrases suppress contained matches,
195
+ including when the longer phrase is allowed. These limited patterns suggest
196
+ reviewing the actual effect or operation; they do not prove a metaphor is wrong.
197
+
198
+ Sentence-ending analysis splits each paragraph at `。`, `!`, and `?`, retaining
199
+ source offsets. It extracts supported endings such as `検証します` and `です`,
200
+ then checks consecutive windows of three sentences. A sentence without a matching
201
+ ending breaks the run. The first matching run produces one informational
202
+ candidate at the ending of its third sentence. Precise technical repetition may
203
+ be worth retaining; this is not a requirement to vary verbs.
204
+
205
+ ### Scoring: density and optional readability judgment
206
+
207
+ Scoring first runs the shared candidate detector. For the default
208
+ `candidate-density-v1`, let `N` be all findings, including informational ones,
209
+ and `C` be non-whitespace Unicode characters after inline masking:
210
+
211
+ ```text
212
+ density = N * 1000 / C
213
+ score = max(0, 100 - 5 * density)
214
+ ```
215
+
216
+ The score is rounded to three decimals. No unmasked prose yields `null`.
217
+ More candidates per 1,000 characters lower the score; short texts are particularly
218
+ sensitive. Changing rules, allow lists, or the detector can change the score of
219
+ an unchanged manuscript. This heuristic is a review indicator, not a calibrated
220
+ quality measure or a probability that AI wrote the text.
221
+
222
+ ```mermaid
223
+ flowchart TD
224
+ P["Selected prose and detected candidates"] --> D["Compute candidate density and mechanical score"]
225
+ D --> A{"Explicit agent option and nonempty prose?"}
226
+ A -->|"No"| R["Text or JSON report"]
227
+ A -->|"Yes"| I["Paragraph IDs, text, headings, and readability rubric"]
228
+ I --> J["Installed Codex or Claude CLI; configured model provider"]
229
+ J --> V["Validate IDs, integer ratings, and reasons"]
230
+ V --> M["Map ratings to 0, 50, 100 and average"]
231
+ M --> R
232
+ D --> K["Retain mechanical score in JSON"]
233
+ K --> R
234
+ ```
235
+
236
+ With explicit `--agent`, `llm-readability-v1` asks a fresh local CLI invocation to
237
+ rate each paragraph's sentence clarity and paragraph coherence separately from
238
+ 1 to 3. The rubric targets engineers familiar with the technical terms. The
239
+ input contains paragraph IDs, original text, and headings, without candidate
240
+ findings or file paths. The CLI may connect to its configured model provider.
241
+ The response must contain every supplied ID exactly once, integer ratings in
242
+ range, and nonempty reasons. Invalid responses fail scoring.
243
+
244
+ Ratings of 1, 2, and 3 map to 0, 50, and 100. Each dimension averages equally
245
+ across scored paragraphs; the displayed score averages the two dimension means.
246
+ JSON retains both dimensions, paragraph reasons, evaluator identity, and the
247
+ mechanical score. These ordinal averages summarize a fallible judgment. There
248
+ is no reference manuscript or fact checklist in this single-document path, so
249
+ it does not assess preservation or establish technical accuracy. Temporary CLI
250
+ artifacts are removed after the invocation, and manuscripts remain unchanged.
251
+
252
+ | Result | What it measures | Evidence needed |
253
+ | --- | --- | --- |
254
+ | Candidate-density score | Detected cues per text length | Current prose and resolved rules |
255
+ | Optional readability score | Model judgment of clarity and coherence | Current prose, context, and rubric |
256
+ | Development benchmark accuracy | Detector agreement and location accuracy | Fixed corpus with annotated targets |
257
+ | Review verification | Mechanical preservation after editing | Original session baseline and current files |
258
+
259
+ See the [prose evaluation guide](prose-evaluation.md) for
260
+ before/after trials with gold targets, separate fact checklists, and evaluator
261
+ calibration. Its precision, recall, and F1 evaluate the detector rather than
262
+ providing a score for an arbitrary manuscript.
263
+
264
+ [Back to README](../README.md)
@@ -0,0 +1,48 @@
1
+ # Configuration
2
+
3
+ `scan` and `score` search upward from the entrypoint directory for the nearest
4
+ `.asciidoc-pubkit.yml`. Use `--config FILE` to select a different file. CLI options
5
+ override configuration values; unspecified values use built-in defaults.
6
+ The CLI loads one configuration file, not merged book/repository files.
7
+
8
+ ```yaml
9
+ review:
10
+ language: ja
11
+ style: desu-masu
12
+ tokenizer: mecab
13
+ # heading_rules: heading-rules.yml # Separate heading rule set
14
+ # Optional overrides (dictionary paths are relative to this file):
15
+ # mecab_command: /opt/homebrew/bin/mecab
16
+ # mecab_dictionary: /opt/homebrew/lib/mecab/dic/ipadic
17
+ base_dir: .
18
+ glossary: glossary.yml
19
+ exclude:
20
+ - generated/**
21
+ allows: []
22
+ attributes:
23
+ edition: print
24
+ ```
25
+
26
+ Configuration paths are relative to the configuration file. Without configuration,
27
+ the base directory is the entrypoint's directory. Exclusion patterns match source
28
+ paths relative to the base directory; excluded files can still supply attributes
29
+ and are preserved by verification. The default style is `preserve`; explicit
30
+ alternatives are `desu-masu` and `dearu`. Only `ja` is currently supported.
31
+
32
+ A glossary maps canonical terms to variant strings:
33
+
34
+ ```yaml
35
+ JavaScript:
36
+ - Javascript
37
+ - Java Script
38
+ ```
39
+
40
+ Variants are review candidates, not automatic replacement instructions. In MeCab
41
+ mode, `allows` can suppress a canonical dictionary form (all its inflections) or
42
+ an exact matched surface (that occurrence's form only). In literal mode it
43
+ suppresses exact dictionary entries. It does not disable glossary checks.
44
+ Regex patterns are not interpreted in glossary or allow-list entries. Unknown
45
+ configuration keys are rejected. A bare `mecab_command` is resolved through PATH;
46
+ use an absolute path for an explicit executable override.
47
+
48
+ [Back to README](../README.md)
@@ -0,0 +1,69 @@
1
+ # Customize review rules
2
+
3
+ The UTF-8 YAML file [`data/review-rules.ja.yml`](../data/review-rules.ja.yml) is
4
+ included in the gem and loaded by default. Edit that file when running a local
5
+ checkout, or copy it to a project-owned file for custom rules. No Ruby changes
6
+ are required to update candidate terms.
7
+
8
+ ```sh
9
+ asciidoc-pubkit review scan book.adoc --rules ./review-rules.yml
10
+ make run ARGS="review scan book.adoc --rules ./review-rules.yml"
11
+ ```
12
+
13
+ For an installed gem, copy the default file with:
14
+
15
+ ```sh
16
+ ruby -rasciidoc_pubkit -e 'puts File.read(AsciidocPubkit::RuleSet::DEFAULT_PATH)' > review-rules.yml
17
+ ```
18
+
19
+ Alternatively, configure a path in `.asciidoc-pubkit.yml`:
20
+
21
+ ```yaml
22
+ review:
23
+ rules: review-rules.yml
24
+ ```
25
+
26
+ Precedence is `--rules`, then `review.rules`, then the packaged default.
27
+ CLI paths are relative to the current working directory; configuration paths
28
+ are relative to the configuration file. A custom file replaces the entire rule
29
+ set; it is not merged with defaults. Start by copying the standard file.
30
+
31
+ ### Rule file format (schema version 1)
32
+
33
+ All top-level fields below are required. Unknown keys and invalid types are
34
+ rejected. YAML aliases and object tags are not supported.
35
+
36
+ | Field | Format and behavior |
37
+ | --- | --- |
38
+ | `schema_version` | Integer `1` |
39
+ | `terms` | Mapping containing all five categories listed below |
40
+ | `verbs` | Mapping from canonical verb forms to nonempty arrays of MeCab/IPADIC dictionary forms; each dictionary form belongs to only one canonical form |
41
+ | `sahen` | Array of nouns matched with a following `する` or potential `できる` verb |
42
+ | `negative_only` | Array of canonical predicates restricted to negative forms; use the noun plus `する` for sahen predicates |
43
+ | `compound_nouns` | Array of terms matched across contiguous noun tokens; each must also appear in `abstract-reference.terms` |
44
+
45
+ Each `terms` category must contain `terms` (an array of unique nonempty strings)
46
+ and `question` (a nonempty review instruction string). The required categories
47
+ are `abstract-reference`, `weak-predicate`, `vague-degree`, `contextual-phrase`,
48
+ and `generic-framing`. Empty term arrays disable that category's literal
49
+ candidates. Empty `verbs`, `sahen`, and `compound_nouns` collections disable their
50
+ respective morphological matchers. Keep `negative_only` consistent with the
51
+ configured predicates.
52
+
53
+ In literal mode, all category term lists use exact phrase matching. In MeCab
54
+ mode, abstract nouns and degree adjectives use dictionary forms, while predicates
55
+ use `verbs` and `sahen`; add a predicate's desired literal surface to
56
+ `weak-predicate.terms` as well if literal mode should detect it. Contextual and
57
+ generic framing phrases use literal matching in both modes, with the
58
+ MeCab exception for the four configured contextual predicate patterns described
59
+ in [rules and coverage](rules-and-coverage.md). Questions apply to
60
+ both detectors. Glossary, style, repeated-ending checks, inline exclusions, and
61
+ morphological suffix handling remain implemented in Ruby.
62
+
63
+ A scan saves the resolved rule contents and source path in `manifest.json`.
64
+ Prompt generation and verification use the saved contents, even if the original
65
+ YAML file is subsequently edited or removed. Start a new session to apply rule
66
+ changes. Sessions require the same tool version that created them; preserve old
67
+ baselines and start a separate new session when upgrading.
68
+
69
+ [Back to README](../README.md)
@@ -0,0 +1,23 @@
1
+ # Development
2
+
3
+ ```sh
4
+ bundle install
5
+ bundle exec rake test
6
+ bundle exec ruby -Ilib exe/asciidoc-pubkit --help
7
+ gem build asciidoc-pubkit.gemspec
8
+ ```
9
+
10
+ The tests exercise include-boundary mapping, inline masking, configuration,
11
+ contextual prompts, stale inputs, protected-content verification, and real MeCab
12
+ analysis of inflections, negative predicates, Unicode positions, and long lines.
13
+ Install MeCab and UTF-8 IPADIC before running the complete test suite.
14
+ GitHub Actions is configured for Ruby 3.2, 3.3, 3.4, and 4.0 on Linux.
15
+
16
+ ## Prose evaluation
17
+
18
+ The checkout includes fixed Japanese prose fixtures, detector regression tests,
19
+ and an optional rewrite-and-judge runner. See [Prose evaluation](prose-evaluation.md)
20
+ for the corpus, metrics, test coverage, before/after procedure, and result
21
+ interpretation. Normal `rake test` runs do not invoke an AI CLI.
22
+
23
+ [Back to README](../README.md)
@@ -0,0 +1,68 @@
1
+ # Document commands
2
+
3
+ Version 1.0.1 provides four read-only document commands. They require neither
4
+ MeCab nor an AI CLI, accept documents in any language, and do not create review
5
+ sessions or change manuscripts.
6
+
7
+ ```sh
8
+ asciidoc-pubkit document toc book.adoc --depth 2 --numbered
9
+ asciidoc-pubkit document info book.adoc --json
10
+ asciidoc-pubkit document check-xrefs book.adoc --json
11
+ asciidoc-pubkit document index . --output index.adoc --title "Index"
12
+ ```
13
+
14
+ All four require exactly one input. Use `--help` for command-specific options.
15
+ Output defaults to stdout. `--output FILE` creates a new file and rejects existing
16
+ files and symlinks. Diagnostics go to stderr. These commands do not discover
17
+ `.asciidoc-pubkit.yml` or load review rules. Use repeatable `-a NAME=VALUE` options
18
+ for Asciidoctor attributes and `--base-dir DIR` for the local include boundary.
19
+ The default boundary is the input file's directory, or the scanned directory for
20
+ `index`. Local includes and conditional directives are parsed normally; source
21
+ files and symlink targets must remain within that boundary. Remote includes are
22
+ rejected. `/shared/` has no special mapping or automatic exclusion: migrate such
23
+ references to local includes within the configured boundary.
24
+
25
+ `toc` prints parsed section titles in document order, with two spaces per nesting
26
+ level. It includes book parts and their child chapters, but excludes the document
27
+ title and apparent headings inside code blocks. `--numbered` uses outline
28
+ positions (`1.`, `1-1.`, etc.), independently of Asciidoctor's publication
29
+ numbering. `--depth` must be a positive integer and limits the Asciidoctor section
30
+ level: chapters are level 1 and book parts are level 0. It does not generate or
31
+ rewrite heading text.
32
+
33
+ `info` prints `key: value` lines or a JSON object with `--json`. Its fields are
34
+ `doctitle`, `subtitle`, `description`, `keywords`, `lang`, `uuid`, `author`,
35
+ `producer`, and `creator`. Missing attributes become empty strings. Metadata is
36
+ extracted from the parsed document, including active local includes.
37
+
38
+ `check-xrefs` reports unresolved local `xref:ID[]` and `<<ID,label>>` references,
39
+ including fragments targeting the entry document or an included file. It
40
+ recognizes explicit and generated IDs and attribute-expanded targets. It scans
41
+ macro-enabled block text, list items, table cells, and titles; comments and
42
+ ordinary code blocks are excluded. References to separate documents and remote
43
+ URLs are outside its scope. This is a limited syntax scan, not complete rendered
44
+ link validation: complex inline passthroughs and custom macros are not analyzed.
45
+ Text output has `file:line`, a tab, and the missing ID; JSON output is an array of
46
+ `refid`, `file`, and `line` objects. Locations use Asciidoctor source cursors;
47
+ table cells, list continuations, and multiline titles may identify the enclosing node's start
48
+ rather than the exact token line. Duplicate occurrences of one ID on the same
49
+ source line are reported once.
50
+
51
+ `index` recursively scans lowercase `.adoc` files, skips hidden subdirectories
52
+ and its output path, and uses each document's ID and title. It produces an
53
+ AsciiDoc alphabetical cross-reference list for English names: parenthesized
54
+ text and subtitles after `:` or `:` are removed; remaining titles must be ASCII
55
+ and contain a letter. Documents without IDs are omitted. Titles are deduplicated
56
+ case-insensitively, preferring the shallowest relative path and then lexical path
57
+ order. `--title` adds a document title with `[#book-index]`; alphabetical groups
58
+ use discrete level-2 headings (`=== A`). This indexes document titles, not all
59
+ section headings. The generated references are useful when those documents are
60
+ included in the consuming book; the command does not verify that membership.
61
+
62
+ Success returns 0. `check-xrefs` returns 1 when local references are unresolved.
63
+ Invalid inputs/options, include or parse errors, and output failures return 2;
64
+ no output file is created on a parse error. Warnings remain visible on stderr.
65
+ Unlike the original directory index script, an input parse error fails the whole
66
+ index instead of silently omitting the file.
67
+
68
+ [Back to README](../README.md)