@cratis/pi 2.29.0 → 2.30.0

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.
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: cratis-social-feed-post
3
+ description: Write or review a short post for a social feed such as LinkedIn, where the opening has to survive the feed's truncation, the body is plain text with no markup, and the common formatting tricks cost accessibility and reach. Use when drafting, adapting or reviewing a feed post. Do not use for documentation pages, release notes, long-form articles, or anything rendered as Markdown.
4
+ license: MIT
5
+ ---
6
+
7
+ # Social feed post
8
+
9
+ A feed post is not a short article. The feed shows a few lines and hides the rest behind a
10
+ "see more" control, so the opening is not an introduction to the point — it is the entire
11
+ advertisement for the post, and the decision to expand is itself a ranking signal.
12
+
13
+ Everything below assumes a plain-text feed with no markup rendering. The character and line
14
+ figures are unofficial approximations reported by third parties; no platform documents them,
15
+ and they move with interface, font size and device width. Treat them as a target zone and
16
+ re-check them against current official guidance rather than encoding them as durable rules.
17
+
18
+ ## The fold decides what the post is judged on
19
+
20
+ On LinkedIn the cut is modelled two ways at once and lands on whichever runs out first:
21
+
22
+ - a character budget of roughly 210 on desktop and 140 on mobile, and
23
+ - a budget of about three rendered lines.
24
+
25
+ **A blank line spends the line budget without spending characters.** A short opening on its
26
+ own line is therefore cut *earlier* than the same words inside a paragraph. Putting the hook
27
+ on its own line is usually still right, because it is what a scroller reads first, but it is
28
+ a trade rather than a free improvement.
29
+
30
+ ## What the opening must do
31
+
32
+ - **Finish a complete thought above the cut.** An opening severed mid-sentence has spent the
33
+ whole advertisement on half an idea.
34
+ - **Stay short on purpose.** A brief opening sentence is a hook doing its job. Do not rewrite
35
+ one into a longer, smoother sentence for the sake of rhythm; that removes the
36
+ advertisement. This is the most common way a well-meaning editing pass makes a post worse.
37
+ - **Earn the identifier before using it.** An opening that begins with a framework type or a
38
+ product name asks a scroller to care about a word they have no reason to recognize yet.
39
+ Name the friction first, then the mechanism.
40
+ - **Skip the throat-clearing.** The first line is the point, not a preamble to it.
41
+
42
+ Check the opening by reading only the first three lines and asking whether they are worth
43
+ expanding. If the answer depends on the fourth line, the opening is wrong.
44
+
45
+ ## Never use Unicode pseudo-formatting
46
+
47
+ Third-party tools offer pseudo-bold and pseudo-italic built from Mathematical Alphanumeric
48
+ Symbols — the characters that look like `𝗕𝗼𝗹𝗱` and `𝘐𝘵𝘢𝘭𝘪𝘤`. Do not use them.
49
+
50
+ - **Assistive technology cannot read them.** A screen-reader user hears "mathematical bold
51
+ capital T, mathematical bold small h" through an entire line, or hears nothing at all.
52
+ - **They are not the letters they resemble.** Platform search and ranking index the actual
53
+ code points, so a styled keyword is no longer that keyword and the term is lost.
54
+
55
+ Emphasis in a plain-text feed comes from sentence construction, line placement and what is
56
+ said first. A point that needs visual weight belongs in an image with its own alt text.
57
+
58
+ ## Two things that cost reach outright
59
+
60
+ - **No external link in the body.** Current ranking suppresses posts that carry one; the
61
+ convention is to put the link in a comment. Verify this at review rather than repeating it
62
+ as folklore, and never write the convention into the copy itself.
63
+ - **No engagement bait.** "Repost if…", "Tag someone who…", "Agree?" are treated as spam
64
+ signals rather than as engagement. A genuinely answerable question that follows from the
65
+ argument is a different thing and is welcome.
66
+
67
+ ## Structure that survives a phone
68
+
69
+ - One idea per post. A feed reader will not assemble two.
70
+ - Short paragraphs, one to three sentences, and visibly different from each other in length.
71
+ A column of identically sized blocks reads as a generated template before it reads as an
72
+ argument.
73
+ - Blank lines separate paragraphs and nothing else. Each one costs line budget above the fold.
74
+ - No Markdown. The feed renders none of it, so `**bold**` and `# heading` reach the reader
75
+ as literal characters.
76
+ - Hashtags on the last line only, never mid-sentence.
77
+ - Every image needs alt text. A post whose point lives only in an unlabeled image has no
78
+ point for part of its audience.
79
+
80
+ ## Before publishing
81
+
82
+ - The opening thought is complete above the fold on mobile as well as desktop.
83
+ - No pseudo-formatted characters anywhere, including the hook.
84
+ - No link in the body and no engagement bait in the close.
85
+ - Every image carries alt text, and the post still makes sense with the images removed.
86
+ - Every technical claim is one the underlying source actually supports, and any limitation
87
+ the post depends on is stated rather than implied.
88
+
89
+ ## Stop conditions
90
+
91
+ Stop and ask when the account owner, the author's perspective, the evidence behind a claim,
92
+ or an asset's permission is unresolved. Drafting a post is not authorization to publish,
93
+ schedule, tag, mention or upload it.
@@ -0,0 +1,14 @@
1
+ {
2
+ "skill": "cratis-social-feed-post",
3
+ "input": "Draft a LinkedIn post about a framework feature and format it for the feed.",
4
+ "fixtures": [],
5
+ "assertions": [
6
+ { "kind": "skill-contains", "value": "A blank line spends the line budget without spending characters" },
7
+ { "kind": "skill-contains", "value": "Never use Unicode pseudo-formatting" },
8
+ { "kind": "skill-contains", "value": "Assistive technology cannot read them" },
9
+ { "kind": "skill-contains", "value": "A brief opening sentence is a hook doing its job" },
10
+ { "kind": "skill-contains", "value": "No external link in the body" },
11
+ { "kind": "skill-contains", "value": "No engagement bait" },
12
+ { "kind": "skill-contains", "value": "unofficial approximations" }
13
+ ]
14
+ }
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: cratis-writing-voice-and-cadence
3
+ description: Find and remove the sentence constructions and structural sameness that make written material read as machine-generated, across documentation, release notes, pull request descriptions, posts and reviews, without changing any technical claim. Use when reviewing or rewriting existing prose for voice. Do not use for technical accuracy review, for original drafting, or as a reason to touch approved copy without authorization.
4
+ license: MIT
5
+ ---
6
+
7
+ # Writing voice and cadence
8
+
9
+ Material that is factually correct can still be unreadable in a way nobody can name. The
10
+ usual diagnosis is "it sounds like AI wrote it", and the usual response is to rewrite by feel,
11
+ which produces a second machine voice rather than a human one.
12
+
13
+ The failure is measurable, and it has two halves. The smaller half is a set of sentence
14
+ constructions used far past the density a person would use them. The larger half is
15
+ structural sameness across a whole body of material: a reader meeting the second piece
16
+ recognizes the format before reading a word of it.
17
+
18
+ ## The constructions
19
+
20
+ None of these is wrong. One of any of them is a good sentence. What turns them into a tell is
21
+ recurrence.
22
+
23
+ | Construction | What it looks like |
24
+ | --- | --- |
25
+ | **Corrective tail** | "…, not a fresh count." The sentence ends by correcting itself |
26
+ | **Balanced semicolon** | Two clauses of equal weight either side of a semicolon |
27
+ | **"rather than"** | The same correction carried by a different connective |
28
+ | **Em-dash pivot** | The dash used to swing into a closing clause |
29
+ | **"That is what X is for"** | A pointer sentence standing in for an explanation |
30
+
31
+ To measure rather than guess, count them. Searching for `, not a`, `; ` between two clauses,
32
+ `rather than`, and an em-dash followed by a short closing clause takes a few minutes across a
33
+ directory and turns an argument about taste into a number. Reading a draft aloud catches all
34
+ of them faster than any tool.
35
+
36
+ ## Structural sameness is the more damaging half
37
+
38
+ Look at ten pieces together, not one at a time:
39
+
40
+ - **Every piece the same length and shape.** If most of them are three or four paragraphs
41
+ with the same paragraph weights, that is a template.
42
+ The fix for a template is not a better template.
43
+ Do not adopt a target shape: vary the paragraph count, and let paragraphs differ visibly
44
+ in weight.
45
+ - **Every sentence the same length.** When sentence length barely varies within a piece, the
46
+ result is a monotone regardless of the words. Let it swing between four words and twenty-five.
47
+ - **Every piece opening the same way.** An abstract noun phrase making a declarative
48
+ assertion — "A screen that needs…", "A registration test can…" — is one move. Alternate it
49
+ with a question, a direct address, a concrete moment, or a number.
50
+
51
+ ## Address somebody
52
+
53
+ - **Say "you".** Material that tells a reader what to do should address that reader.
54
+ - **Attributed writing should sound attributed.** Prose published under a person's name and
55
+ written entirely in the impersonal third person reads as documentation wearing a byline.
56
+ Opinion, judgement and preference belong to the named author and are theirs to give.
57
+ - **First person is not a licence to invent.** Opinion is allowed; invented experience,
58
+ anecdotes that did not happen, and claimed observations the author did not make are not.
59
+ Where a named author owns the material, it stays blocked until that author reviews it.
60
+ - **A question is allowed when the piece has earned it.** A question that follows from the
61
+ argument is not bait; one bolted on to harvest a response is.
62
+
63
+ ## Never trade a claim for a smoother sentence
64
+
65
+ This is the part that makes a voice pass dangerous, and it is the reason to do one carefully
66
+ rather than quickly.
67
+
68
+ The risk is not an obvious rewrite. It is a hedge dissolving into nicer phrasing. "There is
69
+ no need to" becomes "without needing to", and a limit quietly widens. "Not its meaning"
70
+ becomes "and leaves its meaning alone", and a distinction softens. Both read better. Both
71
+ changed what the text asserts.
72
+
73
+ Before accepting any rewrite, confirm that:
74
+
75
+ - every identifier and every number present before is still present, and none was invented;
76
+ - every hedging word — not, never, only, may, unless, until — survives in substance;
77
+ - every stated limitation survives, including one that reads as an awkward caveat, because it
78
+ is a caveat and it is deliberate;
79
+ - the closing limitation or evidence statement is not thinned, relocated into a subordinate
80
+ clause, or dropped because it spoiled the ending.
81
+
82
+ A mechanical check over identifiers, numbers and hedge counts catches most of this before a
83
+ human reads a word, and is worth writing once for any corpus large enough to need a pass.
84
+
85
+ ## Work in tranches that can be read
86
+
87
+ Rewriting is not a batch operation. Any body of material large enough to have a detectable
88
+ voice is too large to rewrite in one pass with judgement, and a fast pass replaces one
89
+ detectable format with another. Rewrite a tranche, read it, and only then continue.
90
+
91
+ Where material carries a recorded approval, a rewrite invalidates it. Recording a fresh
92
+ approval over copy nobody has read makes the record assert something false, after which every
93
+ downstream check agrees with it. Size the tranche to what its owner will actually read.
94
+
95
+ ## Stop conditions
96
+
97
+ Stop when a rewrite would change what the material claims, when the named author has not
98
+ accepted a perspective being introduced on their behalf, or when the material is under an
99
+ approval that the rewrite would invalidate without authorization to refresh it.
@@ -0,0 +1,13 @@
1
+ {
2
+ "skill": "cratis-writing-voice-and-cadence",
3
+ "input": "This documentation reads like it was generated. Make it sound human without changing what it says.",
4
+ "fixtures": [],
5
+ "assertions": [
6
+ { "kind": "skill-contains", "value": "Never trade a claim for a smoother sentence" },
7
+ { "kind": "skill-contains", "value": "The fix for a template is not a better template" },
8
+ { "kind": "skill-contains", "value": "every hedging word" },
9
+ { "kind": "skill-contains", "value": "First person is not a licence to invent" },
10
+ { "kind": "skill-contains", "value": "Structural sameness is the more damaging half" },
11
+ { "kind": "skill-contains", "value": "Rewrite a tranche, read it, and only then continue" }
12
+ ]
13
+ }
@@ -43,6 +43,7 @@
43
43
  "cratis/cli",
44
44
  "cratis/cli/terminal-workbench",
45
45
  "cratis/components",
46
+ "cratis/content",
46
47
  "cratis/documentation",
47
48
  "cratis/full",
48
49
  "cratis/full/csharp",
@@ -559,10 +560,22 @@
559
560
  "typescript"
560
561
  ]
561
562
  },
563
+ {
564
+ "id": "cratis/content",
565
+ "availableTargets": [
566
+ "cratis-social-feed-post",
567
+ "cratis-writing-voice-and-cadence"
568
+ ],
569
+ "languages": [
570
+ "markdown",
571
+ "language-agnostic"
572
+ ]
573
+ },
562
574
  {
563
575
  "id": "cratis/documentation",
564
576
  "availableTargets": [
565
- "cratis-documentation-writing"
577
+ "cratis-documentation-writing",
578
+ "cratis-writing-voice-and-cadence"
566
579
  ],
567
580
  "languages": [
568
581
  "markdown",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "2.29.0",
3
+ "version": "2.30.0",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [