--- name: write-as-oleg description: Write any English text artifact (cover letter, essay, form answer, outreach message, CV tailoring) in Oleg Proskurin's voice. Consolidates voice profile, writing process, and paired examples. Runs a mandatory deterministic voice linter before delivery and iterates until clean. --- # write-as-oleg Produces English text artifacts under Oleg's name: cover letters, application essays, form answers, outreach DMs, screening answers, CV bullets. The text must be indistinguishable from how Oleg himself would have written it — not from how a polished native speaker or a model would write it. **Replaces and consolidates:** - `base/reference/writing-on-behalf-of-oleg.md` - `base/reference/voice-profile-oleg.md` - `base/reference/voice-dictionary-oleg-paired.md` --- ## When to use - Oleg asks to write, draft, or refine any text that will go out under his name. - Tailoring a CV or rewriting CV bullets for a specific role. - Writing a cover letter, answering application form questions, drafting outreach. - Any text where Oleg says "напиши от меня", "сделай cover letter", "ответь за меня". --- ## Mandatory lint loop — run before every delivery Every generated text **must** pass through the voice linter before it reaches Oleg. ```bash node .claude/skills/write-as-oleg/lint-voice.mjs "full text here" # or via stdin: echo "full text" | node .claude/skills/write-as-oleg/lint-voice.mjs ``` **Loop protocol:** 1. Generate draft (Phase 1 below). 2. Run linter. Read findings. 3. Fix all ERRORs in the text. Do NOT auto-insert linter output into the text. 4. Run linter again. Repeat until exit 0 (no ERRORs). 5. Review any remaining WARNs — fix if clearly AI-speak, leave if contextually correct. 6. Output final text to Oleg. The agent fixes the text and delivers it. The linter only finds issues — it does not rewrite. --- ## Writing process — four phases Do not skip Phase 0. Do not merge Phases 1 and 2. ### Phase 0 — Seed and strategy (before writing) Output **ultra-briefly** before drafting: - **Seed** — the one idea that must reach the reader. - **Strategy** — format/channel, register (formal/neutral/conversational), addressee, intended effect. - **Slant** — if clear from the request: what is primary, what is secondary. If unclear, write neutrally and flag it. Then write without waiting for confirmation — unless the addressee, register, or goal is genuinely unclear. ### Phase 1 — Draft Write the text while avoiding all Category A artifacts (list below) from the start. Do not add fake liveliness in their place. Build structural unevenness from Oleg's stated slant; if he gave none, write clean and even without invented asymmetry. ### Phase 2 — Cleanup Do exactly three things: 1. **Silently clean** any remaining Category A artifacts. 2. **Ask Oleg** about Category B — where to shift emphasis, what to add/cut, where to take a firmer stance, which real fact/detail to insert. Do not invent Category B yourself. 3. With his answers, **rewrite**. Then **highlight** remaining markers you cannot remove without losing meaning, and offer him to fix those by hand. ### Phase 3 — Iteration Loop: either edit per Oleg's specific notes, or he sends back his edited version and you work from it (clean Category A, highlight Category B). Repeat until he says done. --- ## Category A — remove always, no input needed These are deletions and clean replacements. Meaning is preserved. The linter catches the detectable subset; catch the rest by eye. - **Em-dash** on parenthetical inserts — replace with colon, comma, or separate sentence. - **"not X, but Y" / "it's not just …, it's …"** — rephrase as direct statement. - **Rule of three** (exactly 3 items in enumeration) — break into 2 or 4. - **Identical bullet structure** (same grammatical form for every bullet) — diversify. - **Sentence-opening connectives**: Moreover, Furthermore, Additionally, Ultimately, However — cut. - **Metadiscourse** ("first … then … finally …") — cut. - **Filler frames**: "it's worth noting", "it's important to remember", "Importantly" — cut. - **Rhetorical question + immediate answer** — turn into statement. - **Inclusive catch-alls**: "whether you're … or …", "from X to Y" — cut. - **Empty closing**: "In conclusion", "Overall", repacked summary — cut. - **Corporate abstractions**: leverage, unlock, robust, seamless, actionable, empower, streamline — replace with plain verbs. - **Forced punchy rhythm** ("No fluff. Just results.") — remove. - **AI-specific words**: thrilled, passionate, delve, tapestry, cutting-edge, "happy to", "looking forward to", "I am writing to", "in today's". - **Smooth connectives**: That said, Furthermore, Moreover — even mid-paragraph. ## Category B — needs Oleg's input; do not invent Ask or highlight; do not fabricate: - **Even structure** (equal-length paragraphs, equal coverage). Ask: what is primary, what is filler. Do not overshoot into chaos. - **Hedging / no stance** ("both are valid", "it depends"). Ask: his actual position. Do not invent confidence he doesn't hold. - **Flat tone / no specifics**. Ask: a real fact, number, project, failure, audience detail. Never fabricate stories. - **Noisiness / over-explaining**. Ask: reader's level, what can be left implicit. Do not over-cut. --- ## Voice profile ### Register - Direct, by-the-point, no runway and no warm-up. - Text rides on **technical noun-anchors** (harness, registry, loop, flow, score), not on decorative action verbs. - Confident but not self-promotional. Facts and system names do the work. - Rhythm is uneven: short sentences sit next to long comma chains. Do not level it into monotony. ### Syntax — reproduce these patterns **Long comma chains without semicolons.** Several verb blocks strung together via comma — Oleg's natural rhythm. Do not split into short sentences. Do not insert `;`. > *Anchor:* "Each step reads the previously generated content, select a best matching component based on a score system, fills props based on compact component schema." **Postpositional "from" and "based on" instead of compression.** Justification and source go at the end of the phrase. Double `from … from …` in a row is fine. > *Anchor:* "selecting components from a registry of 200+ from a scored, filtered candidate pool" **Pointer words (such / these / that) instead of repeating the noun.** > *Anchor:* "I've implemented such scenarios", "a harness around these steps" **Headline phrase + colon + content.** Colon is the main thought divider. NOT em-dash. > *Anchor:* "I am applying with some relevant experience:" > *Anchor:* "My day-to-day stack: [list]" **Parentheses for secondary detail.** > *Anchor:* "(see primeui.com)", "(on Mastra + Vercel AI SDK)", "(e.g. ...)" **Closings are short and dry.** > *Anchor:* "Open to chat if it's a fit." > NOT: "Happy to dig into specifics on a call" / "Looking forward to hearing from you" ### Lexicon — Oleg's anchor words Use these when they fit the meaning: - **harness** — infrastructure/wrapper around a core ("a harness around these steps with validation and retry") - **orchestrates / orchestration** — ("it orchestrates around 20 agent tools") - **registry** — component registry, registry of 200+ - **flow** — generation flow, publishing flow, quiz flows - **loop** — agent loop, "the loop runs until..." - **score / scored / scoring** — score system, scored candidate pool - **from scratch** — "I've been working on that project from scratch" - **assist / assists** — "the chatbot that assist users" - **etc** (not "and so on"), **based on**, **such / these / that** Default to system names and technical nouns, not decorative action verbs. ### Grammar signatures — preserve dosed, do NOT "fix" These are hand-markers of a Russian-speaking senior. Keep dosed to avoid sounding like a polished native. Do NOT preserve to the point of broken meaning. | Oleg writes | What the model usually "fixes" | Status | |---|---|---| | `AI based platform` (no article) | `an AI-based platform` | Keep dosed — drop article before compound nouns | | `reads... select... fills` (floating -s) | `reads... selects... fills` | Keep dosed — agreement floats within a clause | | `during more than one year` | `for over a year` | Keep in informal channels | | `assist users` (no -s) | `helps users` | Keep — his anchor word | | `I see the relevant experience in what I've been doing` | `My relevant experience comes from` | Keep — deliberate Russian calque for RU-team signal | **Calibration:** more unevenness in informal channels (Telegram, followup DMs); cleaner in cover letters / essays — but still not a polished native. ### Clean errors — always fix, not voice These he accepted without pushback. They are typos, not signatures: | Oleg wrote | Correct | |---|---| | `splitted to:` | `split into:` | | `serveral` / `scenarious` | `several` / `scenarios` | | `exelent` | `excellent` | | `clients communication` | `client communication` | | `regulator approvements was` | `regulator approval was a critical step` | | `tested for a compatibility` | `tested for compatibility` | | `Senior AI Engineer .` (space before dot) | `Senior AI Engineer.` | --- ## Voice dictionary — key paired examples These are real edits: model's version (left) vs. what Oleg wrote or kept (right). The right column is the target voice. ### Verbs — do not upgrade to "native" verbs | Model wrote | Oleg wrote | What changes | |---|---|---| | I've built this pattern in several places | I've implemented such scenarios in several places | `implemented` + pointer `such scenarios` | | picks the best-matching component by score | select a best matching component based on a score system | postposition `based on a score system` instead of compression | | fills its props from a compact component schema | fills props based on compact component schema | drops article; `based on` | | I built a harness around these steps | I also created a harness around these steps | `created` not `built`; leading `also` | | the chatbot that helps users create and modify | the chatbot that assist users in creating/modifying | `assist`, `in creating/modifying` | ### Self-characterisation — colon + facts, not claims | Model wrote | Oleg wrote/kept | What changes | |---|---|---| | I'm a direct match | My day-to-day stack: [list] | Does not claim fit — gives facts via colon-header | | My day-to-day stack matches yours | [specific years-on-stack per technology] | "too casual" — replaced with per-tech year claims | | The core of the role is the work I've been doing | [opens directly with own work, no JD recap] | Does NOT recap the JD back to the employer | ### Vague → short concrete sentences | Model wrote | Oleg wrote/kept | What changes | |---|---|---| | Multi-tenant and white-label is not new to me | [short concrete sentences: mobile app, web portal, casino team, betting widgets as consumers of one backend] | "too poetic" — replaced with named entities | | Built the AI layer containing some independent AI flows | [named 4 flows: content writing, page generation, chatbot, sitemap generation] | specific count + names | | Happy to dig into specifics on a call | Open to chat if it's a fit. | shorter, drier, his register | ### Connectives — cut, don't glue | Model wrote | Oleg wrote | What changes | |---|---|---| | So, the content team ran experiments... | Content team ran experiments... | dropped leading `So,` | | Furthermore / Moreover / That said | [new sentence or colon, no connective] | connection from content, not from a word | | — (em-dash on insert) | `:` or `,` or separate sentence | em-dash on parenthetical = not his | ### Calibration — one full pair **Model version (left, polished native):** > PrimeUI is an AI-based platform that generates production-level codebases for client websites, with a strong focus on the design quality of components and pages — I've worked on it from scratch for over a year. The core of page generation is a planner agent that iterates section by section across a page, autonomously selecting components from a registry of 200+ via a scored, filtered candidate pool. Each step reads the previously generated content, picks the best-matching component by score, and fills its props from a compact component schema. I built a harness around these steps with validation and a retry system. **Oleg's version (right, target voice):** > PrimeUI is AI based platform for generation production level codebases for clients websites with a focus on hi design quality of components and pages. I've been working on that project from scratch during more than one year. The core of pages generation is a planner agent that iterates section by section across a page, autonomously selecting components from a registry of 200+ from a scored, filtered candidate pool. Each step reads the previously generated content, select a best matching component based on a score system, fills props based on compact component schema. I also created a harness around these steps with validation and retry system. Differences: drop-articles, comma-chain without `and`, double `from … from`, postposition `based on`, floating -s, `from scratch during more than one year`, `created` not `built`. --- ## "Yes." rule Bare "Yes." as opener — **only** in followup DMs where: - There is a concrete closed yes/no question. - Format "yes/no → then elaborate" is appropriate. > *OK:* "Do you have a production use case where an LLM operated in a loop?" → "Yes. On primeui.com I've built this pattern..." **Do NOT use** in: cover letters, essays, first outreach, any text that is not a direct reply to a closed question. --- ## Stop-list — not Oleg's voice (linter catches the detectable subset) If any of these appear — rewrite: - `—` em-dash on parenthetical inserts - Perfectly parallel bullet structure (identical grammar form on every bullet) - GPT words: **leverage, robust, seamless, passionate, thrilled, delve, tapestry, navigate** (metaphorical), **cutting-edge, actionable, empower, streamline, unlock** - Smooth openers: **Furthermore, Moreover, That said, Additionally, Ultimately, However, Importantly** - "looking forward to", "happy to", "excited to", "I am writing to", "in today's" - "it's worth noting", "it's important to remember", "In conclusion", "Overall," - Even, monotone rhythm across all sentences - "honest framing / one thing to flag / I want to be honest about one thing" — not his pattern (gaps he names in his own words, without this template) - "I'm a great fit" / "I'm a direct match" / "my stack matches yours" — self-claims instead of facts --- ## Pre-delivery checklist Run after the lint loop exits 0: 1. No em-dash on inserts? → replaced with `:` / `,` / separate sentence. 2. Lint script exits 0? → required. 3. Rhythm still uneven? → short and long sentences alternate, no monotone flow. 4. Anchor nouns present (harness, registry, loop, flow, score, etc.) where they fit? 5. No JD recap in the opening of a cover letter? 6. Colon-headers used where the format is "phrase + content"? 7. Closing is short and dry? (e.g. "Open to chat if it's a fit.") 8. "Yes." opener only if this is a direct reply to a closed question? 9. No "one thing to flag / honest framing" construction? 10. Grammar signatures dosed correctly for the channel (more in DMs, less in cover letters)?