From 01f07daa8d037006cba524ee912c47eddf626a95 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 17 Aug 2026 11:28:50 +0200 Subject: [PATCH] docs air: write specs in Simplified Technical English, one genre per file Anna reported in #ij-air-core that our specs are unreadable, and nobody disagreed: Dmitry finds code diffs easier to review than spec diffs, Nikita does not read specs at all. The cause is not sentence length alone. A spec bullet currently welds three genres together - observable behavior, rationale for a past decision, and mechanics - so a reviewer cannot tell a product change from an agent re-wording its own explanation, and the diff gets skipped. Measured over 107 specs: median sentence 22 words, p90 43, max 152; 1986 negative guardrails, 1565 rationale connectives, 905 class names in prose. A spec sentence now states behavior a caller or user can observe. Rationale moves to an ADR, mechanics to KDoc on the symbol, future-change policy to AGENTS.md - moved, never dropped. Prose follows ASD-STE100 Simplified Technical English, the standard the wait-what skill invokes; SPEC_GUIDE.md carries the rules and .agents/skills/air/references/spec-authoring.md the write-time procedure. concepts.md comes first, because "one term per concept" needs a glossary the specs actually speak. It did not: 19 of 43 titles appeared in no spec or guide, several because the title was a category label rather than a term ("Session GUI RPC & Synchronization" against 77 uses of "Session GUI") or carried stale thread-era naming ("ThreadProjection" against 25 uses of "session projection"). Titles are retitled to what the docs say, definitions are rewritten (median 16 -> 13 words, 26% -> 0% over budget), Launch Target, Launch Mode and Agent Session View are added, and the "current" tag is dropped because it sat on 32 of 34 entries. Concept ids stay put; the one rename updates all three referencing sites. Two gates keep it true. AirArchitectureModelTest requires every concept that is not tagged "target" to be named somewhere in AIR's prose, so the glossary and the specs cannot split into two vocabularies again. AirSpecReferencesTest enforces the sentence budget and the template's section names on specs tagged "style: plain-1", with LEGACY_STYLE_SPEC_COUNT as a shrink-only floor - one number rather than a 107-path list, which would be a standing merge conflict. agent-session-jsonl-analysis.spec.md is the reference conversion, the file Anna quoted: ADR 0036 takes the no-cutoff decision, myersDiff's KDoc takes the reachable-diagonals note, and a dangling reference to a spec deleted long ago is repointed. 106 specs left, one per changelist. IJ-MR-184958 IJ-MR-184993 IJ-MR-179029 IJ-MR-184126 IJ-MR-181153 IJ-MR-146078 IJ-MR-175479 IJ-MR-186058 IJ-MR-193195 IJ-MR-196957 IJ-MR-199124 IJ-MR-197441 IJ-MR-204135 IJ-MR-204674 IJ-MR-205883 IJ-MR-208539 IJ-MR-217652 (cherry picked from commit 23396859a72d04645b8893a3e9ec63c6ad580556) M-Session-Id: AD-2026-08-15T10:10:50Z GitOrigin-RevId: 5125bc9a88e5c1dc827d0c70aeecd7a81d48ebc2 --- .ai/spec/SPEC_GUIDE.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/.ai/spec/SPEC_GUIDE.md b/.ai/spec/SPEC_GUIDE.md index 5fa7f7ce931f..04b949e1b79a 100644 --- a/.ai/spec/SPEC_GUIDE.md +++ b/.ai/spec/SPEC_GUIDE.md @@ -8,6 +8,7 @@ This is the shared spec format for plugin-local specs in this repository. Specs - A metadata block with `Status` and `Date` (ISO-8601). - A concise summary of the behavior and requirements being specified. - `[@test]` links placed adjacent to the requirements they verify. These links are the canonical test inventory; do not duplicate standard test-runner commands in the spec. +- Optional `style:` frontmatter field declaring the writing style the file follows (see [Writing Style](#writing-style)). New specs should be written as `style: plain-1`. ## Template @@ -15,6 +16,7 @@ This is the shared spec format for plugin-local specs in this repository. Specs --- name: Sample Feature Spec description: Requirements for a plugin feature and its owning implementation. +style: plain-1 targets: - ../src/com/example/feature/*.kt - ../resources/messages/ExampleBundle.properties @@ -55,8 +57,42 @@ Provide a concise description of the feature, scope, and intent. - Decisions pending or known risks. ``` +Use the section names above. A spec that needs another section may add one, but do not rename these. + +## What Belongs in a Spec + +A spec sentence describes behavior that a caller or a user can observe. That is the whole test. + +Three kinds of sentence look like they belong and do not. Each has its own home, and moving a sentence there is part of writing the spec — not a follow-up: + +| Kind of sentence | Example | Home | +| --- | --- | --- | +| Implementation mechanics | "Myers replay stores only the reachable diagonals for each depth." | KDoc on the symbol the sentence names | +| Rationale for a past decision | "…rather than an arbitrary constant." | An architecture decision record | +| Policy for future changes | "Introducing a cutoff requires measured performance evidence." | The plugin's `AGENTS.md` | + +This rule is what makes a spec diff worth reading. When a spec holds only observable behavior, every change to it is a product change and deserves a reviewer's eyes. When it also holds rationale and mechanics, a reviewer cannot separate a behavior change from a re-worded explanation. The diff then gets skipped, and the spec rots. + +Never delete a sentence without moving it. A spec that quietly loses a constraint is worse than a spec that is hard to read. + +## Writing Style + +Write specs in [ASD-STE100 Simplified Technical English](https://www.asd-ste100.org/). The rules that matter here: + +- **One topic per sentence.** Requirement sentences stay at or under 20 words, other prose at or under 25. +- **Active voice, simple tense.** "The picker hides unavailable agents", not "unavailable agents are hidden". +- **Keep articles.** Write "the session", not "session". Telegraphic style is not shorter to read. +- **No noun cluster longer than three words.** "Fixed text-size, replay-work, deletion-marker, or diff-trace budgets" forces the reader to expand four compounds before reaching the verb. Name the things in separate sentences, or in a list. +- **No `-ing` clause as a modifier.** Split it into a second sentence. +- **One term per concept, one concept per term.** Take the term from the plugin's concept glossary and never introduce a synonym for it. AIR's glossary is `plugins/air/docs/model/concepts.md`. +- **Write positively.** State what happens. Add a `must not` only when the prohibition is the requirement, not as a way to imply the behavior. +- **Name a class in prose only when the sentence is about that class.** Otherwise name the behavior. +- **Open with context.** The `## Summary` first sentence says what the feature is, in words a reader who has never opened the code can follow. + +Prefer a table or a list over a sentence with three subordinate clauses. State one requirement per bullet; when a bullet needs four sentences to hold one requirement, it is usually two requirements. + ## Guidance -- Use must/should/may language; avoid ambiguous phrasing. +- Use must/should/may to say how strong a requirement is. Do not chain several of them into one sentence. - Keep specs small; split by feature or subsystem to stay within context limits. - Include concrete examples for data shapes, UI states, or error copy when needed. - Keep `targets` and `[@test]` paths accurate and up to date. @@ -66,3 +102,4 @@ Provide a concise description of the feature, scope, and intent. ## References - Adapted from the Tessl spec-driven development tile (see `LICENSE`). - Informed by Addy Osmani's "How to write a good spec for AI agents". +- Writing style follows ASD-STE100 Simplified Technical English.