writer
Skill9 starsChanged 11 months agoMITView on GitHub
Generate content in your authentic voice across emails, blogs, social media, and reports
13 other projects use a version of this.
Adopted by
Most recently taken up by
- lumpcode/lumpcodetheir own version, first seen Nov 8, 2026
- David-Florian2013/write-then-checktheir own version, first seen Nov 1, 2026
- wellwelwel/lagunetheir own version, first seen Oct 31, 2026
- danielgefen/soustheir own version, first seen Aug 25, 2026
- flaqai/backlink_skillstheir own version, first seen Aug 19, 2026
- xjsongphy/skillstheir own version, first seen Aug 17, 2026
Other versions13 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 13
- flaqai/backlink_skills★ 872same name
- wellwelwel/lagune★ 177same name
- microsoft/aspnetcore-ja-handbook★ 33same name
- Mikefluff/skills★ 26same name
- lumpcode/lumpcode★ 12same name
- botlearn-ai/botlearn-skills★ 9same name
- xjsongphy/skills★ 7same name
- zdyya/writer-skill★ 4same name
- Notryag/north-agent★ 1same name
- vinitjhawar/opencouncil★ 1same name
3 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository33 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- assistant-architectSkill
- cfo-briefingSkill
- clawdbot-monitorSkill
- docxSkill
- drafts-managerSkill
- elevenlabs-ttsSkill
- freshservice-managerSkill
- google-workspaceSkill
- image-genSkill
- knowledge-managerSkill
- legislative-trackerSkill
- local-ttsSkill
- morning-briefingSkill
- multi-model-researchSkill
- obsidian-managerSkill
- omnifocus-managerSkill
- pai-monitorSkill
- pdfSkill
- pdf-to-markdownSkill
- personal-strategic-planningSkill
- pptxSkill
- presentation-masterSkill
- psd-athleticsSkill
- psd-brand-guidelinesSkill
- psd-instructional-visionSkill
- redrover-managerSkill
- researchSkill
- seven-advisorsSkill
- skill-creatorSkill
- sop-creatorSkill
- strategic-planning-managerSkill
- xlsxSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
35 rules. 0 are common, 27 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 11 edited versions we read keep these.
27
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 37
Use this skill when you need to:
- Distinctive: line 38
Write emails that sound like you (not generic AI)
- Distinctive: line 40
Create social media content consistent with your style
- Distinctive: line 42
Ensure content authentically represents your perspective and voice
- Distinctive: line 90
Check confidence and sample count:
- Distinctive: line 91
If confidence ≥ 0.85: Proceed with confidence
- Distinctive: line 92
If confidence 0.70-0.84: Proceed with note
- Distinctive: line 93
If confidence < 0.70: Warn user, offer options
- Distinctive: line 127
Ask follow-up questions for vague answers
- Distinctive: line 172
Goal: Create a clear structure before writing
- Distinctive: line 175
Create outline based on:
- Distinctive: line 241
Goal: Write content that authentically sounds like you
- Distinctive: line 249
Use for personality alignment:
- Very specific: line 259
Opening: Use patterns from opening_patterns
- Very specific: line 260
Closing: Use patterns from closing_patterns
- Very specific: line 264
Use Geoffrey's native writing capabilities
- Distinctive: line 272
Write naturally with rich voice context
- Distinctive: line 273
Don't mechanically apply patterns
- Distinctive: line 280
Goal: Ensure draft authentically matches your voice
- Distinctive: line 285
Read the draft I just generated
- Very specific: line 286
Read the voice profile (voice_characteristics + examples)
- Distinctive: line 322
If user approves refinement:
- Distinctive: line 475
Read all sample files
- Distinctive: line 501
Purpose: Ensure voice reflects personality (analytical, direct, impact-driven)
- Very specific: line 589
Detection: Check last_updated in writing-voice.json
- Distinctive: line 781
New Contexts: No profile for content types you haven't written before
- Distinctive: line 791
No Spanish email profile (even though you write Spanish emails)
- Distinctive: line 848
Check if file exists:
- Very specific: line 852
If missing: Run initial setup (extract samples + ask Geoffrey to analyze)
- Distinctive: line 853
If file exists but profile missing: Add samples for that content type
- Very specific: line 863
Ask Geoffrey to re-analyze with new samples
- Distinctive: line 882
Cause: Not logged into LinkedIn/X, or selectors changed
- Distinctive: line 889
If still fails: Platform may have changed selectors (update script)
- Very specific: line 896
Identity Alignment: Always cross-reference identity-core.json for personality consistency
- Distinctive: line 898
Versioning: All drafts saved to Obsidian with version numbers
“Common” is measured: kept by at least 6 in 10 of the 11 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Writer Skill
Generate content in your authentic voice by analyzing writing samples and applying learned voice patterns through adaptive interviewing and voice-matched generation.
Philosophy
Key Innovation: This isn't a generic AI writer - it's YOUR voice, learned from YOUR writing.
Unlike generic AI content generation, this skill:
- Learns from 6 distinct voice profiles (work email, personal email, blog, LinkedIn, Twitter, reports)
- Interviews you like a Pulitzer-winning journalist to deeply understand your message
- Validates output against your authentic patterns (not generic "good writing")
- Saves versioned drafts to Obsidian for iteration and history
Simplicity: Geoffrey's native LLM capabilities analyze your voice. Scripts just fetch samples. No complex NLP libraries - clean, maintainable architecture.
When to Activate
Use this skill when you need to:
- Write emails that sound like you (not generic AI)
- Draft blog posts in your established voice
- Create social media content consistent with your style
- Generate reports matching your professional tone
- Ensure content authentically represents your perspective and voice
DON'T use for:
- Quick factual responses (use native Claude)
- Content in someone else's voice
- Generic templates
Voice Profiles
Six distinct profiles capture different contexts:
| Profile | Source | Sample Target | Status |
email_work | PSD Gmail (sent emails, 6mo) | 50+ emails | Check writing-voice.json |
email_personal | Personal/HRG Gmail (sent, 6mo) | 50+ emails | Check writing-voice.json |
blog_technical | psd401.ai + blog.krishagel.com | 10+ posts | Check writing-voice.json |
social_linkedin | LinkedIn profile posts | 30+ posts | Check writing-voice.json |
social_twitter | X/Twitter posts | 30+ posts | Check writing-voice.json |
report_formal | User-provided samples | 5-10 reports | Check writing-voice.json |
Confidence Levels:
- High (0.85+): 50+ samples - voice well established
- Moderate (0.70-0.84): 20-49 samples - patterns emerging
- Low (<0.70): <20 samples - insufficient data, warn user
6-Phase Workflow
Phase 1: Voice Profile Selection & Validation
Goal: Load the right voice profile and verify it's ready
Process:
- Detect content type from user request:
- "write email" →
email_workoremail_personal(ask which) - "blog post" →
blog_technical - "LinkedIn post" →
social_linkedin - "tweet" →
social_twitter - "report" →
report_formal
- "write email" →
- Load voice profile:
cat ~/Library/Mobile\ Documents/com~apple~CloudDocs/Geoffrey/knowledge/writing-voice.json - Check confidence and sample count:
- If confidence ≥ 0.85: Proceed with confidence
- If confidence 0.70-0.84: Proceed with note
- If confidence < 0.70: Warn user, offer options
Low Confidence Response:
Only {sample_count} {content_type} samples (confidence: {confidence}).
Target: {target_samples}+ samples for 0.85+ confidence.
Options:
1. Gather more samples (recommended)
2. Use {alternative_profile} voice as proxy (confidence: {alt_confidence})
3. Proceed anyway (may not fully match your voice)
Preference?Checkpoint 1: User confirms profile or gathers more samples
Phase 2: Deep Interview (Adaptive)
Goal: Deeply understand what you want to communicate
Process:
- Load interview questions from
templates/interview-questions.json - Adapt depth to content type:
- Tweet/Social: 3-5 questions (~2-3 min)
- Email Quick: 4 questions (~3 min)
- Email Complex: 8 questions (~5 min)
- Blog: 8-12 questions (~5-8 min)
- Report: 15+ questions (~10-15 min)
- Interview like a journalist:
- Ask follow-up questions for vague answers
- Probe for examples, data, evidence
- Clarify ambiguities
- Build structured understanding
Email Interview Example (complex):
1. Who are the recipient(s) and what's the context?
→ [User answers]
2. What's the primary goal?
→ [User answers]
[If vague: "Can you be more specific about the outcome you want?"]
3. What background do they need?
→ [User answers]
4. What are the key points? (Max 3-5)
→ [User answers]
[If >5: "Let's focus on the most critical 3-5 points."]
... continue through 8 questionsBlog Interview Example:
1. What's your central message?
2. Why does this matter right now?
3. What should readers do/think/feel after?
4. What evidence supports this?
5. Any stories or case studies?
6. Main counterarguments?
7. How should it open?
8. Key sections (3-5)?
9. How should it close?
10. Primary audience and technical level?
11. Desired tone?Checkpoint 2: Review interview summary, add missing details
Phase 3: Content Planning & Outline
Goal: Create a clear structure before writing
Process:
- Create outline based on:
- Interview responses
- Content type structure (email: intro + points + ask, blog: hook + body + conclusion)
- Voice profile preferences (e.g., blog uses chronological flow, staff quotes)
- Apply voice-specific patterns:
- Email: Opening pattern, bullet points for key points, clear ask
- Blog: Subheadings for scannability, narrative flow, reflective close
- Social: Hook first line, call-to-action
- Suggest length from profile:
- Email avg: Check profile examples
- Blog avg: Check profile examples
- Social: Platform limits (LinkedIn 1300 chars, Twitter 280 chars)
Email Outline Example:
## Email Plan
**Subject**: [Based on purpose]
**Opening**: [Use opening pattern from profile, e.g., "I've reviewed {topic}..."]
**Body**:
- Point 1: [From interview]
- Point 2: [From interview]
- Point 3: [From interview]
**Ask**: [Specific call-to-action from interview]
**Closing**: [Use closing pattern from profile, e.g., "Let me know if..."]
**Tone**: Direct, professional, action-oriented
**Length**: ~200 words (typical for email_work)Blog Outline Example:
## Blog Plan
**Title**: [Derived from central message]
**Structure**:
1. Opening: [Hook strategy - context-setting or reflective quote]
2. Background & Context
3. [Main section 1]
4. [Main section 2]
5. [Main section 3]
6. Impact & Results
7. Closing: [Forward-looking reflection]
**Voice elements**:
- Staff quotes (use throughout)
- Chronological narrative flow
- Subheadings for scannability
- Accessible but authoritative tone
**Length**: ~850 words (typical for blog_technical)Checkpoint 3: User approves outline
Phase 4: Draft Generation
Goal: Write content that authentically sounds like you
Process:
Load identity context:
cat ~/Library/Mobile\ Documents/com~apple~CloudDocs/Geoffrey/knowledge/identity-core.jsonUse for personality alignment:
communication_preferences.style→ Direct, no-nonsense, concisedecision_framework→ Analytical, evidence-basedtelos_summary.top_3_values→ Equity, excellence, empathy
- Apply voice characteristics as generation guidelines:
- Tone: From
voice_characteristics.tone - Sentence structure: From
voice_characteristics.sentence_structure - Vocabulary: Common terms, avoided terms
- Formatting: Bullet points, markdown, emphasis patterns
- Opening: Use patterns from
opening_patterns - Closing: Use patterns from
closing_patterns - Argument structure: Lead with conclusion, use evidence
- Tone: From
- Write content naturally:
- Use Geoffrey's native writing capabilities
- Guided by voice profile (not rigid pattern matching)
- Weave in interview content (examples, data, stories)
- Match typical length from profile examples
- Reference example emails/posts from profile for inspiration
Generation Approach (Hybrid):
- Write naturally with rich voice context
- Don't mechanically apply patterns
- Let voice characteristics inform style, not constrain creativity
Phase 5: Validation & Refinement
Goal: Ensure draft authentically matches your voice
Native LLM Validation (no script needed):
- Geoffrey self-validates by comparing draft to voice profile:
- Read the draft I just generated
- Read the voice profile (
voice_characteristics+examples) - Compare tone, structure, vocabulary, formatting
- Score alignment 0-100
- Scoring criteria (weighted):
- Tone match (20%)
- Sentence structure - length, complexity (15%)
- Vocabulary - common/avoided terms (15%)
- Formatting - bullets, markdown, emphasis (10%)
- Opening pattern match (10%)
- Closing pattern match (10%)
- Argument structure - conclusion placement, evidence use (10%)
- Stylistic markers - contractions, punctuation, framing (10%)
- Identify specific deviations:
- "Sentences 15% longer than typical (avg 16 words vs typical 14)"
- "Missing characteristic bullet points (you use them 67% of time)"
- "Tone slightly more formal than usual"
- Scoring thresholds:
- 85-100: Excellent match, present draft
- 70-84: Good match with minor deviations, note them
- <70: Significant deviations, propose refinements
Refinement (if score < 85):
Voice Validation: {score}/100
Issues:
- {Issue 1 with specific evidence}
- {Issue 2 with specific evidence}
- {Issue 3 with specific evidence}
Should I refine to better match your voice?If user approves refinement:
- Apply specific fixes identified
- Re-validate
- Present refined draft
Checkpoint 4: User accepts, requests refinement, or manually edits
Phase 6: Storage & Versioning
Goal: Save draft to Obsidian with proper versioning
Process:
Determine file path:
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Personal_Notes/Geoffrey/Writing/{ContentType}/{date}-{slug}.mdContent types:
- Blog →
Geoffrey/Writing/Blog/ - Email →
Geoffrey/Writing/Email/ - Social →
Geoffrey/Writing/Social/ - Reports →
Geoffrey/Writing/Reports/
- Blog →
- Generate frontmatter:
--- created: 2025-12-06 type: blog profile: blog_technical topic: AI implementation status: draft version: 1.0 validation_score: 87 word_count: 847 tags: [geoffrey, writing, ai] source: geoffrey-writer interview_date: 2025-12-06 --- - Save file using Obsidian MCP tools:
mcp__obsidian-vault__create_vault_file - Also return text directly (copy-paste ready)
- Offer to open in Obsidian:
mcp__obsidian-vault__show_file_in_obsidian
Versioning:
- Initial:
version: 1.0 - Refinements:
version: 1.1,1.2 - Major rewrites:
version: 2.0
Output to user:
## Draft Complete
**Validation Score**: 87/100 ✓
**Word Count**: 847
**Profile**: blog_technical
**Saved to**: Geoffrey/Writing/Blog/2025-12-06-ai-implementation.md
[Full draft text here]
Actions:
1. Open in Obsidian
2. Request refinements
3. Mark as finalVoice Learning Process
Initial Setup (Before First Use)
Required: Gather writing samples for each profile you'll use
Step 1: Email Samples (3 accounts)
# PSD work emails
bun scripts/extract-email-samples.js \
--account psd \
--date-range "2024-06-01:2025-12-06" \
--max-samples 100 \
--output "/tmp/email-samples-psd.json"
# Personal emails
bun scripts/extract-email-samples.js \
--account kh \
--date-range "2024-06-01:2025-12-06" \
--max-samples 50 \
--output "/tmp/email-samples-kh.json"
# Business/consulting emails
bun scripts/extract-email-samples.js \
--account hrg \
--date-range "2024-06-01:2025-12-06" \
--max-samples 50 \
--output "/tmp/email-samples-hrg.json"Step 2: Blog Samples
# Launch Geoffrey Chrome (for personal blog access)
cd ~/non-ic-code/geoffrey/skills/browser-control
./scripts/launch-chrome.sh
# Extract blog posts
cd ~/non-ic-code/geoffrey/skills/writer
bun scripts/extract-blog-samples.js \
--urls "https://psd401.ai/blog/stanford-ai-tinkery-2025,https://psd401.ai/blog/why-this-website,https://blog.krishagel.com/post1,https://blog.krishagel.com/post2" \
--output "/tmp/blog-samples.json"Step 3: Social Media Samples (requires login)
# IMPORTANT: Manually log into LinkedIn and X in Geoffrey Chrome first
# LinkedIn
bun scripts/extract-social-samples.js \
--platform linkedin \
--profile-url "https://linkedin.com/in/krishagel" \
--max-posts 50 \
--output "/tmp/social-linkedin.json"
# Twitter/X
bun scripts/extract-social-samples.js \
--platform twitter \
--profile-url "https://x.com/KrisHagel" \
--max-posts 50 \
--output "/tmp/social-twitter.json"Step 4: Geoffrey Analyzes
Tell Geoffrey:
Analyze my writing samples and create voice profiles.
Email samples: /tmp/email-samples-psd.json, /tmp/email-samples-kh.json, /tmp/email-samples-hrg.json
Blog samples: /tmp/blog-samples.json
Social samples: /tmp/social-linkedin.json, /tmp/social-twitter.jsonGeoffrey will:
- Read all sample files
- Analyze each profile's:
- Tone and voice
- Sentence structure patterns
- Vocabulary (common/avoided terms)
- Formatting preferences
- Opening/closing patterns
- Argument structure
- Distinctive markers
- Select representative examples
- Calculate confidence scores
- Write to
writing-voice.json:~/Library/Mobile Documents/com~apple~CloudDocs/Geoffrey/knowledge/writing-voice.json
Estimated time: 30-45 min initial setup
Integration Points
knowledge-manager → Identity Context
When: Phase 4 (Draft Generation)
Purpose: Ensure voice reflects personality (analytical, direct, impact-driven)
How:
cat ~/Library/Mobile\ Documents/com~apple~CloudDocs/Geoffrey/knowledge/identity-core.jsonUse:
communication_preferences→ Tone, style, dislikesdecision_framework→ Analytical, evidence-based approachtelos_summary→ Values (equity, excellence, empathy), missionstrengths_essence→ Input (collector), Significance (impact), Analytical
google-workspace → Email Samples
When: Initial voice creation + quarterly refresh
Scripts: search_messages.js, read_message.js
Process:
- Search sent emails
- Filter automated, short, quoted
- Clean signatures, HTML
- Extract plain text + metadata
- Save to JSON for Geoffrey to analyze
browser-control → Blog/Social Samples
When: Initial voice creation + ad-hoc updates
Prerequisites: Geoffrey Chrome running with logins
Process:
- Navigate to blog/profile URL
- Extract article/post content
- Handle scrolling/lazy-loading (social)
- Parse and clean content
- Save to JSON
obsidian-manager → Draft Storage
When: Phase 6 (Storage)
Folder structure:
Geoffrey/Writing/
├── Blog/
├── Email/
├── Social/
└── Reports/File format: YYYY-MM-DD-{slug}.md with frontmatter
Edge Cases & Handling
Insufficient Samples
Scenario: User requests email, but only 12 samples (confidence 0.62)
Response:
Only 12 email_work samples (0.62 confidence). Target: 50+ for 0.85+ confidence.
Options:
1. Gather ~40 more email samples from recent sent (recommended)
2. Use email_personal as proxy (if similar, confidence: 0.88)
3. Proceed with low confidence (may not fully match your voice)
Note: Voice profiles improve with more samples. I can still write, but authenticity may vary.
Preference?Voice Drift (Outdated Profile)
Scenario: Profile last updated 18 months ago
Detection: Check last_updated in writing-voice.json
Response:
Your email_work profile is 18 months old (last updated: 2024-06-15).
Writing styles evolve over time.
Recommendation: Refresh with recent samples (past 6 months)
Run:
bun scripts/extract-email-samples.js --account psd --date-range "2024-06-01:2025-12-06" --max-samples 100 --output "/tmp/email-refresh.json"
Then ask me to analyze and update the profile.
Proceed with current profile or refresh first?Contradictory Samples
Scenario: Email samples vary significantly (45% formal, 35% casual, 20% mixed)
Geoffrey analyzes and responds:
Your email_work voice varies significantly across samples:
- 45% formal (board, superintendent, external)
- 35% casual (staff, peers, project teams)
- 20% mixed
Options:
1. Split into email_work_formal and email_work_casual profiles
2. Choose dominant style (formal) as default
3. Let me dynamically adjust based on recipient (you specify each time)
Preference?Low Validation Score
Scenario: Draft scores 62/100
Response:
Voice Validation: 62/100 ⚠️
Issues:
- Tone too formal (target: direct, action-oriented)
Example: "It would be appreciated if you could consider..." vs typical "Please review and confirm."
- Sentences 35% longer (avg 19 words vs typical 14)
Example: Draft paragraph 2 avg 21 words, your emails avg 14 words.
- Missing bullet points (you use bullets 67% of the time for key points)
Draft uses prose for 5 key points, you typically bullet them.
Should I refine to better match your voice?New Content Type
Scenario: User requests "write a press release"
Response:
I don't have a press_release voice profile yet.
Options:
1. Use report_formal profile as starting point (confidence: 0.83)
2. Provide 5-10 past press releases for me to analyze
3. Write without voice matching (generic professional press release style)
Note: If you provide samples, I can create a new press_release profile.
Preference?Usage Examples
Example 1: Quick Work Email
User: "Write email to my team about next week's leadership meeting"
Geoffrey:
I'll use your email_work profile (confidence: 0.92, 156 samples).
Quick interview (4 questions):
1. Who's the team and what's your relationship?
→ [User: Direct reports - IT leadership team]
2. Purpose? (inform, request, respond, update)
→ [User: Inform and request prep]
3. Key information?
→ [User: Meeting Tuesday 2pm, agenda items: budget, staffing, AI roadmap. Need their input on AI priorities.]
4. Tone?
→ [User: Professional but casual - these are my directs][Generates outline] → User approves
[Generates draft, validates (score: 89), presents to user]
Example 2: Blog Post
User: "Write blog post about our AI implementation journey"
Geoffrey:
I'll use your blog_technical profile (confidence: 0.78, 4 samples).
Note: Only 4 blog samples. Recommend 6+ more for 0.85+ confidence.
Proceed or gather more samples first?
→ [User: Proceed]
Standard interview (11 questions):
1. Central message?
→ [User: ...]
2. Why now?
→ [User: ...]
[... continues through 11 questions ...][Creates detailed outline] → User approves
[Generates ~850 word draft with staff quotes, chronological flow, reflective close]
[Validates (score: 87), presents draft]
[Saves to Geoffrey/Writing/Blog/2025-12-06-ai-implementation-journey.md]
Example 3: LinkedIn Post
User: "LinkedIn post about Stanford AI Tinkery visit"
Geoffrey:
I'll use your social_linkedin profile (confidence: 0.91, 48 posts).
Quick interview (5 questions):
1. Main point (1-2 sentences)?
→ [User: Visited Stanford's AI Tinkery with district team. Collaborative learning happening everywhere, not just at elite institutions.]
2. Target audience?
→ [User: Ed tech leaders, superintendents]
3. Tone?
→ [User: Inspirational, reflective]
4. Call-to-action?
→ [User: Encourage others to build their own learning networks]
5. Link or visual?
→ [User: No link, maybe photo but I'll add later][Generates ~180 word LinkedIn post]
[Validates (score: 92), presents]
Limitations
Known Constraints
- Sample Dependency: Voice quality directly tied to sample quantity and quality
- Low samples (<20) = low accuracy
- Poor quality samples = poor voice matching
- Voice Drift: Styles evolve over time
- Recommend quarterly refresh (every 3 months)
- Auto-warn if profile >12 months old
- New Contexts: No profile for content types you haven't written before
- Press releases, technical docs, grant proposals require new samples
- Can adapt existing profiles but may not match perfectly
- Platform Nuances: Social media scraping limitations
- LinkedIn/X may change selectors
- Requires manual login
- May violate ToS (user accepted risk)
- Multilingual: Currently English only
- No Spanish email profile (even though you write Spanish emails)
- Could add with Spanish samples
- Collaborative Writing: Single voice only
- Can't blend your voice + co-author
- Future enhancement
Validation & Quality
Success Metrics
Quantitative:
- Voice alignment: 85+ for established profiles (0.85+ confidence)
- Sample size: 50+ emails, 10+ blogs, 30+ social per profile
- User acceptance: >80% drafts accepted with minor/no edits
- Refinement iterations: <2 average
Qualitative:
- User feedback: "This sounds like me"
- Consistent voice across topics within profile
- Authentic, not mechanical or formulaic
Quality Checklist
Before presenting draft:
- ✓ Matches tone from voice profile
- ✓ Sentence structure within 20% of typical length
- ✓ Uses common vocabulary, avoids avoided terms
- ✓ Follows formatting preferences (bullets, markdown)
- ✓ Opening/closing match typical patterns
- ✓ Argument structure aligned (conclusion placement, evidence use)
- ✓ Validation score ≥85 (or explained deviations if <85)
- ✓ Word count within typical range for content type
Future Enhancements (Out of Scope)
- Real-time Learning: Auto-analyze new sent emails monthly
- A/B Testing: Generate 2 versions, learn from user choices
- Collaborative Voice: Blend user + co-author voices
- Multi-language: Spanish voice profiles
- Performance Tracking: Voice drift detection over time
- Audience-Aware: Sub-profiles (email_work_superintendent vs email_work_staff)
- Feedback Loop: User rates content, Geoffrey learns from scores
Troubleshooting
"No voice profile found"
Cause: writing-voice.json doesn't exist or profile type missing
Solution:
- Check if file exists:
cat ~/Library/Mobile\ Documents/com~apple~CloudDocs/Geoffrey/knowledge/writing-voice.json - If missing: Run initial setup (extract samples + ask Geoffrey to analyze)
- If file exists but profile missing: Add samples for that content type
"Low confidence warning"
Cause: Fewer than 20 samples for profile
Solution:
- Gather more samples using extraction scripts
- Ask Geoffrey to re-analyze with new samples
- Or: Proceed with caveat that voice may not fully match
"Geoffrey Chrome not running"
Cause: Social/blog extraction requires Geoffrey Chrome with remote debugging
Solution:
cd ~/non-ic-code/geoffrey/skills/browser-control
./scripts/launch-chrome.sh"Failed to extract social posts"
Cause: Not logged into LinkedIn/X, or selectors changed
Solution:
- Open Geoffrey Chrome manually
- Navigate to LinkedIn/X and log in
- Verify posts load
- Re-run extraction script
- If still fails: Platform may have changed selectors (update script)
Notes
- Progressive Disclosure: Load only the profile needed for current task (not all 6)
- Identity Alignment: Always cross-reference identity-core.json for personality consistency
- Checkpoints: 4 user approval points prevent wasted effort
- Versioning: All drafts saved to Obsidian with version numbers
- Native Analysis: Geoffrey's LLM capabilities analyze voice - no complex libraries needed
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

