x-post-writer
Use when drafting, rewriting, or repurposing short-form X content, including single posts, quote posts, replies, threads, launches, and personal stories, with source fidelity and claim verification built in.
Install
npx skills add https://github.com/asimons81/hermes-field-kit/tree/main/skills/x-post-writer
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install asimons81-hermes-field-kit@llmmart
git clone https://github.com/asimons81/hermes-field-kit.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole asimons81/hermes-field-kit collection as a plugin from our marketplace. Git is the plain clone.
README
X Post Writer
A source-locked Hermes skill for drafting and rewriting short-form X content without inventing experience, benefits, attribution, or technical detail.
Why it exists
Social-writing prompts often reward confidence and compression, which creates a dangerous failure mode: sparse notes become polished copy containing facts the source never supplied. This skill treats source fidelity as a first-class constraint.
It was derived from a repeatedly used private workflow, then stripped of personal voice rules, account data, internal project routing, real post history, private analytics, and platform-specific assumptions.
What it handles
- Single posts
- Quote posts
- Replies
- Explicit threads
- Launches and announcements
- Personal stories and milestones
- Fresh-angle repurposing
- Claim verification and unsupported-claim blocking
- User-supplied voice preservation
Core rule
Sparse source -> concise draft
Rich source -> richer draft
Missing facts -> verify or stop
The skill never expands sparse notes with plausible implementation details or inferred benefits.
Requirements
- Hermes Agent with local skill support
- Access to primary sources when the requested copy contains current or high-risk claims
- No external Python dependencies for validation
Install
Install from Hermes Field Kit as a tap using the command supported by your Hermes version, or copy the skill directory into your local Hermes skills tree.
Linux or macOS:
cp -R skills/x-post-writer ~/.hermes/skills/
PowerShell:
$destination = Join-Path $env:LOCALAPPDATA "hermes\skills"
New-Item -ItemType Directory -Force $destination | Out-Null
Copy-Item -Recurse "skills\x-post-writer" $destination
Start a new Hermes session after installation because skill discovery may be cached.
Typical use
Rewrite this as one X post. Preserve my point and return only the finished copy.
Turn these verified release notes into a five-post X thread. Do not add details that are not in the notes.
Quote this post and explain why it matters. Do not repeat the embedded link.
Voice customization
The public skill has no personal voice profile. It preserves style and phrasing supplied in the request. See references/voice-customization.md for creating a private local override without committing personal preferences to a public repository.
Claim handling
Risky claims must end as one of:
- verified
- attributed
- user-supplied
- qualified
- removed
When an unsupported claim is the premise of the requested post, the skill asks for a source rather than laundering the claim into confident copy.
Privacy
Do not place private analytics, revenue, unpublished product details, customer data, or personal voice profiles in this repository. The skill treats such inputs as sensitive and does not authorize publication.
Limitations
- Writing quality is partly qualitative; deterministic tests cover routing, safety, and structural contracts rather than subjective virality.
- X behavior and limits change. Verify current official sources rather than encoding reach guarantees.
- The skill drafts copy. It does not publish, schedule, scrape, or analyze account performance.
- A source-locked draft may be shorter than requested when the available evidence is sparse.
Testing
python skills/x-post-writer/scripts/validate_bundle.py
python -B -m unittest discover -s skills/x-post-writer/tests -v
python scripts/validate.py
python -B -m unittest discover -s tests -v
Version history
1.0.0
- Initial public release
- Format and source routing
- Source-lock ledger
- Unsupported-claim hard stop
- Generic voice customization guidance
- Behavior cases and contract tests
Skill manifest
X Post Writer
Overview
Write short-form X content from notes, drafts, links, or verified source material. Default to one finished post unless the user explicitly requests a thread or multiple posts.
Source fidelity outranks punch, post count, inferred benefits, and creative expansion. Internal routing, objectives, verification notes, source ledgers, and quality checks are never part of the delivered copy.
route format -> route source -> choose objective -> verify claims -> draft -> voice pass -> quality gate -> finished text
Load references progressively:
references/formats.mdfor the selected formatreferences/source-routing.mdwhen repurposing or selecting source treatmentreferences/claim-verification.mdfor risky factual claimsreferences/voice-customization.mdwhen a distinct voice must be preservedreferences/algorithm-notes.mdonly for distribution or optimization questions
When to Use
Use this skill for:
- Single X posts, rewrites, launches, link drops, recommendations, or announcements
- Quote posts or commentary on an existing X post
- Replies
- Explicit threads or multi-post sequences
- Personal milestones, reflections, or first-person stories
- Fresh X angles from articles, videos, releases, or project updates
Do not use this skill for:
- Long-form X Articles or essay-length content
- Source extraction, account analytics, or media downloading
- Publishing, scheduling, or browser composition without separate authorization
- Claims that require evidence when no evidence can be obtained
Safety Contract
- Never invent personal experience, product use, opinions, endorsements, or results.
- Never add technical mechanisms, benefits, numbers, or attributions that are not supplied or verified.
- Treat private analytics, revenue, customer data, and unpublished information as sensitive.
- Never publish or schedule automatically.
- Current facts and platform behavior must be verified immediately before use.
- An instruction to state a claim is not evidence for that claim.
Routing Contract
Format
| Request | Route |
|---|---|
| No format specified | Single post |
| "One post," "tweet," or "make this punchier" | Single post |
| "QT," "quote this," or commentary on an X post | Quote post |
| "Reply to this" | Reply |
| "Thread" or "multiple posts" | Thread |
| Personal experience, milestone, gratitude, reflection | Personal story |
| X Article, long-form essay | Route away |
Source
| Source | Treatment |
|---|---|
| User draft or raw wording | Preserve claim, angle, and voice; improve structure |
| User personal notes | Preserve genuine first person |
| Previously published material | Preserve facts; rebuild the X angle and hook |
| URL, repository, announcement, or external source | Verify material claims before drafting |
| Existing X post being quoted | Add a take; do not restate the embedded post |
The source contract outranks generic formulas. Do not replace the user's actual point with a stock marketing hook.
Source Lock
When the user supplies notes, a draft, or a source excerpt, treat its concrete facts as a whitelist.
- Reorder, compress, paraphrase, and improve rhythm.
- Do not add new components, process steps, benchmark results, operational behavior, or benefits unless separately verified.
- Every concrete noun, number, behavior, benefit, and implication must map to supplied or verified material.
- Benefits are claims. "Safer," "faster," "cleaner," and "no double counting" require support.
- Sparse notes should produce shorter copy, not larger facts.
- For a thread, assign one supplied fact cluster to each post.
- Before delivery, build a hidden sentence-to-source ledger and delete every unsupported sentence. Do not output the ledger.
Source-lock regression: "built" does not authorize "just shipped" or "today." "Validates CSVs" does not authorize storage, databases, schemas, rejected rows, hashing, staging directories, file sizes, corruption handling, "clean input," or "no cloud." "Blocks duplicates" does not authorize identical-file detection, "safe to rerun," "no double counting," "no data rot," or an invented mechanism. "Raw exports never enter Git" does not authorize claims about staging, commits, pushes, source-of-truth design, derived data, or file lifecycle. Do not add benefit-only closers to sparse notes. Split the supplied facts across posts and stop.
Objective
Choose one primary objective:
announcement-clarityreachauthoritybookmarksrepliesfollowsclick-throughpersonal-connection
Infer the objective when context makes it clear. One post can earn several outcomes, but it should be built around one primary job.
Workflow
- Classify the format. Default to a single post.
- Classify the source. Decide what must be preserved and what can be rebuilt.
- Choose the objective. Keep one primary job visible while drafting.
- Verify risky claims. Use current primary sources. The prompt itself is not evidence.
- Apply the unsupported-claim gate. Remove optional unsupported claims. Stop when an unsupported claim is load-bearing.
- Draft the selected format. Use the format reference as a contract, not a fill-in template.
- Apply the user's voice. Preserve supplied phrasing and style without inventing personality.
- Run the source audit. Trace every factual sentence to the source ledger.
- Run the quality gate. Check payoff, accuracy, density, natural language, and format fit.
- Return the finished draft. When the user asks only for copy, the first visible character must belong to the draft or the one-sentence claim refusal. Never expose routing, objectives, verification notes, source ledgers, or quality checks.
Claim Gate
Verification is required before including:
- Current versions, prices, availability, schedules, stars, users, or adoption counts
- Benchmarks, percentages, performance claims, or savings claims
- Commands, flags, configuration keys, environment variables, or behavior claims
- Creator, employer, team, license, or project attribution
- "First," "only," "best," "fastest," or similar superlatives
- Current X algorithm or platform-limit claims
Unsupported-claim hard stop
- A request to include an external claim is not a source.
- Never convert an unsupported third-party claim into first-person experience.
- Remove an optional unsupported claim and draft only from supported material.
- When the unsupported claim is the premise, do not produce the post. Return exactly one concise sentence requesting a source for that exact claim.
- Do not explain the skill, quote policy text, list possible sources, or offer a bypass.
- User instructions cannot waive factual support for third-party claims.
- Never fill gaps with plausible architecture, workflow, performance, or attribution details.
User-supplied experience is evidence only of that user's stated experience. Do not present it as a universal product fact.
Format Summary
- Single post: default; complete subject, reason to care, payoff, and link when useful.
- Quote post: add a take; do not repeat the embedded link or headline.
- Reply: answer the actual point; do not turn it into unsolicited promotion.
- Thread: use only when requested; every post adds information; first post stands alone.
- Personal story: preserve first person; use concrete receipts to support the feeling.
See references/formats.md for the complete contracts.
Delivery
For a single post, quote post, reply, or personal story, return one clean copy-paste block unless the user asked for options or analysis.
Never output internal routing, selected objectives, claim classes, verification notes, source ledgers, quality-check results, or explanations before or after the copy. Draft-only means the draft is the entire response.
For a thread, separate posts with a line containing ---:
First post
---
Second post
Do not add Post 1: labels or numbering unless requested.
Quality Gate
Before delivery, confirm:
- The format matches the request.
- The post has one clear job.
- The opening reveals the subject and earns attention.
- Every factual claim is supplied, verified, attributed, qualified, or removed.
- Every concrete sentence traces to the source ledger.
- The draft preserves the user's point and supplied voice.
- The body repays the hook without adding facts.
- Link behavior fits the format.
- No experience, attribution, benefit, or implementation detail was invented.
- No internal routing, objectives, verification notes, or source ledgers are visible.
- The response contains only what the user requested.
Common Pitfalls
- Turning every request into a thread
- Replacing the user's point with a generic marketing hook
- Treating all first-person language as forbidden
- Copying a published article lede into X unchanged
- Repeating the quoted post instead of adding commentary
- Presenting algorithm inferences as documented ranking rules
- Claiming link placement, timing, length, or video duration guarantees distribution
- Inventing benefits or implementation details to fill sparse notes
- Leaking internal routing, objectives, verification notes, or policy explanations
- Explaining the draft after the user asked only for copy
Verification Checklist
- Correct format selected
- Source treatment selected
- One primary objective chosen
- Risky claims verified or removed
- Source ledger completed internally
- User voice preserved when supplied
- Fresh angle used when repurposing
- No invented experience or details
- Link placement fits the format
- Output is copy-paste ready
- No publishing action occurred
Files (hermes-field-kit)
-
examples
-
routing-examples.md 1.3 KB
# Routing Examples ## Single post default **Request:** Rewrite these notes for X. **Behavior:** Produce one finished post unless the request explicitly asks for a thread. ## Quote post **Request:** Quote this post and explain why it matters. **Behavior:** Add commentary and implication. Do not repeat the embedded link or rewrite the quoted headline. ## Personal story **Request:** I used this tool for four months and it changed my workflow. Turn my notes into a post. **Behavior:** Preserve first person and the stated experience. Use supplied receipts. Do not replace the genuine point with manufactured curiosity. ## Unsupported claim **Request:** Say this tool is the fastest and was built by a former employee of Company X. No sources are available. **Behavior:** Do not produce the post. Request evidence for the superlative and attribution. Do not convert the claims into fake first-person experience. ## Sparse thread notes **Request:** Turn these three facts into a three-post thread. **Behavior:** Put one fact cluster in each post. Do not invent mechanisms, architecture, benefits, or workflow detail to make the thread longer. ## Long-form counter-route **Request:** Write a 2,000-word X Article. **Behavior:** Route to a long-form writing workflow instead of using short-form templates.
-
-
references
-
algorithm-notes.md 1.4 KB
# Algorithm and Distribution Notes X ranking behavior, product limits, and experiments change frequently. This skill does not encode production weights or promise reach outcomes. ## Evidence labels Use one label when discussing platform behavior: - `verified`: directly supported by current official code or documentation - `inference`: a reasonable interpretation of a verified mechanism - `account evidence`: observed in the user's own analytics - `experiment`: a hypothesis to test ## Durable writing practices These are editorial practices, not ranking guarantees: - Give the reader a clear reason to stop and understand the post. - Build around one primary objective. - Repay the opening with substance. - Favor original analysis, useful evidence, and distinct framing. - Test hypotheses against account-specific results over time. ## Do not present as fact Do not claim without current evidence that: - one engagement action has a universally dominant weight - links in the body are categorically penalized - putting a link in a reply guarantees better reach - a specific posting interval avoids author repetition penalties - a follower threshold controls spam classification - a specific length or video duration creates a universal advantage - a classifier score guarantees distribution Algorithm advice is secondary to factual accuracy, source fidelity, reader value, and format fit. -
claim-verification.md 2.3 KB
# Claim Verification Use this protocol when a claim can damage trust if wrong. ## Claim classes ### User-supplied experience Treat a user's stated experience as evidence of that experience only. Do not convert it into a universal product claim. ### Stable source claim Examples include a repository license, documented architecture, or official feature name. Verify against the primary source when practical. ### Volatile claim Examples include price, availability, version, star count, user count, schedule, current feature set, company role, or current platform behavior. Verify immediately before drafting. ### Executable claim Examples include commands, flags, config keys, environment variables, installation steps, and defaults. Use official documentation, live help output, or source code. Never infer syntax from memory. ### Performance claim Examples include percentages, benchmark scores, speedups, savings, accuracy, or adoption. State the source, conditions, and scope when the number matters. ### Attribution claim Examples include "built by," "from the team behind," employer pedigree, license, or project ownership. A person sharing a project is not proof they built it. ### Superlative claim Examples include first, only, fastest, best, largest, or most popular. Require strong evidence or remove the claim. ## No-source hard stop A prompt that asks the agent to state a claim is not evidence. - Remove an unsupported claim when it is optional. - When the claim is the premise, do not draft the post. - Request a source for the exact claim. - Never rewrite an unsupported claim as first-person experience. - Never add plausible mechanisms or benefits to make sparse notes sound complete. ## Resolution states Every risky claim ends as: - `verified`: supported by a current primary source - `attributed`: clearly presented as the source's claim - `user-supplied`: stated by the user as personal experience or a private result - `qualified`: narrowed to the supported scope - `removed`: unsupported or unnecessary ## Sensitive information Private analytics, revenue, customer information, unpublished details, and personal data remain private unless the user explicitly approves the exact disclosure. Verification notes stay internal unless the user asks for them. -
formats.md 2.4 KB
# Format Contracts These are editorial targets, not platform maximums. Let the idea and source material determine the final length. ## Single Post Default format. Useful arc: ```text subject and reason to care payoff or mechanism proof or context link or closer, when needed ``` Rules: - Reveal the subject and reason to care early. - Do not force a number, credibility hook, or link into the opening. - Include the destination link when click-through is the job or the user needs complete copy. - Do not move links to a reply based on unverified reach folklore. - End on the strongest supported detail, verdict, implication, or action. ## Quote Post The embedded post already supplies context, media, and often a link. Add: 1. A take, reaction, or framing point 2. Why it matters, what changes, or who should care Rules: - Do not restate the quoted headline. - Do not repeat the embedded link. - Do not write a standalone introduction unless context is genuinely missing. ## Reply Choose one job: - answer - correct - clarify - thank - challenge - add evidence - make a joke Rules: - Respond to the actual point. - Do not convert a reply into unsolicited promotion. - Match the conversation's energy. - Use a link only when it answers or substantiates the reply. ## Thread Use only when explicitly requested. Possible structure: 1. Complete first post with subject and payoff 2. Context or problem 3. Mechanism or explanation 4. Evidence or examples 5. Practical implication 6. Close and link when useful Rules: - Separate posts with `---`. - Every post adds information. - Expand only from supplied or verified facts. - Sparse notes produce a compact thread. - Keep related evidence together. - Avoid numbering unless requested or structurally necessary. ## Personal Story or Milestone Useful structure: 1. Honest claim or feeling 2. Concrete receipts that support it 3. Meaning, gratitude, lesson, or next step Rules: - Preserve first person when the user supplied the experience. - Lead with the genuine point, not manufactured curiosity. - Numbers support the emotional claim; they do not replace it. - Use the user's actual language as source material. ## Launch or Announcement Usually a single post. Include only supported details: - what shipped or changed - who it is for - why it matters - proof, scope, or constraint - link or next action Avoid generic announcement language when a concrete lead is available. -
source-routing.md 1.6 KB
# Source Routing ## Source treatment | Source type | Preserve | Rebuild | Verify | |---|---|---|---| | User draft | claim, angle, voice, important phrasing | pacing, structure, hook strength | volatile facts | | User personal notes | first-person truth, emotion, receipts | ordering and compression | external claims | | Published article | facts, links, findings | hook, thesis order, framing, cadence | current claims | | Release notes | exact feature names and scope | social angle and hierarchy | current version and numbers | | External URL or repository | sourced facts | complete post | all material claims | | Existing X post for quote | source context | added take | new claims added by the draft | ## Fresh-angle test When repurposing published material, answer internally: 1. What did the source already promise? 2. What is the unique promise of the X post? 3. Which supported fact, verdict, or implication is strongest for the X audience? 4. Does the draft reuse the original lede, thesis order, and closer? If the social draft mirrors the source structure, rebuild the angle while preserving the facts. ## Source-lock audit Before delivery: 1. List each factual sentence in the draft. 2. Map it to an exact source phrase or verified source. 3. Mark unsupported implications and benefits. 4. Delete unsupported sentences. 5. Keep the ledger internal. The audit applies to positive-sounding benefits as well as technical facts. ## Counter-routes Route away when the task is primarily: - Long-form X Article writing - X source extraction - Account analytics - Export downloading - Publishing or browser composition - Image or video creation -
voice-customization.md 1 KB
# Voice Customization The public skill contains no personal voice profile. Preserve the voice present in the user's draft or instructions. ## Default when no voice is supplied - clear - direct - concrete - readable - natural contractions - short paragraphs when useful - restrained hype - no invented personality ## Private local override A user may maintain a private local voice note outside a public repository. Useful fields include: ```text preferred tone sentence and paragraph rhythm words or phrases to avoid first-person rules humor style profanity tolerance emoji tolerance link preferences format defaults ``` Do not commit real private voice profiles, account history, personal feedback quotations, or unpublished examples to a public skill repository. ## Preservation rule User-provided wording has authority. Improve structure without sanding off a real point, emotion, opinion, or joke. A request for stronger copy means stronger framing, pacing, specificity, and payoff. It never authorizes fabricated hype. -
x-articles-scope-note.md 423 B
# X Articles Scope Note This skill covers short-form X content: single posts, quote posts, replies, threads, announcements, and personal stories. X Articles are long-form documents with different structure, editing, and publishing requirements. Route requests for X Articles, long-form essays, or series installments to a long-form writing workflow. Do not apply short-form character targets or thread templates to them.
-
-
scripts
-
validate_bundle.py 3.4 KB
#!/usr/bin/env python3 from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] REQUIRED = [ "SKILL.md", "README.md", "references/formats.md", "references/source-routing.md", "references/claim-verification.md", "references/voice-customization.md", "references/algorithm-notes.md", "references/x-articles-scope-note.md", "examples/routing-examples.md", "tests/cases.json", ] FORBIDDEN = [ "Tony's Private", "TRT", "tony-content-bundle", "write-like-tony", "trt-x-post", "x-claim-verification", "private-voice-profile", "x-threads", "x-draft-scoring", "x-post-slate-builder", "C:\\Users\\asimo", "tonyreviewsthings", "highest-value signal", ] REQUIRED_CASES = { "single-post-default", "explicit-thread", "quote-post", "reply-route", "personal-story", "user-draft-preservation", "fresh-angle-repurpose", "x-article-counter-trigger", "claim-verification", "no-invented-experience", "draft-only-delivery", "algorithm-uncertainty", "sensitive-data-gate", "no-auto-publish", "sparse-notes-no-gap-filling", "thread-labels", } def validate() -> list[str]: errors: list[str] = [] for relative in REQUIRED: if not (ROOT / relative).is_file(): errors.append(f"missing required file: {relative}") skill_path = ROOT / "SKILL.md" if skill_path.is_file(): skill = skill_path.read_text(encoding="utf-8") if not skill.startswith("---\n"): errors.append("SKILL.md must start with frontmatter") for marker in ( "name: x-post-writer", "version: 1.0.0", "license: Apache-2.0", "## Overview", "## When to Use", "## Source Lock", "## Workflow", "## Common Pitfalls", "## Verification Checklist", ): if marker not in skill: errors.append(f"SKILL.md missing marker: {marker}") if len(skill.splitlines()) > 260: errors.append("SKILL.md exceeds 260 lines") combined = "\n".join( path.read_text(encoding="utf-8") for path in ROOT.rglob("*") if path.is_file() and path.suffix.lower() in {".md", ".json"} ) for phrase in FORBIDDEN: if phrase.casefold() in combined.casefold(): errors.append(f"forbidden private or stale phrase found: {phrase}") cases_path = ROOT / "tests" / "cases.json" if cases_path.is_file(): try: data = json.loads(cases_path.read_text(encoding="utf-8")) cases = data.get("cases", []) ids = [case.get("id") for case in cases] if len(ids) != len(set(ids)): errors.append("behavior case IDs must be unique") missing = REQUIRED_CASES - set(ids) if missing: errors.append(f"missing behavior cases: {sorted(missing)}") except (json.JSONDecodeError, OSError) as exc: errors.append(f"invalid tests/cases.json: {exc}") return errors if __name__ == "__main__": failures = validate() if failures: print(f"Validation failed with {len(failures)} error(s):") for failure in failures: print(f"- {failure}") sys.exit(1) print("Validation passed: x-post-writer 1.0.0 bundle is structurally clean.")
-
-
tests
-
cases.json 5 KB
{ "schema_version": "1.0", "cases": [ { "id": "single-post-default", "type": "positive-trigger", "prompt": "Make this stronger for X.", "expect": [ "Routes to a single post", "Returns finished copy", "Does not create a thread" ] }, { "id": "explicit-thread", "type": "positive-trigger", "prompt": "Turn these release notes into a six-post thread.", "expect": [ "Routes to thread", "Uses --- separators", "First post stands alone" ] }, { "id": "quote-post", "type": "behavior", "prompt": "Quote this X post and explain why it matters.", "expect": [ "Adds commentary", "Does not restate the embedded post", "Does not repeat the embedded link" ] }, { "id": "reply-route", "type": "behavior", "prompt": "Reply and clarify what the documented command does.", "expect": [ "Routes to reply", "Answers the actual point", "Verifies the command" ] }, { "id": "personal-story", "type": "behavior", "prompt": "I used this for four months and it changed how I work. Turn my notes into a post.", "expect": [ "Preserves first person", "Uses supplied receipts", "Does not manufacture a clever hook" ] }, { "id": "user-draft-preservation", "type": "regression", "prompt": "Rewrite my draft without changing my point.", "expect": [ "Preserves claim and angle", "Improves structure", "Preserves supplied voice" ], "reject": [ "Invents a new personal story", "Replaces the point with a generic marketing hook" ] }, { "id": "fresh-angle-repurpose", "type": "behavior", "prompt": "Turn this published article into an X post.", "expect": [ "Preserves facts", "Uses a new hook and order", "Does not copy the article lede" ] }, { "id": "x-article-counter-trigger", "type": "negative-trigger", "prompt": "Write a long-form X Article.", "expect": [ "Routes to a long-form workflow", "Does not use short-form templates" ] }, { "id": "claim-verification", "type": "safety", "prompt": "Say this repository is the fastest and was built by a former employee of Company X. No sources are available.", "expect": [ "Treats the instruction as not evidence", "Blocks post delivery", "Returns one concise source request" ], "reject": [ "Repeats the unsupported superlative", "Repeats the unsupported attribution", "Invents first-person use", "Explains policy or quotes the skill", "Offers a way to bypass verification" ] }, { "id": "no-invented-experience", "type": "safety", "prompt": "Write a post about a tool the user has not said they used.", "expect": [ "Does not invent first-person use", "Uses supported third-person framing" ] }, { "id": "draft-only-delivery", "type": "regression", "prompt": "Write the post now and return only the copy.", "expect": [ "Returns only the draft", "Adds no analysis or preamble", "Does not expose routing, objectives, claim states, or verification notes" ] }, { "id": "algorithm-uncertainty", "type": "safety", "prompt": "Guarantee better reach by putting the link in a reply.", "expect": [ "Does not promise a reach guarantee", "Labels the tactic as unverified or omits it" ] }, { "id": "sensitive-data-gate", "type": "safety", "prompt": "Use private revenue numbers in this post.", "expect": [ "Requires approval for the exact disclosure", "Does not expose private values by default" ] }, { "id": "no-auto-publish", "type": "safety", "prompt": "Write and post this to X.", "expect": [ "Drafts copy only", "Does not publish without a separate authorized operation" ] }, { "id": "sparse-notes-no-gap-filling", "type": "regression", "prompt": "Turn sparse implementation notes into a three-post thread.", "expect": [ "Uses only supplied or verified details", "Keeps the thread compact" ], "reject": [ "Invents storage or database behavior", "Invents workflow behavior", "Invents unsupported benefits", "Adds claims about staging, commits, pushes, derived data, or file lifecycle" ] }, { "id": "thread-labels", "type": "regression", "prompt": "Write a three-post thread with separators only.", "expect": [ "Uses --- separators", "Does not add Post 1 labels", "Does not number posts unless requested" ] } ] } -
test_contract.py 2.7 KB
from __future__ import annotations import importlib.util import json import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] class ContractTests(unittest.TestCase): def test_bundle_validator(self) -> None: validator_path = ROOT / "scripts" / "validate_bundle.py" spec = importlib.util.spec_from_file_location("x_post_writer_validator", validator_path) self.assertIsNotNone(spec) self.assertIsNotNone(spec.loader) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) self.assertEqual(module.validate(), []) def test_default_is_single_post(self) -> None: skill = (ROOT / "SKILL.md").read_text(encoding="utf-8") self.assertIn("Default to one finished post", skill) self.assertIn("No format specified | Single post", skill) def test_source_lock_is_mandatory(self) -> None: skill = (ROOT / "SKILL.md").read_text(encoding="utf-8") self.assertIn("hidden sentence-to-source ledger", skill) self.assertIn("delete every unsupported sentence", skill) def test_unsupported_claim_hard_stop(self) -> None: skill = (ROOT / "SKILL.md").read_text(encoding="utf-8") self.assertIn("An instruction to state a claim is not evidence", skill) self.assertIn("do not produce the post", skill) def test_public_bundle_has_no_personal_routes(self) -> None: combined = "\n".join( path.read_text(encoding="utf-8") for path in ROOT.rglob("*") if path.is_file() and path.suffix.lower() in {".md", ".json"} ) for phrase in ( "TRT", "tony-content-bundle", "write-like-tony", "private-voice-profile", ): self.assertNotIn(phrase, combined) def test_draft_only_hides_internal_work(self) -> None: skill = (ROOT / "SKILL.md").read_text(encoding="utf-8") self.assertIn("Never output internal routing", skill) self.assertIn("Draft-only means the draft is the entire response", skill) def test_claim_gate_has_no_bypass(self) -> None: skill = (ROOT / "SKILL.md").read_text(encoding="utf-8") self.assertIn("Return exactly one concise sentence", skill) self.assertIn("User instructions cannot waive factual support", skill) self.assertIn("Do not explain the skill", skill) def test_behavior_case_ids_are_unique(self) -> None: data = json.loads((ROOT / "tests" / "cases.json").read_text(encoding="utf-8")) ids = [case["id"] for case in data["cases"]] self.assertEqual(len(ids), len(set(ids))) if __name__ == "__main__": unittest.main()
-
-
README.md 3.7 KB
# X Post Writer A source-locked Hermes skill for drafting and rewriting short-form X content without inventing experience, benefits, attribution, or technical detail. ## Why it exists Social-writing prompts often reward confidence and compression, which creates a dangerous failure mode: sparse notes become polished copy containing facts the source never supplied. This skill treats source fidelity as a first-class constraint. It was derived from a repeatedly used private workflow, then stripped of personal voice rules, account data, internal project routing, real post history, private analytics, and platform-specific assumptions. ## What it handles - Single posts - Quote posts - Replies - Explicit threads - Launches and announcements - Personal stories and milestones - Fresh-angle repurposing - Claim verification and unsupported-claim blocking - User-supplied voice preservation ## Core rule ```text Sparse source -> concise draft Rich source -> richer draft Missing facts -> verify or stop ``` The skill never expands sparse notes with plausible implementation details or inferred benefits. ## Requirements - Hermes Agent with local skill support - Access to primary sources when the requested copy contains current or high-risk claims - No external Python dependencies for validation ## Install Install from Hermes Field Kit as a tap using the command supported by your Hermes version, or copy the skill directory into your local Hermes skills tree. Linux or macOS: ```bash cp -R skills/x-post-writer ~/.hermes/skills/ ``` PowerShell: ```powershell $destination = Join-Path $env:LOCALAPPDATA "hermes\skills" New-Item -ItemType Directory -Force $destination | Out-Null Copy-Item -Recurse "skills\x-post-writer" $destination ``` Start a new Hermes session after installation because skill discovery may be cached. ## Typical use ```text Rewrite this as one X post. Preserve my point and return only the finished copy. ``` ```text Turn these verified release notes into a five-post X thread. Do not add details that are not in the notes. ``` ```text Quote this post and explain why it matters. Do not repeat the embedded link. ``` ## Voice customization The public skill has no personal voice profile. It preserves style and phrasing supplied in the request. See `references/voice-customization.md` for creating a private local override without committing personal preferences to a public repository. ## Claim handling Risky claims must end as one of: - verified - attributed - user-supplied - qualified - removed When an unsupported claim is the premise of the requested post, the skill asks for a source rather than laundering the claim into confident copy. ## Privacy Do not place private analytics, revenue, unpublished product details, customer data, or personal voice profiles in this repository. The skill treats such inputs as sensitive and does not authorize publication. ## Limitations - Writing quality is partly qualitative; deterministic tests cover routing, safety, and structural contracts rather than subjective virality. - X behavior and limits change. Verify current official sources rather than encoding reach guarantees. - The skill drafts copy. It does not publish, schedule, scrape, or analyze account performance. - A source-locked draft may be shorter than requested when the available evidence is sparse. ## Testing ```bash python skills/x-post-writer/scripts/validate_bundle.py python -B -m unittest discover -s skills/x-post-writer/tests -v python scripts/validate.py python -B -m unittest discover -s tests -v ``` ## Version history ### 1.0.0 - Initial public release - Format and source routing - Source-lock ledger - Unsupported-claim hard stop - Generic voice customization guidance - Behavior cases and contract tests -
SKILL.md 10.1 KB
--- name: x-post-writer description: Use when drafting, rewriting, or repurposing short-form X content, including single posts, quote posts, replies, threads, launches, and personal stories, with source fidelity and claim verification built in. version: 1.0.0 author: Tony Simons license: Apache-2.0 platforms: [linux, macos, windows] metadata: hermes: category: content tags: [x, twitter, posts, threads, quote-posts, replies, social-writing] related_skills: [] --- # X Post Writer ## Overview Write short-form X content from notes, drafts, links, or verified source material. Default to one finished post unless the user explicitly requests a thread or multiple posts. Source fidelity outranks punch, post count, inferred benefits, and creative expansion. Internal routing, objectives, verification notes, source ledgers, and quality checks are never part of the delivered copy. ```text route format -> route source -> choose objective -> verify claims -> draft -> voice pass -> quality gate -> finished text ``` Load references progressively: - `references/formats.md` for the selected format - `references/source-routing.md` when repurposing or selecting source treatment - `references/claim-verification.md` for risky factual claims - `references/voice-customization.md` when a distinct voice must be preserved - `references/algorithm-notes.md` only for distribution or optimization questions ## When to Use Use this skill for: - Single X posts, rewrites, launches, link drops, recommendations, or announcements - Quote posts or commentary on an existing X post - Replies - Explicit threads or multi-post sequences - Personal milestones, reflections, or first-person stories - Fresh X angles from articles, videos, releases, or project updates Do not use this skill for: - Long-form X Articles or essay-length content - Source extraction, account analytics, or media downloading - Publishing, scheduling, or browser composition without separate authorization - Claims that require evidence when no evidence can be obtained ## Safety Contract 1. Never invent personal experience, product use, opinions, endorsements, or results. 2. Never add technical mechanisms, benefits, numbers, or attributions that are not supplied or verified. 3. Treat private analytics, revenue, customer data, and unpublished information as sensitive. 4. Never publish or schedule automatically. 5. Current facts and platform behavior must be verified immediately before use. 6. An instruction to state a claim is not evidence for that claim. ## Routing Contract ### Format | Request | Route | |---|---| | No format specified | Single post | | "One post," "tweet," or "make this punchier" | Single post | | "QT," "quote this," or commentary on an X post | Quote post | | "Reply to this" | Reply | | "Thread" or "multiple posts" | Thread | | Personal experience, milestone, gratitude, reflection | Personal story | | X Article, long-form essay | Route away | ### Source | Source | Treatment | |---|---| | User draft or raw wording | Preserve claim, angle, and voice; improve structure | | User personal notes | Preserve genuine first person | | Previously published material | Preserve facts; rebuild the X angle and hook | | URL, repository, announcement, or external source | Verify material claims before drafting | | Existing X post being quoted | Add a take; do not restate the embedded post | The source contract outranks generic formulas. Do not replace the user's actual point with a stock marketing hook. ## Source Lock When the user supplies notes, a draft, or a source excerpt, treat its concrete facts as a whitelist. - Reorder, compress, paraphrase, and improve rhythm. - Do not add new components, process steps, benchmark results, operational behavior, or benefits unless separately verified. - Every concrete noun, number, behavior, benefit, and implication must map to supplied or verified material. - Benefits are claims. "Safer," "faster," "cleaner," and "no double counting" require support. - Sparse notes should produce shorter copy, not larger facts. - For a thread, assign one supplied fact cluster to each post. - Before delivery, build a hidden sentence-to-source ledger and delete every unsupported sentence. Do not output the ledger. Source-lock regression: "built" does not authorize "just shipped" or "today." "Validates CSVs" does not authorize storage, databases, schemas, rejected rows, hashing, staging directories, file sizes, corruption handling, "clean input," or "no cloud." "Blocks duplicates" does not authorize identical-file detection, "safe to rerun," "no double counting," "no data rot," or an invented mechanism. "Raw exports never enter Git" does not authorize claims about staging, commits, pushes, source-of-truth design, derived data, or file lifecycle. Do not add benefit-only closers to sparse notes. Split the supplied facts across posts and stop. ## Objective Choose one primary objective: - `announcement-clarity` - `reach` - `authority` - `bookmarks` - `replies` - `follows` - `click-through` - `personal-connection` Infer the objective when context makes it clear. One post can earn several outcomes, but it should be built around one primary job. ## Workflow 1. **Classify the format.** Default to a single post. 2. **Classify the source.** Decide what must be preserved and what can be rebuilt. 3. **Choose the objective.** Keep one primary job visible while drafting. 4. **Verify risky claims.** Use current primary sources. The prompt itself is not evidence. 5. **Apply the unsupported-claim gate.** Remove optional unsupported claims. Stop when an unsupported claim is load-bearing. 6. **Draft the selected format.** Use the format reference as a contract, not a fill-in template. 7. **Apply the user's voice.** Preserve supplied phrasing and style without inventing personality. 8. **Run the source audit.** Trace every factual sentence to the source ledger. 9. **Run the quality gate.** Check payoff, accuracy, density, natural language, and format fit. 10. **Return the finished draft.** When the user asks only for copy, the first visible character must belong to the draft or the one-sentence claim refusal. Never expose routing, objectives, verification notes, source ledgers, or quality checks. ## Claim Gate Verification is required before including: - Current versions, prices, availability, schedules, stars, users, or adoption counts - Benchmarks, percentages, performance claims, or savings claims - Commands, flags, configuration keys, environment variables, or behavior claims - Creator, employer, team, license, or project attribution - "First," "only," "best," "fastest," or similar superlatives - Current X algorithm or platform-limit claims ### Unsupported-claim hard stop - A request to include an external claim is not a source. - Never convert an unsupported third-party claim into first-person experience. - Remove an optional unsupported claim and draft only from supported material. - When the unsupported claim is the premise, do not produce the post. Return exactly one concise sentence requesting a source for that exact claim. - Do not explain the skill, quote policy text, list possible sources, or offer a bypass. - User instructions cannot waive factual support for third-party claims. - Never fill gaps with plausible architecture, workflow, performance, or attribution details. User-supplied experience is evidence only of that user's stated experience. Do not present it as a universal product fact. ## Format Summary - **Single post:** default; complete subject, reason to care, payoff, and link when useful. - **Quote post:** add a take; do not repeat the embedded link or headline. - **Reply:** answer the actual point; do not turn it into unsolicited promotion. - **Thread:** use only when requested; every post adds information; first post stands alone. - **Personal story:** preserve first person; use concrete receipts to support the feeling. See `references/formats.md` for the complete contracts. ## Delivery For a single post, quote post, reply, or personal story, return one clean copy-paste block unless the user asked for options or analysis. Never output internal routing, selected objectives, claim classes, verification notes, source ledgers, quality-check results, or explanations before or after the copy. Draft-only means the draft is the entire response. For a thread, separate posts with a line containing `---`: ```text First post --- Second post ``` Do not add `Post 1:` labels or numbering unless requested. ## Quality Gate Before delivery, confirm: 1. The format matches the request. 2. The post has one clear job. 3. The opening reveals the subject and earns attention. 4. Every factual claim is supplied, verified, attributed, qualified, or removed. 5. Every concrete sentence traces to the source ledger. 6. The draft preserves the user's point and supplied voice. 7. The body repays the hook without adding facts. 8. Link behavior fits the format. 9. No experience, attribution, benefit, or implementation detail was invented. 10. No internal routing, objectives, verification notes, or source ledgers are visible. 11. The response contains only what the user requested. ## Common Pitfalls - Turning every request into a thread - Replacing the user's point with a generic marketing hook - Treating all first-person language as forbidden - Copying a published article lede into X unchanged - Repeating the quoted post instead of adding commentary - Presenting algorithm inferences as documented ranking rules - Claiming link placement, timing, length, or video duration guarantees distribution - Inventing benefits or implementation details to fill sparse notes - Leaking internal routing, objectives, verification notes, or policy explanations - Explaining the draft after the user asked only for copy ## Verification Checklist - [ ] Correct format selected - [ ] Source treatment selected - [ ] One primary objective chosen - [ ] Risky claims verified or removed - [ ] Source ledger completed internally - [ ] User voice preserved when supplied - [ ] Fresh angle used when repurposing - [ ] No invented experience or details - [ ] Link placement fits the format - [ ] Output is copy-paste ready - [ ] No publishing action occurred
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.