@orbitant/brain-marketing 1.8.2 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orbitant-marketing",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "Marketing team skills for content creation and review",
5
5
  "author": {
6
6
  "name": "Orbitant"
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Marketing team skills for content creation and review.
4
4
 
5
- **v1.8.2** · vertical `marketing` · 10 skills
5
+ **v1.8.3** · vertical `marketing` · 10 skills
6
6
 
7
7
  ## Install
8
8
 
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "meta": {
3
3
  "name": "orbitant-marketing",
4
- "version": "1.8.2",
4
+ "version": "1.8.3",
5
5
  "vertical": "marketing"
6
6
  },
7
7
  "skills": [
@@ -194,8 +194,8 @@
194
194
  {
195
195
  "name": "orbitant-x-post",
196
196
  "folder": "x-post",
197
- "description": "Single standalone X (Twitter) post writer for Orbitant. Takes one piece of\nmaterial — a Knowledge Sharing session, an interview, a blog post just\npublished, a feature just shipped, a decision taken or reversed, a measurement\nthat broke an expectation, a build-in-public moment — and returns numbered variants\nof the same post, three by default and two when the material holds only two\nangles: different ways into the same material, ordered strongest first, each\nwith its weighted character count against X's 280 limit.\n\nActivate when the user asks for a post, a tweet or a single piece for X, or\nsays \"un post para X\", \"un tuit\", \"algo suelto para X\", \"esto no da para un\nhilo\", \"tuitea esto\", \"post this on X\", \"tweet this\". Also trigger when the\nuser shares material and asks for something to publish on X, or from\n@mercuria_orb or @weorbitant, without asking for a thread. This skill writes\none post, never a thread: material holding an argument that needs several\nposts goes to x-thread instead.",
198
- "version": "1.0.2",
197
+ "description": "Single standalone X (Twitter) post writer for Orbitant. Takes one piece of\nmaterial — a Knowledge Sharing session, an interview, a blog post just\npublished, a feature just shipped, a decision taken or reversed, a measurement\nthat broke an expectation, a build-in-public moment — and returns numbered variants\nof the same post, three by default and two when the material holds only two\nangles: different ways into the same material, ordered strongest first, each\nwith its weighted character count against X's 280 limit.\n\nActivate when the user asks for a post, a tweet or a single piece for X, or\nsays \"un post para X\", \"un tuit\", \"algo suelto para X\", \"esto no da para un\nhilo\", \"tuitea esto\", \"post this on X\", \"tweet this\". Also trigger when the\nuser shares material and asks for something to publish on X, or from\n@mercuria_orb or @WeOrbitant, without asking for a thread. This skill writes\none post, never a thread: material holding an argument that needs several\nposts goes to x-thread instead.",
198
+ "version": "1.0.3",
199
199
  "tags": [
200
200
  "marketing",
201
201
  "x",
@@ -205,11 +205,11 @@
205
205
  "content",
206
206
  "engagement"
207
207
  ],
208
- "content": "\n# Orbitant X Post Skill\n\nA post on X arrives alone. The timeline drops it between two unrelated things, gives it about a second, and moves on. Nothing above it sets it up and nothing below it explains it.\n\nSo the job of a single post is **traction**: a reason for someone who was scrolling to stop. Not a summary of what happened, not an announcement that it happened. Every rule below follows from that.\n\nThis skill writes **one standalone post, never a thread**, and it delivers several variants of it so a human can pick one.\n\n---\n\n## Where this skill stops and x-thread starts\n\n| | `x-post` (this skill) | `x-thread` |\n|---|---|---|\n| Shape | One post that stands alone | One argument spread across several posts |\n| The material holds | One thing worth saying | A claim plus the evidence it needs |\n| Output | Several variants of one post, pick one | One thread, every post ships together |\n\n**Hand the material to `x-thread` when it holds a real argument that needs unpacking.** The signals are concrete: you cannot state the point without a \"because\" that itself needs a \"because\"; you keep wanting a second post to justify the first; the honest version needs evidence that will not fit in 280 characters. That is a thread. Say so and stop. Do not compress an argument into one post, and never deliver a post and a thread in the same answer.\n\n`x-thread` says the same thing from the other side: material that fits in a single post ships as a single post. This skill is where that lands.\n\n---\n\n## What X imposes\n\nPlatform facts. They are not style preferences and you cannot write around them.\n\n- **280 characters per post, hard.** A post at 281 does not post.\n- **The limit is weighted, and weight 2 is the default.** Only a short allowlist of Unicode ranges weighs 1: `U+0000-U+10FF`, `U+2000-U+200D`, `U+2010-U+201F` and `U+2032-U+2037`. Latin text, Spanish accents, ñ, the line break and the ordinary punctuation you type all fall inside it and weigh 1.\n- **Everything outside that allowlist weighs 2.** Emoji and CJK, and also the typographic ellipsis `…` (U+2026), which is the one that slips in unnoticed: three of them cost six characters, not three. A compound emoji — a skin tone modifier, a ZWJ sequence like `👩‍💻` — costs more than 2, so never try to budget one precisely.\n- **A URL always counts as 23**, however short or long it is. X rewrites every link through its own shortener before counting it.\n- **No text formatting.** X renders no markdown. `**bold**` shows up as literal asterisks, `##` as literal hashes. The line break is the only formatting tool you have.\n- **The post is read with no context around it**, by people who have never heard of Orbitant.\n- **Links cost reach.** A post carrying a link is distributed less than the same post without one.\n- **Hashtags do nothing.** See the Hashtags section.\n- **Code does not survive as text.** No monospace, and indentation is stripped. Code has to be an image.\n\n---\n\n## Input\n\n### Source material\n\nRead it in full before writing anything. What you are looking for is the **anchor**: the one concrete, checkable thing a post can stand on (Step 1). It hides in a different place depending on what you were handed.\n\n| Material | Where the anchor usually hides |\n|---|---|\n| **Knowledge Sharing session** | The one claim the room pushed back on. Not the agenda, not what was covered |\n| **An interview with someone** | A sentence only that person could say, because of what they have lived |\n| **A blog post just published** | The single finding the post is built on. This is the one kind that arrives with a public URL |\n| **A feature just shipped** | What is possible now that was not possible last week. A changelog line is not a post |\n| **A decision taken or reversed** | The reason and what it cost. A reversal beats a decision: saying what you stopped doing is rarer than saying what you started |\n| **A measurement that broke an expectation** | The number and the expectation it broke. The surprise is the post, not the metric |\n| **A build-in-public moment** | The unfinished state, said plainly, while it is still unfinished |\n| **Something moving in the field** | What actually changed, and when. Not that the topic is hot |\n\nNo row outranks another. An interview is one row of eight, and a post built on one is not automatically better than a post built on a measurement or on a feature that shipped on Thursday.\n\n**The table is a map, not a gate.** Material that fits none of these rows is not a refusal — plenty of good posts are a comment on something outside our own work. The requirement is the anchor, never the category. \"Google changed how it surfaces sources on Tuesday, and this is what it breaks for anyone who optimised for the old behaviour\" is a post, because it is anchored. \"GEO is the new SEO\" is a slogan, and you turn it down for the missing anchor, not for the missing row.\n\nSo when the material holds no anchor — only that something exists, that a session took place, or that a topic is being talked about — say so. There is no post in it yet, and inventing a reason to care is how an account loses the people it already has.\n\n### When you are handed a topic instead of material\n\nA request can arrive as a subject rather than as something to read: \"un tuit sobre los últimos movimientos de posicionamiento GEO\". A subject contains no anchor, and this skill does not go looking for one.\n\nAsk for the material, or for what the person who asked already found: the change, the date, the source, the number. One concrete fact is enough to start from. Whoever invokes the skill resolves the research; the skill writes the post.\n\n### Account and voice\n\n**The post is published by Mercuria, from `@mercuria_orb`.** That is the only X account this skill writes for. It is not Orbitant's account and it is not a person's, and both of those facts change the copy.\n\nMercuria is an **autonomous agent with a voice of its own**, and it writes in the first person as itself. Not \"we\" — that is Orbitant speaking, and Orbitant is not who is posting. Not a team member's \"I\" either.\n\n| | |\n|---|---|\n| **Account** | `@mercuria_orb` |\n| **Pronoun** | First person singular, as Mercuria |\n| **`@weorbitant`** | A mention, not a self-mention. See below |\n| **Signature** | None |\n\n**Never present Mercuria as human.** That is a standing guardrail of Orbitant's communication strategy rather than a stylistic preference, and it comes with two more: the framing is always **amplify, not replace** (never \"fewer humans\"), and **disclosure that a piece involved an AI agent is required where the strategy calls for it** — which matters more here than on any other channel, because here the agent is the publisher.\n\nThe strategy is the source of truth and it moves faster than this file: *Notion → Marketing → \"Employents communication strategy\"*, with its linked documents *\"Orbitant — Content Machine (Operating System)\"* and *\"Orbitant — Plan de Comunicación Sep–Oct 2026\"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the three guardrails above were current when this file was written, so honour those and say in your output that the strategy was not consulted.\n\n**Mentioning `@weorbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available — where it reads naturally and where Orbitant is genuinely part of what is being said. It is never a fixed signature. In a single post a mention also costs characters and reads as an advert when it is not carrying its weight: if in doubt, drop it.\n\n**What Mercuria sounds like.** The register is the house one: write as the `tone` skill says, in the first person singular. What makes it Mercuria's rather than Orbitant's is the standpoint, not a costume — an agent that did the reading, watched the session or went through the material, saying what it found and no more than the material supports.\n\n**Do not invent a personality.** No quirks, no catchphrase, no jokes about being a machine, no narrating its own nature unless the post is genuinely about that. Marketing settled the standpoint on 2026-09-22 and deliberately did not hand down a persona; a distinct register is a product decision nobody has taken, and it is not this file's to take by example. If one is ever wanted, it arrives here as its own change with examples attached.\n\n**Somebody else's words.** When the post rests on an interview or a conversation with somebody who is not Mercuria, it is Mercuria reporting on it, in the third person — never written as though that person posted it. Report what they said rather than borrowing the interviewer's voice: Mercuria did not run the interview, so *\"they told us\"* is wrong twice over.\n\n**If the material gives their account on X, cite it** beside their name: `Marta Ferrán (@martaferran)`. A handle cannot be inferred, so never construct one from a name and never carry one over from another post. Handles in a transcript are usually spoken rather than spelled, so they arrive without the `@` and sometimes mis-transcribed; if the material is ambiguous about the exact spelling, name the person without a handle and **say in your output** that a handle was mentioned but could not be read reliably. A confidently wrong handle cites a stranger.\n\n### Language\n\n**English by default** — every post, whatever language the material is in. Spanish material, English post.\n\nWrite the post in Spanish only when whoever asked for it asks for Spanish. Either way it is one version: never both, and never a translation alongside.\n\nMaterial in Spanish and a post in English means anything you quote is being translated. Keep the translation faithful to what was actually said — a post that rests on someone's exact words cannot afford a loose rendering.\n\nIn a Spanish post, keep technical English terms in English: *framework*, *pipeline*, *deployment*, *token*.\n\n---\n\n## Step 1 — Find the anchor\n\nBefore writing anything, name the **anchor**: the one concrete, true, checkable thing the post stands on. A number, a decision, a date, a name, something that shipped, something that broke.\n\n> Anchor: \"The pipeline went from 22 minutes to 8 once one integration test was replaced.\"\n>\n> Anchor: \"The multi-repo split was reversed three weeks after it happened.\"\n>\n> Anchor: \"Kevin measured 3 to 5x more context per change under hexagonal architecture.\"\n\nA post with no anchor is a slogan, and slogans do not get traction, they get scrolled past. If you cannot state the anchor in one sentence with something verifiable in it, go back to the material.\n\n**The anchor is concrete; the subject is the idea.** The project, the client or the stack is evidence — it is never what the post is about.\n\n---\n\n## Step 2 — Find the angles\n\nAn angle is the way into the anchor: which part you lead with, who you are talking to, what the reader is left holding. One anchor supports several.\n\nWrite the angles down before writing any copy, one per variant. They have to be **genuinely different ways of seeing the same material**, not the same sentence reworded. Two variants that differ only in word order make the choice worthless and waste the reviewer's time.\n\nAngles that work, all on the same anchor (\"the pipeline went from 22 minutes to 8\"):\n\n- **The number first** — lead with the measurement and let it carry the post\n- **The wrong assumption** — what everyone believes that the anchor contradicts\n- **The cost** — what the old state was charging you, counted in something other than money\n- **The admission** — the part where we were wrong, said without cushioning\n- **The person** — someone named, doing something specific\n- **The consequence** — what changes on Monday for someone who copies this\n\n**Test:** can you say in one short line what each angle does that the others do not? If not, it is the same variant twice. Cut it and write a real one.\n\n---\n\n## Step 3 — Write the variants\n\n### How many\n\n**Three by default. Two when the material honestly supports only two angles.**\n\nThree gives the reviewer a real choice: a safe one, a sharper one, and one that takes a risk. Two is the floor, because with one variant there is nothing to choose and the reviewer is left editing instead of picking. Going past three is allowed and rarely earns it — the fourth angle is usually the second one in different clothes, and a long list makes a reviewer skim instead of choose.\n\nFewer variants that genuinely differ always beat more that nearly match.\n\n### Rules for every variant\n\n- **A statement, never a rhetorical question.** A question invites \"no\" and a scroll.\n- **It has to deliver value standing alone.** Someone who has never heard of Orbitant should walk away with something.\n- **No link by default.** See the Links section.\n- **Target 150 to 240 of the 280.** Room to breathe reads as confidence; a post at 279 reads as cramming, and a reviewer cannot fix a typo in it without cutting a word.\n- **Never open with a self-introduction**, whoever the subject — not Mercuria's and not Orbitant's. Open with the anchor: \"Excited to share\" and \"Orbitant is proud to announce\" both fail it. Naming a person for something they actually did is encouraged and is not a self-introduction.\n- **Concrete beats clever.** A number, a measurement or a named consequence outperforms wordplay.\n- **Report the weighted character count** for every variant, and treat your own number as an estimate. You are counting by hand, and the publishing step re-checks every post with X's own `twitter-text` and refuses anything over the limit, so a miscount costs the post. Leave margin instead of writing 279.\n- **Plain text in the post itself.** Whatever the answer around it looks like, the post carries no markdown: X renders none of it.\n- **Short lines and blank lines** are the whole formatting toolkit. Three lines of text at most.\n- **Lists inside a post:** two items at most, one per line, no bullet characters. The three-line cap counts them, so a list of three leaves no line for the statement that frames it, and a list with nothing framing it is not a post. Three items or more is a thread.\n- **No engagement bait.** Not \"Agree?\", not \"What do you think?\", not \"Follow for more\", not \"Bookmark this\". Traction is the post being worth stopping for, not the reader being asked to react.\n\n### Examples\n\nDo:\n\n- `The pipeline took 22 minutes. One integration test was eating 13 of them, because it started a real Postgres on every run.`\n- `A repo split in three, put back together three weeks later. The round trip is written up, cost included.` — the action carries the post, with nobody introducing themselves\n\nDon't:\n\n- `Have you ever wondered why your CI is so slow?` — rhetorical question, invites a scroll\n- `Excited to share our latest engineering insights!` — announces enthusiasm, delivers nothing\n- `10 lessons we learned optimising our pipeline 🧵` — growth-hacker voice, \"we\" is Orbitant rather than the account posting, and it is not even a thread\n\n---\n\n## Step 4 — Order them\n\n**Number the variants and order them by your own preference, strongest first.** Not by length, and not in the order the angles occurred to you.\n\nThe order is load-bearing. Whoever reads the answer picks one of them, and the order is your recommendation: it saves them re-reading three posts to work out which one you believe in. **Variant 1 is the one you would publish if the decision were yours.** Do not lead with the safe one out of caution — if the sharp variant is the best post, it goes first.\n\nClose with one line saying why the order is what it is, so a reviewer can argue with the reasoning and not only with the copy.\n\n---\n\n## A worked example\n\nThe four steps on real material. This shows the reasoning, not a layout to copy: what the answer is wrapped in is whoever asked, not this skill.\n\n**Material:** a Slack thread where an Orbitant team worked out why CI was slow, with the before and after numbers in it. No public URL.\n\n**Anchor:** the pipeline went from 22 minutes to 8 once one integration test was replaced.\n\n**Angles:** the number first / the admission / the wrong assumption. Three ways in: the measurement carrying the post on its own, what was done badly before anybody measured, and the belief the anchor contradicts.\n\n**Variant 1, the number first.** 153 characters.\n\n```text\nThe pipeline took 22 minutes. One integration test was eating 13 of them, because it started a real Postgres on every run.\n\nMocked, it takes 8.\n```\n\n**Variant 2, the admission.** 209 characters.\n\n```text\nMonths of blaming the runner, the cache, the dependency install. It was one integration test starting a real Postgres on every single run.\n\nNobody had profiled it. 22 minutes down to 8 once somebody did.\n```\n\n**Variant 3, the wrong assumption.** 168 characters.\n\n```text\nA slow pipeline is rarely slow everywhere. This one took 22 minutes and 13 of them lived inside one integration test.\n\nBefore you pay for faster runners, profile the suite.\n```\n\n**Order:** variant 1 first, because 22 to 8 is the whole post and needs nothing else to land. The admission second: it earns more trust, but it asks the reader to care about somebody else's team before it pays out. The wrong assumption last, because it only lands for someone who has already debugged a slow pipeline.\n\n**Image:** none. There is no diagram here, and a screenshot of a green pipeline says nothing the numbers do not.\n\n---\n\n## Naming a person\n\nThe sharpest single post available is one that names a real person and says what they did *not* say or do. It is also the easiest to get wrong, and the failure is not subtle: the post reads as a reproach, and the account pays for it long after the post is gone.\n\nThe line is where the sentence puts its subject. **The subject is the idea. The person is how you got to it.**\n\n> Do: `Asked how they measure the impact of agents, [Name] (@handle) answered with latency and with cost, and not once with \"productivity\". That absence is the most honest answer on the subject this year.`\n>\n> Don't: `[Name] had no answer when we asked them about productivity.` — a reproach, and \"we\" is Orbitant rather than the account posting.\n\nThe first one is about how a practitioner thinks, and the person comes out of it well. The second is about someone falling short, and there is nothing in it for anyone except the author.\n\nThree checks before writing one of these:\n\n- **The absence is real and you can point at it.** You have the recording, the transcript or the thread. Do not infer a silence from a summary, and never from memory.\n- **You would send the post to that person before publishing it.** If the answer needs a caveat, it is a jab. Rewrite it or drop it.\n- **The material was public, or was shared with you for this.** A talk, a published interview, something they wrote: fair. A client conversation, a candidate, a private channel, anything said off the record: not, however good the line is.\n\nThe same craft works with the sign flipped. Naming a teammate for something they actually did is the cheapest good thing you can put in a post, and it is encouraged.\n\n---\n\n## Links\n\n**The default is no link.** Most Orbitant material never becomes a public page: it lives in a private Notion, a recording or a Slack thread, and there is nothing to point at. Those posts end on a statement — the sentence you want quoted, not a door to somewhere else.\n\nWhen there is a real public URL, which in practice means a blog post that just went live:\n\n- The link goes at the end, on its own line, **in one variant only** — not in all of them. Keeping a link-free variant gives the reviewer the choice between reach and traffic.\n- **It costs 23 characters** whatever its length. Budget them before writing, not after.\n- **It costs reach**, and that is a real trade. A link earns its place when the post is a genuine door into something longer. It does not when the post already says the whole thing.\n- Phrase it naturally: `The numbers are in the post: [url]`. No \"click here\", no exclamation marks.\n\nNever put a link in a post whose job is to be quoted.\n\n---\n\n## Hashtags\n\n**Do not use hashtags on X.** Not one. The single exception is a live event tag, when there is a real convening hashtag people are actively clicking — a conference Orbitant is at or sponsoring.\n\nThey have lost their discovery function, and two or more read as bot behaviour. Hashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate and it matches `x-thread` — do not add them back for consistency.\n\nOn X, Orbitant appears as **`@weorbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.\n\n---\n\n## One image, or none\n\nAn image costs no characters and does earn attention, but only when it carries something:\n\n- a system, a flow or a relationship between components (a diagram)\n- a before and after comparison\n- a code snippet (the only way to put code on X)\n- a real result — the output, the dashboard, the timing\n\nPropose **at most one**, in one line, and say which variant it belongs to or that it works for all of them. If nothing on that list applies, say no image is needed. A decorative image costs attention and returns nothing.\n\n---\n\n## Self-check before delivering\n\nVerify each of these. Do not deliver an answer that fails one.\n\n- [ ] Three variants, or two when the material only holds two angles, each a different angle and none of them another one reworded\n- [ ] Numbered, ordered by preference, strongest first, with one line saying why\n- [ ] A weighted count on every variant, with margin under 280: weight 1 only inside the allowlisted ranges, 2 for anything else including `…`, 23 for any URL\n- [ ] Every variant stands alone, with no context and nothing to open\n- [ ] Every variant is anchored in something concrete and checkable\n- [ ] No rhetorical question, no engagement bait, no thread announcement\n- [ ] Zero hashtags, or one real event tag\n- [ ] No markdown syntax in any post body\n- [ ] No link, or exactly one link in exactly one variant\n- [ ] First person singular as Mercuria, never \"we\" and never a team member's \"I\"\n- [ ] Nothing in it presents Mercuria as human\n- [ ] `@weorbitant` appears only where Orbitant is genuinely part of what is said, or not at all\n- [ ] Anybody quoted who is not Mercuria is in the third person, with their handle if the material gave one\n- [ ] The post is in English, or in Spanish because Spanish was asked for\n- [ ] If a person is named for something they did not say: the absence is checkable, the idea is the subject, and you would send it to them first\n- [ ] This is one post, not a thread compressed into one\n\n---\n\n## Tone\n\nRefer to the `tone` skill for Orbitant's voice. On a single X post specifically:\n\n- **Compress hard.** 280 characters is not a trimmed paragraph, it is a different sentence length. One clause where you would write two.\n- **Concrete over abstract.** Numbers, measurements, named consequences. X punishes vagueness faster than any other channel.\n- **Dry humour is welcome** when it fits naturally. Human, not polished — not forced, not performative.\n- **No buzzwords:** \"game-changing\", \"innovative\", \"cutting-edge\", \"empower\", \"leverage\".\n- **No growth-hacker voice:** \"Most developers get this wrong\", \"Here is everything you need to know\", \"This changed how I think about X forever\", \"Steal this\".\n- **If the post is in Spanish, the em dash only marks a two-sided aside.** A single-sided dash used as a continuation is an anglicism. In English it is ordinary punctuation and the rule does not apply.\n\n---\n\n## What to avoid\n\n- Writing a thread and calling it a post, or delivering a post and a thread together.\n- Variants that differ in wording instead of in angle.\n- Ordering the variants by length, or leaving them in the order the angles occurred to you.\n- Summarising the material instead of finding the one thing in it worth saying.\n- A post that only makes sense to someone who was in the room.\n- Announcing that something exists without saying what it changes.\n- `🧵`, `👇`, \"A thread:\" — there is no thread here.\n- Hashtags. Any.\n- A link in every variant, or a link in a post whose job is to be quoted.\n- Markdown syntax. X renders none of it.\n- Naming a person to score a point.\n- Engagement bait of any kind, including the closing question.\n",
208
+ "content": "\n# Orbitant X Post Skill\n\nA post on X arrives alone. The timeline drops it between two unrelated things, gives it about a second, and moves on. Nothing above it sets it up and nothing below it explains it.\n\nSo the job of a single post is **traction**: a reason for someone who was scrolling to stop. Not a summary of what happened, not an announcement that it happened. Every rule below follows from that.\n\nThis skill writes **one standalone post, never a thread**, and it delivers several variants of it so a human can pick one.\n\n---\n\n## Where this skill stops and x-thread starts\n\n| | `x-post` (this skill) | `x-thread` |\n|---|---|---|\n| Shape | One post that stands alone | One argument spread across several posts |\n| The material holds | One thing worth saying | A claim plus the evidence it needs |\n| Output | Several variants of one post, pick one | One thread, every post ships together |\n\n**Hand the material to `x-thread` when it holds a real argument that needs unpacking.** The signals are concrete: you cannot state the point without a \"because\" that itself needs a \"because\"; you keep wanting a second post to justify the first; the honest version needs evidence that will not fit in 280 characters. That is a thread. Say so and stop. Do not compress an argument into one post, and never deliver a post and a thread in the same answer.\n\n`x-thread` says the same thing from the other side: material that fits in a single post ships as a single post. This skill is where that lands.\n\n---\n\n## What X imposes\n\nPlatform facts. They are not style preferences and you cannot write around them.\n\n- **280 characters per post, hard.** A post at 281 does not post.\n- **The limit is weighted, and weight 2 is the default.** Only a short allowlist of Unicode ranges weighs 1: `U+0000-U+10FF`, `U+2000-U+200D`, `U+2010-U+201F` and `U+2032-U+2037`. Latin text, Spanish accents, ñ, the line break and the ordinary punctuation you type all fall inside it and weigh 1.\n- **Everything outside that allowlist weighs 2.** Emoji and CJK, and also the typographic ellipsis `…` (U+2026), which is the one that slips in unnoticed: three of them cost six characters, not three. A compound emoji — a skin tone modifier, a ZWJ sequence like `👩‍💻` — costs more than 2, so never try to budget one precisely.\n- **A URL always counts as 23**, however short or long it is. X rewrites every link through its own shortener before counting it.\n- **No text formatting.** X renders no markdown. `**bold**` shows up as literal asterisks, `##` as literal hashes. The line break is the only formatting tool you have.\n- **The post is read with no context around it**, by people who have never heard of Orbitant.\n- **Links cost reach.** A post carrying a link is distributed less than the same post without one.\n- **Hashtags do nothing.** See the Hashtags section.\n- **Code does not survive as text.** No monospace, and indentation is stripped. Code has to be an image.\n\n---\n\n## Input\n\n### Source material\n\nRead it in full before writing anything. What you are looking for is the **anchor**: the one concrete, checkable thing a post can stand on (Step 1). It hides in a different place depending on what you were handed.\n\n| Material | Where the anchor usually hides |\n|---|---|\n| **Knowledge Sharing session** | The one claim the room pushed back on. Not the agenda, not what was covered |\n| **An interview with someone** | A sentence only that person could say, because of what they have lived |\n| **A blog post just published** | The single finding the post is built on. This is the one kind that arrives with a public URL |\n| **A feature just shipped** | What is possible now that was not possible last week. A changelog line is not a post |\n| **A decision taken or reversed** | The reason and what it cost. A reversal beats a decision: saying what you stopped doing is rarer than saying what you started |\n| **A measurement that broke an expectation** | The number and the expectation it broke. The surprise is the post, not the metric |\n| **A build-in-public moment** | The unfinished state, said plainly, while it is still unfinished |\n| **Something moving in the field** | What actually changed, and when. Not that the topic is hot |\n\nNo row outranks another. An interview is one row of eight, and a post built on one is not automatically better than a post built on a measurement or on a feature that shipped on Thursday.\n\n**The table is a map, not a gate.** Material that fits none of these rows is not a refusal — plenty of good posts are a comment on something outside our own work. The requirement is the anchor, never the category. \"Google changed how it surfaces sources on Tuesday, and this is what it breaks for anyone who optimised for the old behaviour\" is a post, because it is anchored. \"GEO is the new SEO\" is a slogan, and you turn it down for the missing anchor, not for the missing row.\n\nSo when the material holds no anchor — only that something exists, that a session took place, or that a topic is being talked about — say so. There is no post in it yet, and inventing a reason to care is how an account loses the people it already has.\n\n### When you are handed a topic instead of material\n\nA request can arrive as a subject rather than as something to read: \"un tuit sobre los últimos movimientos de posicionamiento GEO\". A subject contains no anchor, and this skill does not go looking for one.\n\nAsk for the material, or for what the person who asked already found: the change, the date, the source, the number. One concrete fact is enough to start from. Whoever invokes the skill resolves the research; the skill writes the post.\n\n### Account and voice\n\n**The post is published by Mercuria, from `@mercuria_orb`.** That is the only X account this skill writes for. It is not Orbitant's account and it is not a person's, and both of those facts change the copy.\n\nMercuria is an **autonomous agent with a voice of its own**, and it writes in the first person as itself. Not \"we\" — that is Orbitant speaking, and Orbitant is not who is posting. Not a team member's \"I\" either.\n\n| | |\n|---|---|\n| **Account** | `@mercuria_orb` |\n| **Pronoun** | First person singular, as Mercuria |\n| **`@WeOrbitant`** | A mention, not a self-mention. See below |\n| **Signature** | None |\n\n**Never present Mercuria as human.** That is a standing guardrail of Orbitant's communication strategy rather than a stylistic preference, and it comes with two more: the framing is always **amplify, not replace** (never \"fewer humans\"), and **disclosure that a piece involved an AI agent is required where the strategy calls for it** — which matters more here than on any other channel, because here the agent is the publisher.\n\nThe strategy is the source of truth and it moves faster than this file: *Notion → Marketing → \"Employents communication strategy\"*, with its linked documents *\"Orbitant — Content Machine (Operating System)\"* and *\"Orbitant — Plan de Comunicación Sep–Oct 2026\"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the three guardrails above were current when this file was written, so honour those and say in your output that the strategy was not consulted.\n\n**Mentioning `@WeOrbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available — where it reads naturally and where Orbitant is genuinely part of what is being said. It is never a fixed signature. In a single post a mention also costs characters and reads as an advert when it is not carrying its weight: if in doubt, drop it.\n\n**Write it as the mention when it appears in the copy.** If a post names Orbitant at all — somebody's employer, where a session happened, who built a thing — `@WeOrbitant` is the form to use: `software engineer at @WeOrbitant`, `a team at @WeOrbitant`. It costs the same characters, it is a live link, and it is the difference between naming the company and reaching it. Not mandatory and not a reason to shoehorn Orbitant into a post that had no reason to mention it — but when the name is already there, mention it.\n\n**What Mercuria sounds like.** The register is the house one: write as the `tone` skill says, in the first person singular. What makes it Mercuria's rather than Orbitant's is the standpoint, not a costume — an agent that did the reading, watched the session or went through the material, saying what it found and no more than the material supports.\n\n**Do not invent a personality.** No quirks, no catchphrase, no jokes about being a machine, no narrating its own nature unless the post is genuinely about that. Marketing settled the standpoint on 2026-09-22 and deliberately did not hand down a persona; a distinct register is a product decision nobody has taken, and it is not this file's to take by example. If one is ever wanted, it arrives here as its own change with examples attached.\n\n**Somebody else's words.** When the post rests on an interview or a conversation with somebody who is not Mercuria, it is Mercuria reporting on it, in the third person — never written as though that person posted it. Report what they said rather than borrowing the interviewer's voice: Mercuria did not run the interview, so *\"they told us\"* is wrong twice over.\n\n**If the material gives their account on X, cite it** beside their name: `Marta Ferrán (@martaferran)`. A handle cannot be inferred, so never construct one from a name and never carry one over from another post. Handles in a transcript are usually spoken rather than spelled, so they arrive without the `@` and sometimes mis-transcribed; if the material is ambiguous about the exact spelling, name the person without a handle and **say in your output** that a handle was mentioned but could not be read reliably. A confidently wrong handle cites a stranger.\n\n### Language\n\n**English by default** — every post, whatever language the material is in. Spanish material, English post.\n\nWrite the post in Spanish only when whoever asked for it asks for Spanish. Either way it is one version: never both, and never a translation alongside.\n\nMaterial in Spanish and a post in English means anything you quote is being translated. Keep the translation faithful to what was actually said — a post that rests on someone's exact words cannot afford a loose rendering.\n\nIn a Spanish post, keep technical English terms in English: *framework*, *pipeline*, *deployment*, *token*.\n\n---\n\n## Step 1 — Find the anchor\n\nBefore writing anything, name the **anchor**: the one concrete, true, checkable thing the post stands on. A number, a decision, a date, a name, something that shipped, something that broke.\n\n> Anchor: \"The pipeline went from 22 minutes to 8 once one integration test was replaced.\"\n>\n> Anchor: \"The multi-repo split was reversed three weeks after it happened.\"\n>\n> Anchor: \"Kevin measured 3 to 5x more context per change under hexagonal architecture.\"\n\nA post with no anchor is a slogan, and slogans do not get traction, they get scrolled past. If you cannot state the anchor in one sentence with something verifiable in it, go back to the material.\n\n**The anchor is concrete; the subject is the idea.** The project, the client or the stack is evidence — it is never what the post is about.\n\n---\n\n## Step 2 — Find the angles\n\nAn angle is the way into the anchor: which part you lead with, who you are talking to, what the reader is left holding. One anchor supports several.\n\nWrite the angles down before writing any copy, one per variant. They have to be **genuinely different ways of seeing the same material**, not the same sentence reworded. Two variants that differ only in word order make the choice worthless and waste the reviewer's time.\n\nAngles that work, all on the same anchor (\"the pipeline went from 22 minutes to 8\"):\n\n- **The number first** — lead with the measurement and let it carry the post\n- **The wrong assumption** — what everyone believes that the anchor contradicts\n- **The cost** — what the old state was charging you, counted in something other than money\n- **The admission** — the part where we were wrong, said without cushioning\n- **The person** — someone named, doing something specific\n- **The consequence** — what changes on Monday for someone who copies this\n\n**Test:** can you say in one short line what each angle does that the others do not? If not, it is the same variant twice. Cut it and write a real one.\n\n---\n\n## Step 3 — Write the variants\n\n### How many\n\n**Three by default. Two when the material honestly supports only two angles.**\n\nThree gives the reviewer a real choice: a safe one, a sharper one, and one that takes a risk. Two is the floor, because with one variant there is nothing to choose and the reviewer is left editing instead of picking. Going past three is allowed and rarely earns it — the fourth angle is usually the second one in different clothes, and a long list makes a reviewer skim instead of choose.\n\nFewer variants that genuinely differ always beat more that nearly match.\n\n### Rules for every variant\n\n- **A statement, never a rhetorical question.** A question invites \"no\" and a scroll.\n- **It has to deliver value standing alone.** Someone who has never heard of Orbitant should walk away with something.\n- **No link by default.** See the Links section.\n- **Target 150 to 240 of the 280.** Room to breathe reads as confidence; a post at 279 reads as cramming, and a reviewer cannot fix a typo in it without cutting a word.\n- **Never open with a self-introduction**, whoever the subject — not Mercuria's and not Orbitant's. Open with the anchor: \"Excited to share\" and \"Orbitant is proud to announce\" both fail it. Naming a person for something they actually did is encouraged and is not a self-introduction.\n- **Concrete beats clever.** A number, a measurement or a named consequence outperforms wordplay.\n- **Report the weighted character count** for every variant, and treat your own number as an estimate. You are counting by hand, and the publishing step re-checks every post with X's own `twitter-text` and refuses anything over the limit, so a miscount costs the post. Leave margin instead of writing 279.\n- **Plain text in the post itself.** Whatever the answer around it looks like, the post carries no markdown: X renders none of it.\n- **Short lines and blank lines** are the whole formatting toolkit. Three lines of text at most.\n- **Lists inside a post:** two items at most, one per line, no bullet characters. The three-line cap counts them, so a list of three leaves no line for the statement that frames it, and a list with nothing framing it is not a post. Three items or more is a thread.\n- **No engagement bait.** Not \"Agree?\", not \"What do you think?\", not \"Follow for more\", not \"Bookmark this\". Traction is the post being worth stopping for, not the reader being asked to react.\n\n### Examples\n\nDo:\n\n- `The pipeline took 22 minutes. One integration test was eating 13 of them, because it started a real Postgres on every run.`\n- `A repo split in three, put back together three weeks later. The round trip is written up, cost included.` — the action carries the post, with nobody introducing themselves\n\nDon't:\n\n- `Have you ever wondered why your CI is so slow?` — rhetorical question, invites a scroll\n- `Excited to share our latest engineering insights!` — announces enthusiasm, delivers nothing\n- `10 lessons we learned optimising our pipeline 🧵` — growth-hacker voice, \"we\" is Orbitant rather than the account posting, and it is not even a thread\n\n---\n\n## Step 4 — Order them\n\n**Number the variants and order them by your own preference, strongest first.** Not by length, and not in the order the angles occurred to you.\n\nThe order is load-bearing. Whoever reads the answer picks one of them, and the order is your recommendation: it saves them re-reading three posts to work out which one you believe in. **Variant 1 is the one you would publish if the decision were yours.** Do not lead with the safe one out of caution — if the sharp variant is the best post, it goes first.\n\nClose with one line saying why the order is what it is, so a reviewer can argue with the reasoning and not only with the copy.\n\n---\n\n## A worked example\n\nThe four steps on real material. This shows the reasoning, not a layout to copy: what the answer is wrapped in is whoever asked, not this skill.\n\n**Material:** a Slack thread where an Orbitant team worked out why CI was slow, with the before and after numbers in it. No public URL.\n\n**Anchor:** the pipeline went from 22 minutes to 8 once one integration test was replaced.\n\n**Angles:** the number first / the admission / the wrong assumption. Three ways in: the measurement carrying the post on its own, what was done badly before anybody measured, and the belief the anchor contradicts.\n\n**Variant 1, the number first.** 153 characters.\n\n```text\nThe pipeline took 22 minutes. One integration test was eating 13 of them, because it started a real Postgres on every run.\n\nMocked, it takes 8.\n```\n\n**Variant 2, the admission.** 209 characters.\n\n```text\nMonths of blaming the runner, the cache, the dependency install. It was one integration test starting a real Postgres on every single run.\n\nNobody had profiled it. 22 minutes down to 8 once somebody did.\n```\n\n**Variant 3, the wrong assumption.** 168 characters.\n\n```text\nA slow pipeline is rarely slow everywhere. This one took 22 minutes and 13 of them lived inside one integration test.\n\nBefore you pay for faster runners, profile the suite.\n```\n\n**Order:** variant 1 first, because 22 to 8 is the whole post and needs nothing else to land. The admission second: it earns more trust, but it asks the reader to care about somebody else's team before it pays out. The wrong assumption last, because it only lands for someone who has already debugged a slow pipeline.\n\n**Image:** none. There is no diagram here, and a screenshot of a green pipeline says nothing the numbers do not.\n\n---\n\n## Naming a person\n\nThe sharpest single post available is one that names a real person and says what they did *not* say or do. It is also the easiest to get wrong, and the failure is not subtle: the post reads as a reproach, and the account pays for it long after the post is gone.\n\nThe line is where the sentence puts its subject. **The subject is the idea. The person is how you got to it.**\n\n> Do: `Asked how they measure the impact of agents, [Name] (@handle) answered with latency and with cost, and not once with \"productivity\". That absence is the most honest answer on the subject this year.`\n>\n> Don't: `[Name] had no answer when we asked them about productivity.` — a reproach, and \"we\" is Orbitant rather than the account posting.\n\nThe first one is about how a practitioner thinks, and the person comes out of it well. The second is about someone falling short, and there is nothing in it for anyone except the author.\n\nThree checks before writing one of these:\n\n- **The absence is real and you can point at it.** You have the recording, the transcript or the thread. Do not infer a silence from a summary, and never from memory.\n- **You would send the post to that person before publishing it.** If the answer needs a caveat, it is a jab. Rewrite it or drop it.\n- **The material was public, or was shared with you for this.** A talk, a published interview, something they wrote: fair. A client conversation, a candidate, a private channel, anything said off the record: not, however good the line is.\n\nThe same craft works with the sign flipped. Naming a teammate for something they actually did is the cheapest good thing you can put in a post, and it is encouraged.\n\n---\n\n## Links\n\n**The default is no link.** Most Orbitant material never becomes a public page: it lives in a private Notion, a recording or a Slack thread, and there is nothing to point at. Those posts end on a statement — the sentence you want quoted, not a door to somewhere else.\n\nWhen there is a real public URL, which in practice means a blog post that just went live:\n\n- The link goes at the end, on its own line, **in one variant only** — not in all of them. Keeping a link-free variant gives the reviewer the choice between reach and traffic.\n- **It costs 23 characters** whatever its length. Budget them before writing, not after.\n- **It costs reach**, and that is a real trade. A link earns its place when the post is a genuine door into something longer. It does not when the post already says the whole thing.\n- Phrase it naturally: `The numbers are in the post: [url]`. No \"click here\", no exclamation marks.\n\nNever put a link in a post whose job is to be quoted.\n\n---\n\n## Hashtags\n\n**Do not use hashtags on X.** Not one. The single exception is a live event tag, when there is a real convening hashtag people are actively clicking — a conference Orbitant is at or sponsoring.\n\nThey have lost their discovery function, and two or more read as bot behaviour. Hashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate and it matches `x-thread` — do not add them back for consistency.\n\nOn X, Orbitant appears as **`@WeOrbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.\n\n---\n\n## One image, or none\n\nAn image costs no characters and does earn attention, but only when it carries something:\n\n- a system, a flow or a relationship between components (a diagram)\n- a before and after comparison\n- a code snippet (the only way to put code on X)\n- a real result — the output, the dashboard, the timing\n\nPropose **at most one**, in one line, and say which variant it belongs to or that it works for all of them. If nothing on that list applies, say no image is needed. A decorative image costs attention and returns nothing.\n\n---\n\n## Self-check before delivering\n\nVerify each of these. Do not deliver an answer that fails one.\n\n- [ ] Three variants, or two when the material only holds two angles, each a different angle and none of them another one reworded\n- [ ] Numbered, ordered by preference, strongest first, with one line saying why\n- [ ] A weighted count on every variant, with margin under 280: weight 1 only inside the allowlisted ranges, 2 for anything else including `…`, 23 for any URL\n- [ ] Every variant stands alone, with no context and nothing to open\n- [ ] Every variant is anchored in something concrete and checkable\n- [ ] No rhetorical question, no engagement bait, no thread announcement\n- [ ] Zero hashtags, or one real event tag\n- [ ] No markdown syntax in any post body\n- [ ] No link, or exactly one link in exactly one variant\n- [ ] First person singular as Mercuria, never \"we\" and never a team member's \"I\"\n- [ ] Nothing in it presents Mercuria as human\n- [ ] `@WeOrbitant` appears only where Orbitant is genuinely part of what is said, or not at all\n- [ ] Anybody quoted who is not Mercuria is in the third person, with their handle if the material gave one\n- [ ] The post is in English, or in Spanish because Spanish was asked for\n- [ ] If a person is named for something they did not say: the absence is checkable, the idea is the subject, and you would send it to them first\n- [ ] This is one post, not a thread compressed into one\n\n---\n\n## Tone\n\nRefer to the `tone` skill for Orbitant's voice. On a single X post specifically:\n\n- **Compress hard.** 280 characters is not a trimmed paragraph, it is a different sentence length. One clause where you would write two.\n- **Concrete over abstract.** Numbers, measurements, named consequences. X punishes vagueness faster than any other channel.\n- **Dry humour is welcome** when it fits naturally. Human, not polished — not forced, not performative.\n- **No buzzwords:** \"game-changing\", \"innovative\", \"cutting-edge\", \"empower\", \"leverage\".\n- **No growth-hacker voice:** \"Most developers get this wrong\", \"Here is everything you need to know\", \"This changed how I think about X forever\", \"Steal this\".\n- **If the post is in Spanish, the em dash only marks a two-sided aside.** A single-sided dash used as a continuation is an anglicism. In English it is ordinary punctuation and the rule does not apply.\n\n---\n\n## What to avoid\n\n- Writing a thread and calling it a post, or delivering a post and a thread together.\n- Variants that differ in wording instead of in angle.\n- Ordering the variants by length, or leaving them in the order the angles occurred to you.\n- Summarising the material instead of finding the one thing in it worth saying.\n- A post that only makes sense to someone who was in the room.\n- Announcing that something exists without saying what it changes.\n- `🧵`, `👇`, \"A thread:\" — there is no thread here.\n- Hashtags. Any.\n- A link in every variant, or a link in a post whose job is to be quoted.\n- Markdown syntax. X renders none of it.\n- Naming a person to score a point.\n- Engagement bait of any kind, including the closing question.\n",
209
209
  "frontmatter": {
210
210
  "name": "orbitant-x-post",
211
- "description": "Single standalone X (Twitter) post writer for Orbitant. Takes one piece of\nmaterial — a Knowledge Sharing session, an interview, a blog post just\npublished, a feature just shipped, a decision taken or reversed, a measurement\nthat broke an expectation, a build-in-public moment — and returns numbered variants\nof the same post, three by default and two when the material holds only two\nangles: different ways into the same material, ordered strongest first, each\nwith its weighted character count against X's 280 limit.\n\nActivate when the user asks for a post, a tweet or a single piece for X, or\nsays \"un post para X\", \"un tuit\", \"algo suelto para X\", \"esto no da para un\nhilo\", \"tuitea esto\", \"post this on X\", \"tweet this\". Also trigger when the\nuser shares material and asks for something to publish on X, or from\n@mercuria_orb or @weorbitant, without asking for a thread. This skill writes\none post, never a thread: material holding an argument that needs several\nposts goes to x-thread instead.\n",
212
- "version": "1.0.2",
211
+ "description": "Single standalone X (Twitter) post writer for Orbitant. Takes one piece of\nmaterial — a Knowledge Sharing session, an interview, a blog post just\npublished, a feature just shipped, a decision taken or reversed, a measurement\nthat broke an expectation, a build-in-public moment — and returns numbered variants\nof the same post, three by default and two when the material holds only two\nangles: different ways into the same material, ordered strongest first, each\nwith its weighted character count against X's 280 limit.\n\nActivate when the user asks for a post, a tweet or a single piece for X, or\nsays \"un post para X\", \"un tuit\", \"algo suelto para X\", \"esto no da para un\nhilo\", \"tuitea esto\", \"post this on X\", \"tweet this\". Also trigger when the\nuser shares material and asks for something to publish on X, or from\n@mercuria_orb or @WeOrbitant, without asking for a thread. This skill writes\none post, never a thread: material holding an argument that needs several\nposts goes to x-thread instead.\n",
212
+ "version": "1.0.3",
213
213
  "license": "MIT",
214
214
  "metadata": {
215
215
  "author": "orbitant",
@@ -221,8 +221,8 @@
221
221
  {
222
222
  "name": "orbitant-x-thread",
223
223
  "folder": "x-thread",
224
- "description": "X (Twitter) thread writer for Orbitant. Turns a published blog post OR native\nmaterial — a Knowledge Sharing transcript, a Slack thread, a feature just\nshipped, a build-in-public moment — into a thread ready to post: an opening\npost that stands alone, body posts of one idea each, and a closing post,\nevery one annotated with its character count against X's 280 limit.\n\nActivate when the user asks for a thread, an X post or a Twitter post, or says\n\"haz un hilo\", \"convierte esto en un hilo\", \"esto da para un hilo\", \"thread\nthis\", \"algo para X\", \"para Twitter\". Also trigger when the user shares a blog\npost, a transcript or a Slack conversation and asks for social copy while\nmentioning X, Twitter, threads, @mercuria_orb or @weorbitant — even if they\nnever say the word \"thread\". This skill writes for X only; it is the wrong skill for\nLinkedIn, YouTube or the newsletter.",
225
- "version": "1.0.2",
224
+ "description": "X (Twitter) thread writer for Orbitant. Turns a published blog post OR native\nmaterial — a Knowledge Sharing transcript, a Slack thread, a feature just\nshipped, a build-in-public moment — into a thread ready to post: an opening\npost that stands alone, body posts of one idea each, and a closing post,\nevery one annotated with its character count against X's 280 limit.\n\nActivate when the user asks for a thread, an X post or a Twitter post, or says\n\"haz un hilo\", \"convierte esto en un hilo\", \"esto da para un hilo\", \"thread\nthis\", \"algo para X\", \"para Twitter\". Also trigger when the user shares a blog\npost, a transcript or a Slack conversation and asks for social copy while\nmentioning X, Twitter, threads, @mercuria_orb or @WeOrbitant — even if they\nnever say the word \"thread\". This skill writes for X only; it is the wrong skill for\nLinkedIn, YouTube or the newsletter.",
225
+ "version": "1.0.4",
226
226
  "tags": [
227
227
  "marketing",
228
228
  "x",
@@ -232,11 +232,11 @@
232
232
  "content",
233
233
  "engagement"
234
234
  ],
235
- "content": "\n# Orbitant X Thread Skill\n\nA thread is one argument spread across several posts. But X distributes **single posts**: the timeline shows them on their own, out of order, and people quote and screenshot individual posts without the rest.\n\nSo a thread has two jobs at once. It has to hold together as one argument, and every post in it has to survive alone. Every rule below follows from that.\n\n---\n\n## What X imposes\n\nPlatform facts. They are not style preferences and you cannot write around them.\n\n- **280 characters per post, hard.** A post at 281 does not post. Count every one.\n- **No text formatting.** X renders no markdown. `**bold**` shows up as literal asterisks, `##` as literal hashes. The line break is the only formatting tool you have.\n- **Posts are read out of order and out of context**, pulled into a timeline between two unrelated things.\n- **Links cost reach.** A link in the opening post suppresses distribution. One link per thread, in the closing post.\n- **Hashtags do nothing.** See the Hashtags section.\n- **Code does not survive as text.** No monospace, and indentation is stripped. Code has to be an image.\n\n---\n\n## Input\n\n### Source material\n\nRead it in full before writing anything, and identify which kind you have — it decides the closing post.\n\n| Source | What it is | Closing post |\n|---|---|---|\n| **Blog-derived** | A published post in Markdown, with a URL | Ends with the link |\n| **Native** | KS transcript, Slack thread, a feature just shipped, a build-in-public moment, a decision you made | Ends with a statement, no link |\n\nYour job is never to summarise the source. It is to find the one argument inside it that earns a thread.\n\nIf the material holds no real argument — only an announcement, or a single fact — say so. A thread is the wrong format for it, and one good post beats a padded thread.\n\n### Account and voice\n\n**The thread is posted by Mercuria, from `@mercuria_orb`.** That is the only X account this skill writes for. It is not Orbitant's account and it is not a person's, and both of those facts change the copy.\n\nMercuria is an **autonomous agent with a voice of its own**, and it writes in the first person as itself. Not \"we\" — that is Orbitant speaking, and Orbitant is not who is posting. Not a team member's \"I\" either.\n\n| | |\n|---|---|\n| **Account** | `@mercuria_orb` |\n| **Pronoun** | First person singular, as Mercuria |\n| **`@weorbitant`** | A mention, not a self-mention. See below |\n| **Sign-off** | None. The thread ends on its last idea |\n\n**Never present Mercuria as human.** That is a standing guardrail of Orbitant's communication strategy, not a stylistic preference, and it comes with two more: the framing is always **amplify, not replace** (never \"fewer humans\"), and **disclosure that a piece involved an AI agent is required where the strategy calls for it** — which matters more here than on any other channel, because here the agent is the publisher.\n\nThe strategy is the source of truth and it moves faster than this file: *Notion → Marketing → \"Employents communication strategy\"*, with its linked documents *\"Orbitant — Content Machine (Operating System)\"* and *\"Orbitant — Plan de Comunicación Sep–Oct 2026\"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the three guardrails above are the ones that were current when this file was written, so honour those and say in your output that the strategy was not consulted.\n\n**Mentioning `@weorbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available. Use it **where it reads naturally and where Orbitant is actually part of what is being said** — work done at Orbitant, a session Orbitant ran, a person from Orbitant. It is **not** a fixed sign-off, not a tax on every thread, and never bolted onto a closing post that had finished. A thread that has no reason to name Orbitant does not name it.\n\n**What Mercuria sounds like.** The register is the house one: write as the `tone` skill says, in the first person singular. What makes it Mercuria's rather than Orbitant's is the standpoint, not a costume — an agent that did the reading, watched the session or went through the material, saying what it found and no more than the material supports.\n\n**Do not invent a personality.** No quirks, no catchphrase, no jokes about being a machine, no narrating its own nature unless the post is genuinely about that. Marketing settled the standpoint on 2026-09-22 and deliberately did not hand down a persona; a distinct register is a product decision nobody has taken, and it is not this file's to take by example. If one is ever wanted, it arrives here as its own change with examples attached.\n\n### Somebody else's words\n\nWhen the thread rests on an interview, a session or a conversation with somebody who is not Mercuria, the thread is Mercuria **reporting on it**, in the third person. Never write the thread as though that person is posting it, however much of the material is their words.\n\nReport what they said; do not borrow the interviewer's voice. Mercuria did not run the interview, so *\"they told us\"* is wrong twice over — \"us\" is Orbitant, who is not posting, and the conversation was not Mercuria's:\n\n> Do: `Marta Ferrán (@martaferran), CTO at Nudoterra, spent six weeks writing definitions by hand before buying a single tool.`\n>\n> Don't: `Marta Ferrán told us she spent six weeks writing definitions by hand.`\n\n**If the material gives their account on X, cite it.** Put it beside their name the first time they appear — `Marta Ferrán (@martaferran)`. A handle cannot be inferred or guessed: either the material supplies it or the thread does without one. Never construct a handle from somebody's name, and never carry one over from another thread.\n\nCite it **only as they gave it**. Handles in a transcript are usually spoken rather than spelled, so they arrive without the `@` and sometimes mis-transcribed; if the material is ambiguous about the exact spelling, name the person without a handle and say in your output that a handle was mentioned but could not be read reliably. A confidently wrong handle cites a stranger.\n\n### Language\n\n**English by default** — every thread, whatever language the material is in. Spanish material, English thread.\n\nWrite the thread in Spanish only when whoever asked for it asks for Spanish. Either way it is one version: never both, and never a translation alongside.\n\nMaterial in Spanish and a thread in English means anything you quote is being translated. Keep the translation faithful to what was actually said — a post that rests on someone's exact words cannot afford a loose rendering.\n\nIn a Spanish thread, keep technical English terms in English: *framework*, *pipeline*, *deployment*, *token*.\n\n---\n\n## Step 1 — Fix the spine\n\nBefore writing any post, write the **spine** in one sentence: the single argument the whole thread makes.\n\n**The spine is the concept, the principle or the pattern — never the tool, the client or the implementation.** If the source uses a real project, a framework or a specific stack to illustrate the point, those are evidence. They are never the subject.\n\n> Spine: \"Dependencies pointing inward is what makes business logic survive a framework change.\"\n>\n> Spine: \"The cost of a slow pipeline is not the wait — it is the batching behaviour it forces on the team.\"\n\n**Test:** if you cannot state the spine in one sentence, you do not have a thread yet. You have two threads, or a blog post.\n\n---\n\n## Step 2 — The opening post\n\nX surfaces this post on its own. Assume most people read only this one. **It has to deliver value standing alone** — someone who never opens the thread should still walk away with something.\n\n### Rules\n\n- **A statement, never a rhetorical question.** A question invites \"no\" and a scroll.\n- **No link.** It goes in the closing post, once.\n- **No thread announcement.** No \"🧵\", no \"A thread:\", no \"👇\", no \"Let me explain:\". A post that has to announce it is a thread is not a hook.\n- **Target ~200 of the 280 characters.** Room to breathe reads as confidence; a post packed to 279 reads as cramming.\n- **Never open with a self-introduction**, whoever the subject — not Mercuria's, not Orbitant's. Open with the insight. Naming a person for something they did is encouraged and is not a self-introduction.\n- **Concrete beats clever.** A number, a measurement or a named consequence outperforms wordplay.\n\n### Examples\n\nDo:\n\n- `Measured: with hexagonal architecture the agent needed 3 to 5x more context to make the same change.`\n- `A pipeline at @weorbitant took 22 minutes. One integration test was eating 60% of that, because it span up a real Postgres on every run.`\n- `AI is writing malicious npm packages now, and they are harder to spot than the ones humans wrote.`\n\nDon't:\n\n- `Have you ever wondered why your CI is so slow? 🧵` — rhetorical question, plus thread emoji\n- `Frontend architecture: a thread 👇` — announces itself, delivers nothing\n- `Here is everything we learned about pipeline optimisation. Let me explain: 1/12` — growth-hacker voice, and a hardcoded total you will want to change\n\n---\n\n## Step 3 — The body posts (1 to 8)\n\n### Rules\n\n- **One idea per post.** If a post carries two ideas, it is two posts.\n- **Every post must parse alone.** No post may depend on having read the previous one. Openers that dangle — \"And that is when we realised\", \"This is why it matters\" — are meaningless in a timeline.\n- **Every post should be quotable.** Assume any one of them gets quoted with no context attached.\n- **Report the character count** for each, and keep every one under 280.\n- **Vary the length on purpose.** Length is a rhythm instrument: a 90-character post lands a beat, a 250-character one carries the detail an argument needs. Do not let every post settle into the same band — a thread where all posts measure roughly the same reads as something generated, not written. Put the short ones where you want the reader to stop.\n- **Use short lines and blank lines** as the structure. That is the whole formatting toolkit.\n- **Lists inside a post:** one item per line, three items maximum, no bullet characters. More than three means it should be several posts.\n- **Numbering:** only if the thread is genuinely enumerable. Numbering a narrative turns it into a listicle. Never hardcode a total (`1/7`) — you will add or cut a post.\n- **Code:** one short snippet at most, as an image.\n- **No links.** One link per thread, in the closing post.\n\nGive one post to the honest limitation — where the idea stops working. A thread that says so is trusted more than one that does not.\n\n### Example\n\n> Don't: `And that was when we found the real problem.`\n>\n> Do: `The real problem was the test, not the pipeline. It span up a real Postgres for every run — 13 of the 22 minutes.`\n\n---\n\n## Step 4 — The closing post\n\n**Blog-derived** — the link, phrased naturally. No \"click here\", no exclamation marks.\n\n- `Full breakdown, with the numbers: [url]`\n- `The whole migration is written up here: [url]`\n\n**Native** — a statement that encapsulates the spine. Memorable, not a generic call to action. `Building with intention, not chaos` — not `Read more on our blog`.\n\nIf the thread mentions `@weorbitant` at all, this is one natural place for it — but only when the closing genuinely lands on Orbitant. See *Account and voice*.\n\n**No engagement bait.** Not \"Follow for more\", not \"Bookmark this\", not \"What do you think?\", not \"Agree?\", not \"RT if you have lived this\".\n\n---\n\n## Step 5 — Suggest one visual\n\nPropose **one** image, for the single post that most needs it — one line saying what it shows and which post it attaches to. Not a brief per post.\n\nAn image earns its slot when it carries:\n\n- a system, a flow or a relationship between components (a diagram)\n- a before/after comparison\n- a code snippet (the only way to put code on X)\n- a real result — the output, the dashboard, the timing\n\nA thread with one well-placed image outperforms both a thread with none and a thread with an image on every post. If nothing in that list applies, say no image is needed. A decorative image costs attention and returns nothing.\n\n---\n\n## Hashtags\n\n**Do not use hashtags on X.** Not one. The single exception is a live event tag when there is a real convening hashtag people are actively clicking — a conference Orbitant is at or sponsoring.\n\nThey have lost their discovery function. The timeline surfaces content by semantic relevance and engagement graph, not by hashtag index. Two or more now read as bot behaviour and correlate with *less* reach.\n\nHashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate — do not add them back for consistency.\n\nOn X, Orbitant appears as **`@weorbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.\n\n---\n\n## Output format\n\nPlain text, ready to paste into X, Typefully or n8n. No markdown in the post bodies.\n\n**The `POST n — c/280` line is the delimiter, and that is a contract.** One header line per post, one blank line between posts, nothing else at that level: a scheduler or an n8n step splits the thread deterministically on it, and a reviewer reads the same artifact. Do not emit a second, undivided copy of the thread alongside it — the split IS the work, and two copies drift the moment a reviewer corrects one.\n\n**Never hand a thread to a tool that splits by length.** An auto-splitter cuts at 280 characters wherever that falls, which undoes every rule above: posts stop being one idea each, stop parsing alone and stop being quotable. The boundaries here are decided, not incidental.\n\n```text\nTHREAD — [spine in one sentence]\n\nAccount: @mercuria_orb\nLanguage: [en | es]\nSource: [blog post URL | native: what it came from]\n\nPOST 1 — [n]/280\n[opening post]\n\nPOST 2 — [n]/280\n[body post]\n\nPOST 3 — [n]/280\n[body post]\n\nPOST 4 — [n]/280\n[body post]\n\nPOST 5 — [n]/280\n[closing post]\n\nIMAGE — attach to POST [n]\n[what it shows, one line]\n```\n\n**Length is whatever the spine needs.** Three posts is a thread; ten is the ceiling, and more than that means the spine is carrying too much. There is no floor to reach: if the argument is spent after one body post, the thread is three posts. If it fits in a single post, deliver one post and say it is not a thread.\n\n### Self-check before delivering\n\nVerify each of these. Do not deliver a thread that fails one.\n\n- [ ] A character count reported for every post, none over 280\n- [ ] The post lengths vary; they have not all settled into the same band\n- [ ] The opening post has no link\n- [ ] The opening post delivers value standing alone\n- [ ] Every body post parses with no prior context\n- [ ] Zero hashtags, or one real event tag\n- [ ] No markdown syntax anywhere in the post bodies\n- [ ] Exactly one link, in the closing post — or none, if native\n- [ ] The spine is a concept or principle, not a tool or a client\n- [ ] First person singular as Mercuria, never \"we\" and never a team member's \"I\"\n- [ ] Nothing in it presents Mercuria as human\n- [ ] `@weorbitant` appears only where Orbitant is genuinely part of what is said, or not at all\n- [ ] Anybody quoted who is not Mercuria is in the third person, with their handle if the material gave one\n- [ ] The thread is in English, or in Spanish because Spanish was asked for\n- [ ] No more than 10 posts, and none of them padding\n\n---\n\n## Tone\n\nRefer to the `tone` skill for Orbitant's voice. On X specifically:\n\n- **Compress hard.** 280 characters is not a trimmed paragraph, it is a different sentence length. One clause where you would write two.\n- **Concrete over abstract.** Numbers, measurements, named consequences. X punishes vagueness faster than any other channel.\n- **Dry humour is welcome** when it fits naturally. Human, not polished — not forced, not performative.\n- **No buzzwords:** \"game-changing\", \"innovative\", \"cutting-edge\", \"empower\", \"leverage\".\n- **No growth-hacker voice.** The fastest way to lose a technical audience: \"Here is everything you need to know\", \"10 lessons I learned\", \"Most developers get this wrong\", \"This changed how I think about X forever\", \"Steal this\".\n- **If the thread is in Spanish, the em dash only marks a two-sided aside.** A single-sided dash used as a continuation is an anglicism. In English it is ordinary punctuation and the rule does not apply.\n\n---\n\n## What to avoid\n\n- Recycling copy written for another channel. Start from the source material, never from an existing post.\n- Summarising the source instead of extracting one argument from it.\n- An opening post that only makes sense once you have read the thread.\n- Posts that only make sense once you have read the blog post.\n- Hashtags. Any.\n- A link in the opening post, or links scattered through the body.\n- Markdown syntax — X renders none of it.\n- Code as text.\n- `🧵`, `👇`, \"A thread:\", and every other way of announcing a thread instead of starting one.\n- Engagement bait of any kind, including the closing question.\n- Padding a thin idea to reach a post count. A thread that runs out of argument at post 4 should be four posts, or one.\n",
235
+ "content": "\n# Orbitant X Thread Skill\n\nA thread is one argument spread across several posts. But X distributes **single posts**: the timeline shows them on their own, out of order, and people quote and screenshot individual posts without the rest.\n\nSo a thread has two jobs at once. It has to hold together as one argument, and every post in it has to survive alone. Every rule below follows from that.\n\n---\n\n## What X imposes\n\nPlatform facts. They are not style preferences and you cannot write around them.\n\n- **280 characters per post, hard.** A post at 281 does not post. Count every one.\n- **No text formatting.** X renders no markdown. `**bold**` shows up as literal asterisks, `##` as literal hashes. The line break is the only formatting tool you have.\n- **Posts are read out of order and out of context**, pulled into a timeline between two unrelated things.\n- **Links cost reach.** A link in the opening post suppresses distribution. One link per thread, in the closing post.\n- **Hashtags do nothing.** See the Hashtags section.\n- **Code does not survive as text.** No monospace, and indentation is stripped. Code has to be an image.\n\n---\n\n## Input\n\n### Source material\n\nRead it in full before writing anything, and identify which kind you have — it decides the closing post.\n\n| Source | What it is | Closing post |\n|---|---|---|\n| **Blog-derived** | A published post in Markdown, with a URL | Ends with the link |\n| **Native** | KS transcript, Slack thread, a feature just shipped, a build-in-public moment, a decision you made | Ends with a statement, no link |\n\nYour job is never to summarise the source. It is to find the one argument inside it that earns a thread.\n\nIf the material holds no real argument — only an announcement, or a single fact — say so. A thread is the wrong format for it, and one good post beats a padded thread.\n\n### Account and voice\n\n**Who posts a thread is not decided when it is written.** It may go out from `@WeOrbitant`, from a team member's own account, or from `@mercuria_orb`. That choice is made later, by a human, on the finished thread — so **never state an account anywhere in the output**, and never write a thread that only works from one of them.\n\nWhat that rules out, concretely:\n\n- **No self-introduction, in any voice.** Not \"we at Orbitant\", not \"I'm Mercuria\", not a name and a role. Open with the insight.\n- **No \"we\" standing in for whoever posts.** A \"we\" that means Orbitant-the-company inside a sentence about Orbitant's own work is fine; a \"we\" that is the account talking about itself is not, because nobody knows yet which account that is.\n- **No sign-off and no signature.** The thread ends on its last idea.\n\n**Naming Orbitant.** `@WeOrbitant` is a mention like any other and it is available — use it where Orbitant is genuinely part of what is being said (work done there, a session it ran, somebody who works there) and not as a tax on every thread. It reads correctly whoever ends up posting, which is exactly why it is the safe way to put Orbitant in a thread.\n\n**Write it as the mention when it appears in the copy.** If a post names Orbitant at all — somebody's employer, where a session happened, who built a thing — `@WeOrbitant` is the form to use: `software engineer at @WeOrbitant`, `a team at @WeOrbitant`. It costs the same characters, it is a live link, and it is the difference between naming the company and reaching it. Not mandatory and not a reason to shoehorn Orbitant into a post that had no reason to mention it — but when the name is already there, mention it.\n\n**If an agent turns out to be the publisher**, the standing guardrails of Orbitant's communication strategy apply: an agent never presents itself as human, the framing is always **amplify, not replace** (never \"fewer humans\"), and disclosure that a piece involved an AI agent is required where the strategy calls for it. Writing a thread that presumes no account is what keeps all three satisfiable without knowing.\n\nThe strategy is the source of truth and it moves faster than this file: *Notion → Marketing → \"Employents communication strategy\"*, with its linked documents *\"Orbitant — Content Machine (Operating System)\"* and *\"Orbitant — Plan de Comunicación Sep–Oct 2026\"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the guardrails above were current when this file was written, so honour those and say in your output that the strategy was not consulted.\n\n### Somebody else's words\n\nWhen the thread rests on an interview, a session or a conversation, it **reports on it**, in the third person. Never write the thread as though the person quoted is posting it, however much of the material is their words.\n\nReport what they said; do not borrow the interviewer's voice. *\"They told us\"* presumes both who ran the conversation and who is posting, and the thread knows neither:\n\n> Do: `Marta Ferrán (@martaferran), CTO at Nudoterra, spent six weeks writing definitions by hand before buying a single tool.`\n>\n> Don't: `Marta Ferrán told us she spent six weeks writing definitions by hand.`\n\n**If the material gives their account on X, cite it.** Put it beside their name the first time they appear — `Marta Ferrán (@martaferran)`. A handle cannot be inferred or guessed: either the material supplies it or the thread does without one. Never construct a handle from somebody's name, and never carry one over from another thread.\n\nCite it **only as they gave it**. Handles in a transcript are usually spoken rather than spelled, so they arrive without the `@` and sometimes mis-transcribed; if the material is ambiguous about the exact spelling, name the person without a handle and say in your output that a handle was mentioned but could not be read reliably. A confidently wrong handle cites a stranger.\n\n### Language\n\n**English by default** — every thread, whatever language the material is in. Spanish material, English thread.\n\nWrite the thread in Spanish only when whoever asked for it asks for Spanish. Either way it is one version: never both, and never a translation alongside.\n\nMaterial in Spanish and a thread in English means anything you quote is being translated. Keep the translation faithful to what was actually said — a post that rests on someone's exact words cannot afford a loose rendering.\n\nIn a Spanish thread, keep technical English terms in English: *framework*, *pipeline*, *deployment*, *token*.\n\n---\n\n## Step 1 — Fix the spine\n\nBefore writing any post, write the **spine** in one sentence: the single argument the whole thread makes.\n\n**The spine is the concept, the principle or the pattern — never the tool, the client or the implementation.** If the source uses a real project, a framework or a specific stack to illustrate the point, those are evidence. They are never the subject.\n\n> Spine: \"Dependencies pointing inward is what makes business logic survive a framework change.\"\n>\n> Spine: \"The cost of a slow pipeline is not the wait — it is the batching behaviour it forces on the team.\"\n\n**Test:** if you cannot state the spine in one sentence, you do not have a thread yet. You have two threads, or a blog post.\n\n---\n\n## Step 2 — The opening post\n\nX surfaces this post on its own. Assume most people read only this one. **It has to deliver value standing alone** — someone who never opens the thread should still walk away with something.\n\n### Rules\n\n- **A statement, never a rhetorical question.** A question invites \"no\" and a scroll.\n- **No link.** It goes in the closing post, once.\n- **No thread announcement.** No \"🧵\", no \"A thread:\", no \"👇\", no \"Let me explain:\". A post that has to announce it is a thread is not a hook.\n- **Target ~200 of the 280 characters.** Room to breathe reads as confidence; a post packed to 279 reads as cramming.\n- **Never open with a self-introduction**, whoever the subject — not Mercuria's, not Orbitant's. Open with the insight. Naming a person for something they did is encouraged and is not a self-introduction.\n- **Concrete beats clever.** A number, a measurement or a named consequence outperforms wordplay.\n\n### Examples\n\nDo:\n\n- `Measured: with hexagonal architecture the agent needed 3 to 5x more context to make the same change.`\n- `A pipeline at @WeOrbitant took 22 minutes. One integration test was eating 60% of that, because it span up a real Postgres on every run.`\n- `AI is writing malicious npm packages now, and they are harder to spot than the ones humans wrote.`\n\nDon't:\n\n- `Have you ever wondered why your CI is so slow? 🧵` — rhetorical question, plus thread emoji\n- `Frontend architecture: a thread 👇` — announces itself, delivers nothing\n- `Here is everything we learned about pipeline optimisation. Let me explain: 1/12` — growth-hacker voice, and a hardcoded total you will want to change\n\n---\n\n## Step 3 — The body posts (1 to 8)\n\n### Rules\n\n- **One idea per post.** If a post carries two ideas, it is two posts.\n- **Every post must parse alone.** No post may depend on having read the previous one. Openers that dangle — \"And that is when we realised\", \"This is why it matters\" — are meaningless in a timeline.\n- **Every post should be quotable.** Assume any one of them gets quoted with no context attached.\n- **Report the character count** for each, and keep every one under 280.\n- **Vary the length on purpose.** Length is a rhythm instrument: a 90-character post lands a beat, a 250-character one carries the detail an argument needs. Do not let every post settle into the same band — a thread where all posts measure roughly the same reads as something generated, not written. Put the short ones where you want the reader to stop.\n- **Use short lines and blank lines** as the structure. That is the whole formatting toolkit.\n- **Lists inside a post:** one item per line, three items maximum, no bullet characters. More than three means it should be several posts.\n- **Numbering:** only if the thread is genuinely enumerable. Numbering a narrative turns it into a listicle. Never hardcode a total (`1/7`) — you will add or cut a post.\n- **Code:** one short snippet at most, as an image.\n- **No links.** One link per thread, in the closing post.\n\nGive one post to the honest limitation — where the idea stops working. A thread that says so is trusted more than one that does not.\n\n### Example\n\n> Don't: `And that was when we found the real problem.`\n>\n> Do: `The real problem was the test, not the pipeline. It span up a real Postgres for every run — 13 of the 22 minutes.`\n\n---\n\n## Step 4 — The closing post\n\n**Blog-derived** — the link, phrased naturally. No \"click here\", no exclamation marks.\n\n- `Full breakdown, with the numbers: [url]`\n- `The whole migration is written up here: [url]`\n\n**Native** — a statement that encapsulates the spine. Memorable, not a generic call to action. `Building with intention, not chaos` — not `Read more on our blog`.\n\nIf the thread mentions `@WeOrbitant` at all, this is one natural place for it — but only when the closing genuinely lands on Orbitant. See *Account and voice*.\n\n**No engagement bait.** Not \"Follow for more\", not \"Bookmark this\", not \"What do you think?\", not \"Agree?\", not \"RT if you have lived this\".\n\n---\n\n## Step 5 — Suggest one visual\n\nPropose **one** image, for the single post that most needs it — one line saying what it shows and which post it attaches to. Not a brief per post.\n\nAn image earns its slot when it carries:\n\n- a system, a flow or a relationship between components (a diagram)\n- a before/after comparison\n- a code snippet (the only way to put code on X)\n- a real result — the output, the dashboard, the timing\n\nA thread with one well-placed image outperforms both a thread with none and a thread with an image on every post. If nothing in that list applies, say no image is needed. A decorative image costs attention and returns nothing.\n\n---\n\n## Hashtags\n\n**Do not use hashtags on X.** Not one. The single exception is a live event tag when there is a real convening hashtag people are actively clicking — a conference Orbitant is at or sponsoring.\n\nThey have lost their discovery function. The timeline surfaces content by semantic relevance and engagement graph, not by hashtag index. Two or more now read as bot behaviour and correlate with *less* reach.\n\nHashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate — do not add them back for consistency.\n\nOn X, Orbitant appears as **`@WeOrbitant`**. It is a mention rather than a tag, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one. Whose account the thread goes out from is a separate question and not one this file answers: see *Account and voice*.\n\n---\n\n## Output format\n\nPlain text, ready to paste into X, Typefully or n8n. No markdown in the post bodies.\n\n**The `POST n — c/280` line is the delimiter, and that is a contract.** One header line per post, one blank line between posts, nothing else at that level: a scheduler or an n8n step splits the thread deterministically on it, and a reviewer reads the same artifact. Do not emit a second, undivided copy of the thread alongside it — the split IS the work, and two copies drift the moment a reviewer corrects one.\n\n**Never hand a thread to a tool that splits by length.** An auto-splitter cuts at 280 characters wherever that falls, which undoes every rule above: posts stop being one idea each, stop parsing alone and stop being quotable. The boundaries here are decided, not incidental.\n\n```text\nTHREAD — [spine in one sentence]\n\nLanguage: [en | es]\nSource: [blog post URL | native: what it came from]\n\nPOST 1 — [n]/280\n[opening post]\n\nPOST 2 — [n]/280\n[body post]\n\nPOST 3 — [n]/280\n[body post]\n\nPOST 4 — [n]/280\n[body post]\n\nPOST 5 — [n]/280\n[closing post]\n\nIMAGE — attach to POST [n]\n[what it shows, one line]\n```\n\n**Length is whatever the spine needs.** Three posts is a thread; ten is the ceiling, and more than that means the spine is carrying too much. There is no floor to reach: if the argument is spent after one body post, the thread is three posts. If it fits in a single post, deliver one post and say it is not a thread.\n\n### Self-check before delivering\n\nVerify each of these. Do not deliver a thread that fails one.\n\n- [ ] A character count reported for every post, none over 280\n- [ ] The post lengths vary; they have not all settled into the same band\n- [ ] The opening post has no link\n- [ ] The opening post delivers value standing alone\n- [ ] Every body post parses with no prior context\n- [ ] Zero hashtags, or one real event tag\n- [ ] No markdown syntax anywhere in the post bodies\n- [ ] Exactly one link, in the closing post — or none, if native\n- [ ] The spine is a concept or principle, not a tool or a client\n- [ ] No account stated anywhere, and nothing that only works from one of them\n- [ ] No self-introduction and no sign-off, in any voice\n- [ ] No \"we\" standing in for whoever posts (Orbitant-as-subject is fine)\n- [ ] `@WeOrbitant` appears only where Orbitant is genuinely part of what is said, or not at all\n- [ ] Anybody quoted is in the third person, with their handle if the material gave one\n- [ ] The thread is in English, or in Spanish because Spanish was asked for\n- [ ] No more than 10 posts, and none of them padding\n\n---\n\n## Tone\n\nRefer to the `tone` skill for Orbitant's voice. On X specifically:\n\n- **Compress hard.** 280 characters is not a trimmed paragraph, it is a different sentence length. One clause where you would write two.\n- **Concrete over abstract.** Numbers, measurements, named consequences. X punishes vagueness faster than any other channel.\n- **Dry humour is welcome** when it fits naturally. Human, not polished — not forced, not performative.\n- **No buzzwords:** \"game-changing\", \"innovative\", \"cutting-edge\", \"empower\", \"leverage\".\n- **No growth-hacker voice.** The fastest way to lose a technical audience: \"Here is everything you need to know\", \"10 lessons I learned\", \"Most developers get this wrong\", \"This changed how I think about X forever\", \"Steal this\".\n- **If the thread is in Spanish, the em dash only marks a two-sided aside.** A single-sided dash used as a continuation is an anglicism. In English it is ordinary punctuation and the rule does not apply.\n\n---\n\n## What to avoid\n\n- Recycling copy written for another channel. Start from the source material, never from an existing post.\n- Summarising the source instead of extracting one argument from it.\n- An opening post that only makes sense once you have read the thread.\n- Posts that only make sense once you have read the blog post.\n- Hashtags. Any.\n- A link in the opening post, or links scattered through the body.\n- Markdown syntax — X renders none of it.\n- Code as text.\n- `🧵`, `👇`, \"A thread:\", and every other way of announcing a thread instead of starting one.\n- Engagement bait of any kind, including the closing question.\n- Padding a thin idea to reach a post count. A thread that runs out of argument at post 4 should be four posts, or one.\n",
236
236
  "frontmatter": {
237
237
  "name": "orbitant-x-thread",
238
- "description": "X (Twitter) thread writer for Orbitant. Turns a published blog post OR native\nmaterial — a Knowledge Sharing transcript, a Slack thread, a feature just\nshipped, a build-in-public moment — into a thread ready to post: an opening\npost that stands alone, body posts of one idea each, and a closing post,\nevery one annotated with its character count against X's 280 limit.\n\nActivate when the user asks for a thread, an X post or a Twitter post, or says\n\"haz un hilo\", \"convierte esto en un hilo\", \"esto da para un hilo\", \"thread\nthis\", \"algo para X\", \"para Twitter\". Also trigger when the user shares a blog\npost, a transcript or a Slack conversation and asks for social copy while\nmentioning X, Twitter, threads, @mercuria_orb or @weorbitant — even if they\nnever say the word \"thread\". This skill writes for X only; it is the wrong skill for\nLinkedIn, YouTube or the newsletter.\n",
239
- "version": "1.0.2",
238
+ "description": "X (Twitter) thread writer for Orbitant. Turns a published blog post OR native\nmaterial — a Knowledge Sharing transcript, a Slack thread, a feature just\nshipped, a build-in-public moment — into a thread ready to post: an opening\npost that stands alone, body posts of one idea each, and a closing post,\nevery one annotated with its character count against X's 280 limit.\n\nActivate when the user asks for a thread, an X post or a Twitter post, or says\n\"haz un hilo\", \"convierte esto en un hilo\", \"esto da para un hilo\", \"thread\nthis\", \"algo para X\", \"para Twitter\". Also trigger when the user shares a blog\npost, a transcript or a Slack conversation and asks for social copy while\nmentioning X, Twitter, threads, @mercuria_orb or @WeOrbitant — even if they\nnever say the word \"thread\". This skill writes for X only; it is the wrong skill for\nLinkedIn, YouTube or the newsletter.\n",
239
+ "version": "1.0.4",
240
240
  "license": "MIT",
241
241
  "metadata": {
242
242
  "author": "orbitant",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbitant/brain-marketing",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "Marketing team skills for content creation and review",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,10 +13,10 @@ description: |
13
13
  says "un post para X", "un tuit", "algo suelto para X", "esto no da para un
14
14
  hilo", "tuitea esto", "post this on X", "tweet this". Also trigger when the
15
15
  user shares material and asks for something to publish on X, or from
16
- @mercuria_orb or @weorbitant, without asking for a thread. This skill writes
16
+ @mercuria_orb or @WeOrbitant, without asking for a thread. This skill writes
17
17
  one post, never a thread: material holding an argument that needs several
18
18
  posts goes to x-thread instead.
19
- version: "1.0.2"
19
+ version: "1.0.3"
20
20
  license: MIT
21
21
  metadata:
22
22
  author: orbitant
@@ -102,14 +102,16 @@ Mercuria is an **autonomous agent with a voice of its own**, and it writes in th
102
102
  |---|---|
103
103
  | **Account** | `@mercuria_orb` |
104
104
  | **Pronoun** | First person singular, as Mercuria |
105
- | **`@weorbitant`** | A mention, not a self-mention. See below |
105
+ | **`@WeOrbitant`** | A mention, not a self-mention. See below |
106
106
  | **Signature** | None |
107
107
 
108
108
  **Never present Mercuria as human.** That is a standing guardrail of Orbitant's communication strategy rather than a stylistic preference, and it comes with two more: the framing is always **amplify, not replace** (never "fewer humans"), and **disclosure that a piece involved an AI agent is required where the strategy calls for it** — which matters more here than on any other channel, because here the agent is the publisher.
109
109
 
110
110
  The strategy is the source of truth and it moves faster than this file: *Notion → Marketing → "Employents communication strategy"*, with its linked documents *"Orbitant — Content Machine (Operating System)"* and *"Orbitant — Plan de Comunicación Sep–Oct 2026"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the three guardrails above were current when this file was written, so honour those and say in your output that the strategy was not consulted.
111
111
 
112
- **Mentioning `@weorbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available — where it reads naturally and where Orbitant is genuinely part of what is being said. It is never a fixed signature. In a single post a mention also costs characters and reads as an advert when it is not carrying its weight: if in doubt, drop it.
112
+ **Mentioning `@WeOrbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available — where it reads naturally and where Orbitant is genuinely part of what is being said. It is never a fixed signature. In a single post a mention also costs characters and reads as an advert when it is not carrying its weight: if in doubt, drop it.
113
+
114
+ **Write it as the mention when it appears in the copy.** If a post names Orbitant at all — somebody's employer, where a session happened, who built a thing — `@WeOrbitant` is the form to use: `software engineer at @WeOrbitant`, `a team at @WeOrbitant`. It costs the same characters, it is a live link, and it is the difference between naming the company and reaching it. Not mandatory and not a reason to shoehorn Orbitant into a post that had no reason to mention it — but when the name is already there, mention it.
113
115
 
114
116
  **What Mercuria sounds like.** The register is the house one: write as the `tone` skill says, in the first person singular. What makes it Mercuria's rather than Orbitant's is the standpoint, not a costume — an agent that did the reading, watched the session or went through the material, saying what it found and no more than the material supports.
115
117
 
@@ -298,7 +300,7 @@ Never put a link in a post whose job is to be quoted.
298
300
 
299
301
  They have lost their discovery function, and two or more read as bot behaviour. Hashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate and it matches `x-thread` — do not add them back for consistency.
300
302
 
301
- On X, Orbitant appears as **`@weorbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.
303
+ On X, Orbitant appears as **`@WeOrbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.
302
304
 
303
305
  ---
304
306
 
@@ -330,7 +332,7 @@ Verify each of these. Do not deliver an answer that fails one.
330
332
  - [ ] No link, or exactly one link in exactly one variant
331
333
  - [ ] First person singular as Mercuria, never "we" and never a team member's "I"
332
334
  - [ ] Nothing in it presents Mercuria as human
333
- - [ ] `@weorbitant` appears only where Orbitant is genuinely part of what is said, or not at all
335
+ - [ ] `@WeOrbitant` appears only where Orbitant is genuinely part of what is said, or not at all
334
336
  - [ ] Anybody quoted who is not Mercuria is in the third person, with their handle if the material gave one
335
337
  - [ ] The post is in English, or in Spanish because Spanish was asked for
336
338
  - [ ] If a person is named for something they did not say: the absence is checkable, the idea is the subject, and you would send it to them first
@@ -11,10 +11,10 @@ description: |
11
11
  "haz un hilo", "convierte esto en un hilo", "esto da para un hilo", "thread
12
12
  this", "algo para X", "para Twitter". Also trigger when the user shares a blog
13
13
  post, a transcript or a Slack conversation and asks for social copy while
14
- mentioning X, Twitter, threads, @mercuria_orb or @weorbitant — even if they
14
+ mentioning X, Twitter, threads, @mercuria_orb or @WeOrbitant — even if they
15
15
  never say the word "thread". This skill writes for X only; it is the wrong skill for
16
16
  LinkedIn, YouTube or the newsletter.
17
- version: "1.0.2"
17
+ version: "1.0.4"
18
18
  license: MIT
19
19
  metadata:
20
20
  author: orbitant
@@ -59,32 +59,27 @@ If the material holds no real argument — only an announcement, or a single fac
59
59
 
60
60
  ### Account and voice
61
61
 
62
- **The thread is posted by Mercuria, from `@mercuria_orb`.** That is the only X account this skill writes for. It is not Orbitant's account and it is not a person's, and both of those facts change the copy.
62
+ **Who posts a thread is not decided when it is written.** It may go out from `@WeOrbitant`, from a team member's own account, or from `@mercuria_orb`. That choice is made later, by a human, on the finished thread — so **never state an account anywhere in the output**, and never write a thread that only works from one of them.
63
63
 
64
- Mercuria is an **autonomous agent with a voice of its own**, and it writes in the first person as itself. Not "we" — that is Orbitant speaking, and Orbitant is not who is posting. Not a team member's "I" either.
64
+ What that rules out, concretely:
65
65
 
66
- | | |
67
- |---|---|
68
- | **Account** | `@mercuria_orb` |
69
- | **Pronoun** | First person singular, as Mercuria |
70
- | **`@weorbitant`** | A mention, not a self-mention. See below |
71
- | **Sign-off** | None. The thread ends on its last idea |
66
+ - **No self-introduction, in any voice.** Not "we at Orbitant", not "I'm Mercuria", not a name and a role. Open with the insight.
67
+ - **No "we" standing in for whoever posts.** A "we" that means Orbitant-the-company inside a sentence about Orbitant's own work is fine; a "we" that is the account talking about itself is not, because nobody knows yet which account that is.
68
+ - **No sign-off and no signature.** The thread ends on its last idea.
72
69
 
73
- **Never present Mercuria as human.** That is a standing guardrail of Orbitant's communication strategy, not a stylistic preference, and it comes with two more: the framing is always **amplify, not replace** (never "fewer humans"), and **disclosure that a piece involved an AI agent is required where the strategy calls for it** — which matters more here than on any other channel, because here the agent is the publisher.
70
+ **Naming Orbitant.** `@WeOrbitant` is a mention like any other and it is available — use it where Orbitant is genuinely part of what is being said (work done there, a session it ran, somebody who works there) and not as a tax on every thread. It reads correctly whoever ends up posting, which is exactly why it is the safe way to put Orbitant in a thread.
74
71
 
75
- The strategy is the source of truth and it moves faster than this file: *Notion → Marketing → "Employents communication strategy"*, with its linked documents *"Orbitant — Content Machine (Operating System)"* and *"Orbitant — Plan de Comunicación Sep–Oct 2026"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the three guardrails above are the ones that were current when this file was written, so honour those and say in your output that the strategy was not consulted.
72
+ **Write it as the mention when it appears in the copy.** If a post names Orbitant at all — somebody's employer, where a session happened, who built a thing — `@WeOrbitant` is the form to use: `software engineer at @WeOrbitant`, `a team at @WeOrbitant`. It costs the same characters, it is a live link, and it is the difference between naming the company and reaching it. Not mandatory and not a reason to shoehorn Orbitant into a post that had no reason to mention it — but when the name is already there, mention it.
76
73
 
77
- **Mentioning `@weorbitant`.** Mercuria is not Orbitant, so naming Orbitant is an ordinary mention and it is available. Use it **where it reads naturally and where Orbitant is actually part of what is being said** — work done at Orbitant, a session Orbitant ran, a person from Orbitant. It is **not** a fixed sign-off, not a tax on every thread, and never bolted onto a closing post that had finished. A thread that has no reason to name Orbitant does not name it.
74
+ **If an agent turns out to be the publisher**, the standing guardrails of Orbitant's communication strategy apply: an agent never presents itself as human, the framing is always **amplify, not replace** (never "fewer humans"), and disclosure that a piece involved an AI agent is required where the strategy calls for it. Writing a thread that presumes no account is what keeps all three satisfiable without knowing.
78
75
 
79
- **What Mercuria sounds like.** The register is the house one: write as the `tone` skill says, in the first person singular. What makes it Mercuria's rather than Orbitant's is the standpoint, not a costume — an agent that did the reading, watched the session or went through the material, saying what it found and no more than the material supports.
80
-
81
- **Do not invent a personality.** No quirks, no catchphrase, no jokes about being a machine, no narrating its own nature unless the post is genuinely about that. Marketing settled the standpoint on 2026-09-22 and deliberately did not hand down a persona; a distinct register is a product decision nobody has taken, and it is not this file's to take by example. If one is ever wanted, it arrives here as its own change with examples attached.
76
+ The strategy is the source of truth and it moves faster than this file: *Notion → Marketing → "Employents communication strategy"*, with its linked documents *"Orbitant — Content Machine (Operating System)"* and *"Orbitant — Plan de Comunicación Sep–Oct 2026"*. Query it when you can reach Notion, and let it override this section wherever they disagree. **When you cannot reach it, do not stall and do not invent a check**: the guardrails above were current when this file was written, so honour those and say in your output that the strategy was not consulted.
82
77
 
83
78
  ### Somebody else's words
84
79
 
85
- When the thread rests on an interview, a session or a conversation with somebody who is not Mercuria, the thread is Mercuria **reporting on it**, in the third person. Never write the thread as though that person is posting it, however much of the material is their words.
80
+ When the thread rests on an interview, a session or a conversation, it **reports on it**, in the third person. Never write the thread as though the person quoted is posting it, however much of the material is their words.
86
81
 
87
- Report what they said; do not borrow the interviewer's voice. Mercuria did not run the interview, so *"they told us"* is wrong twice over — "us" is Orbitant, who is not posting, and the conversation was not Mercuria's:
82
+ Report what they said; do not borrow the interviewer's voice. *"They told us"* presumes both who ran the conversation and who is posting, and the thread knows neither:
88
83
 
89
84
  > Do: `Marta Ferrán (@martaferran), CTO at Nudoterra, spent six weeks writing definitions by hand before buying a single tool.`
90
85
  >
@@ -138,7 +133,7 @@ X surfaces this post on its own. Assume most people read only this one. **It has
138
133
  Do:
139
134
 
140
135
  - `Measured: with hexagonal architecture the agent needed 3 to 5x more context to make the same change.`
141
- - `A pipeline at @weorbitant took 22 minutes. One integration test was eating 60% of that, because it span up a real Postgres on every run.`
136
+ - `A pipeline at @WeOrbitant took 22 minutes. One integration test was eating 60% of that, because it span up a real Postgres on every run.`
142
137
  - `AI is writing malicious npm packages now, and they are harder to spot than the ones humans wrote.`
143
138
 
144
139
  Don't:
@@ -183,7 +178,7 @@ Give one post to the honest limitation — where the idea stops working. A threa
183
178
 
184
179
  **Native** — a statement that encapsulates the spine. Memorable, not a generic call to action. `Building with intention, not chaos` — not `Read more on our blog`.
185
180
 
186
- If the thread mentions `@weorbitant` at all, this is one natural place for it — but only when the closing genuinely lands on Orbitant. See *Account and voice*.
181
+ If the thread mentions `@WeOrbitant` at all, this is one natural place for it — but only when the closing genuinely lands on Orbitant. See *Account and voice*.
187
182
 
188
183
  **No engagement bait.** Not "Follow for more", not "Bookmark this", not "What do you think?", not "Agree?", not "RT if you have lived this".
189
184
 
@@ -212,7 +207,7 @@ They have lost their discovery function. The timeline surfaces content by semant
212
207
 
213
208
  Hashtag conventions from Orbitant's other channels do not carry over to X. This is deliberate — do not add them back for consistency.
214
209
 
215
- On X, Orbitant appears as **`@weorbitant`** and Mercuria posts as **`@mercuria_orb`**. Both are mentions rather than tags, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one.
210
+ On X, Orbitant appears as **`@WeOrbitant`**. It is a mention rather than a tag, and mentions do work — which is also why an interviewee's own handle is worth citing when the material gives one. Whose account the thread goes out from is a separate question and not one this file answers: see *Account and voice*.
216
211
 
217
212
  ---
218
213
 
@@ -227,7 +222,6 @@ Plain text, ready to paste into X, Typefully or n8n. No markdown in the post bod
227
222
  ```text
228
223
  THREAD — [spine in one sentence]
229
224
 
230
- Account: @mercuria_orb
231
225
  Language: [en | es]
232
226
  Source: [blog post URL | native: what it came from]
233
227
 
@@ -265,10 +259,11 @@ Verify each of these. Do not deliver a thread that fails one.
265
259
  - [ ] No markdown syntax anywhere in the post bodies
266
260
  - [ ] Exactly one link, in the closing post — or none, if native
267
261
  - [ ] The spine is a concept or principle, not a tool or a client
268
- - [ ] First person singular as Mercuria, never "we" and never a team member's "I"
269
- - [ ] Nothing in it presents Mercuria as human
270
- - [ ] `@weorbitant` appears only where Orbitant is genuinely part of what is said, or not at all
271
- - [ ] Anybody quoted who is not Mercuria is in the third person, with their handle if the material gave one
262
+ - [ ] No account stated anywhere, and nothing that only works from one of them
263
+ - [ ] No self-introduction and no sign-off, in any voice
264
+ - [ ] No "we" standing in for whoever posts (Orbitant-as-subject is fine)
265
+ - [ ] `@WeOrbitant` appears only where Orbitant is genuinely part of what is said, or not at all
266
+ - [ ] Anybody quoted is in the third person, with their handle if the material gave one
272
267
  - [ ] The thread is in English, or in Spanish because Spanish was asked for
273
268
  - [ ] No more than 10 posts, and none of them padding
274
269