Reset version declarations to v0.4.0 across plugin.json, README badge + version-history, CLAUDE.md header, and the root marketplace README entry. The 1.0.0–4.1.0 numbering reflected ambition, not maturity: user data still lives inside the plugin tree (.gitignore-defended), no command has passed the hardening quality-gate, command testing is incomplete, and there is no GUI. A deliberate marketplace downgrade (existing installs will not auto-pull a lower number). Path to v1.0.0 = architecture (M0 per-user data-dir migration) + hardening + command testing + GUI. No functionality changed — only version declarations; all prior changelog/history preserved. Lint green (Passed 74 / Failed 0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.0] - 2026-05-31
Re-baselined
Honest version reset: 4.1.0 → 0.4.0. The project was previously numbered 1.0.0–4.1.0, but those were pre-release iterations. The honest maturity is v0.4.0: user data still lives inside the plugin tree (defended only by .gitignore), no command has yet passed the hardening quality-gate, command testing is incomplete, and there is no GUI. This is a deliberate marketplace downgrade — existing installs will not auto-pull a lower number. The path to v1.0.0 is four workstreams: architecture (move all user data out of the plugin into a per-user data dir — the M0 migration), hardening (every command through the quality-gate), command testing (each command run against real/isolated ground truth), and a GUI.
Changed
- Version declarations reset to
0.4.0across.claude-plugin/plugin.json,README.md(badge + version-history),CLAUDE.md(header), and the root marketplaceREADME.mdentry. No functionality changed — no code, command, agent, hook, or state-shape change. All prior changelog entries below are preserved as the development history.
[4.1.0] - 2026-05-30
Summary
Journey layer over the command surface (Voyage S14). Step 14a's cold, independent command-rationalization (docs/remediation/command-rationalization.md) audited all 27 commands under the same subsumption discipline as the agent-overlap study and found zero redundancy — the surface was over-grown in count, not in duplication (the two prior consolidations already removed the genuine overlaps). So instead of cutting, this release organizes: the 27 atomic commands are kept as the execution tier, and a journey layer is added on top. Additive and minor — no command removed, renamed, or behavior-changed; the two new commands register on reload. Design contract: docs/remediation/journey-layer-design.md.
Added
/linkedin:create— Create front-door. One guided "what do you want to make?" entry that routes to the command owning the format (post/quick/react/carousel/video/multiplatform/batch/newsletter). Delegates only — no drafting logic of its own./linkedin:measure— Measure front-door. One guided "how am I doing?" entry that routes to the right analytics command (import/report/analyze/audit/ab-test). Delegates only. Commands 27 → 29.
Changed
- Router re-tiered into five journeys (
commands/linkedin.md) — Start · Create · Engage · Measure · Grow, each headed by a front-door (onboarding/strategyelevated as the Start/Grow front-doors;create/measurenew; Engage is acalendar+firsthourrelay), with the atomic commands nested as the execution tier. Absorbs the planned router-tiering UX step. - Honesty nits from 14a fixed — the router now lists
/linkedin:firsthour(was agent-only under Post-Publish);calendar's publish-action first-hour block cross-links to/linkedin:firsthourfor the full worked sprint plan. EXPECT_COMMANDSinscripts/test-runner.sh27 → 29; CLAUDE.md / README rosters + counts updated in lockstep.
Fixed
- 14a deliverable correction — the cold review's first pass omitted
multiplatform(covered 26/27) and raised acompetitive1K-gating inconsistency that did not survive verification (CLAUDE.md:64, README:222, the router, and the command body all leavecompetitiveungated). Both corrected incommand-rationalization.md; net finding unchanged (keep 27, 0 merge, 0 cut).
Compatibility
- Minor / additive. No command removed, renamed, or behavior-changed; the 27 existing commands, all 19 agents, and all state shapes are unchanged. The two new commands (
create,measure) register when the plugin command set is rebuilt at session start — reload required to see them.
Added — within 4.1.0 (refinement sessions, no surface/count/version change)
- Manual per-post saves in analytics (Voyage S16). Lifts the original v4.0.0 Non-Goal:
PostMetricsgains an optionalsavesfield, ingested when the user adds aSavescolumn to the CSV with the count read off native LinkedIn post analytics (count-only, ~Sept 2025; absent from the export, no self-serve API). The parser (scripts/analytics/src/parsers/csv-parser.ts) reads it when present; weekly/monthly summaries gain an optionaltotalSaves; the CLI (import/report) surfaces saves per-post and as a total. Backward-compatible — a missing column or blank cell leaves saves unknown (never coerced to 0), saves is not folded intoengagementRate(which stays comparable to older imports), and saves-free data round-trips byte-identical. Dwell stays explicitly unmeasurable — no dwell field or surface was added. This refines the v4.0.0 "the plugin cannot read those signals" wording: the plugin still cannot auto-track saves, but it now ingests a manually-entered count. Built location-agnostically through the existinggetAnalyticsRoot()seam so the planned data-dir migration (UI brief §9b/M0) relocates it in one place. NewRankableMetrictype fixes the trend/alert index access that the optional field would otherwise widen tonumber | undefined. - Onboarding tool-grant fix (S16-pre).
commands/onboarding.mdPhase 2 saves voice/user-profile files but its frontmatter omittedWrite; addedWritetoallowed-tools(matchingfirst-post.md). Closes a pre-existing tool-contract gap surfaced by the S15 review.
[4.0.0] - 2026-05-30
Summary
Audit-remediation release (Voyage Phase 0–3). A critical self-review (docs/critical-review-2026-05-29.local.md) found the plugin had drifted in three ways: (1) overclaiming — surfaces promised tracking, analytics, and review independence the plugin could not actually deliver; (2) dormant capability — eleven agents shipped in agents/ were never invoked by any command; (3) structural rot — the structure lint validated a layout the plugin had outgrown, an algorithm-signal claim contradicted itself across files, and an unpublishable model brand/date was baked into user-facing copy. This release is the systematic fix: every claim is made honest or removed, every orphan agent is wired, and the lint is rebuilt to guard the real layout plus version/count/stat consistency. Major version marks the scope of the remediation (every user-facing claim re-examined) and the reinstall/reload required for the newly-wired agents to register; it consolidates — but does not repeat — the v3.0.0 identity break (slug, agent namespace, state-file path). No content-pipeline behavior is removed; the short-form and long-form engines are unchanged except where a gate was added.
Added
/linkedin:firsthour— post-publish first-hour / reply-loop sprint command wiring the previously-orphanedengagement-coachagent: a timestamped target list, draft comments, and a timeline, persisted to state (recordFirstHourPlan), handing off topost-feedback-monitor. Commands 26 → 27.- All 11 orphaned agents wired (case-by-case: 9 in the wiring pass, 2 via the new gates/command) — the agent set is now fully reachable from a command, with no deletions. Agents stay 19.
- Short-form de-AI gate — the short-form content commands run
differentiation-checker+ the voice-guardian before output, the short-form mirror of the long-form de-AI discipline. - Video quality gate —
/linkedin:videoenforces captions + aspect-ratio guidance (4:5 / 1:1 + captions) and drops the hard 9:16 mandate. - Version-consistency grep in the structure lint (
scripts/test-runner.sh) — theplugin.jsonversion must match the README badge, the pluginCLAUDE.mdheader, and the CHANGELOG top entry; theplugin.jsondescription is now also covered by the algorithm-stat-consistency scan.
Changed
- Structure lint rebuilt (
scripts/test-runner.sh) — dynamic registration counts derived fromls(agents/commands/refs/skills), frontmatter shape, hook-drift (compile-hooks.py --check), and an algorithm-stat-consistency grep that forbids the unpublishable model brand/date and competing magnitudes from returning. Replaces a dead validator that asserted an outgrown layout. - Algorithm signals reconciled to one sourced statement —
references/algorithm-signals-reference.mdis the single source of truth (per-claim Source + Confidence); every citer cites rather than restates. The 2026 relevance-ranking model is referenced without a name or a date (the unpublishable brand/date removed everywhere, including the root README and the marketplace manifest). post-feedback-monitorpromoted to Opus (Opus-default for human-facing reasoning).- Newsletter distribution, profile-SEO, and outreach surfaces made honest — they describe what the plugin produces (drafts, recommendations, queues) versus what the operator does manually, with no implied automation.
- Long-form review language is configurable; render output de-branded; series path parameterized (no hard-coded author or series).
- Counts reconciled to the
ls-derived source of truth: 27 commands · 19 agents · 6 skills · 9 hooks · 25 reference docs · 16 newsletter phases. README badges + intro, root README, and the marketplace catalog brought into sync. - Long-form review-pass overlap measured (
docs/remediation/overlap-measurement.md) across the seven long-form review gates against in-repo fixtures: every gate has ≥ 1 unique catch and the real overlaps are justified → no gate trimmed (the review stack stays seven).
Fixed
- Analytics CLI fresh-clone crash —
report.md/import.mdsurface thenpm installat point-of-use, andgetAnalyticsRoot()is anchored on the.claude-plugin/plugin.jsonmarker instead of a build-layout-relative depth (latent correctness bug). - No false metric claims — saves/dwell wording is honest (the plugin cannot read those signals), and the A/B significance claim is downgraded to directional.
Security / Privacy
- Voice-profile leak closed — the tracked
authentic-voice-samples.mdis now a PII-free placeholder carrying a<!-- VOICE_PLACEHOLDER -->sentinel; the author's real profile moved to a gitignored.local.md;personalization-score.mjsscores the placeholder 0 voice points via the sentinel (both voice writers replace-not-append). The author name is scrubbed fromplugin.json(theLICENSEMIT copyright holder is the intentional exception). Per a documented decision, git history is not rewritten — the historical voice file is attributed open-source authorship, not a leaked secret.
Compatibility
- Breaking — reinstall / reload required. The eleven newly-wired agents register only when the plugin agent set is rebuilt at session start; the v3.0.0 slug / agent-namespace (
linkedin-studio:<agent>) / state-path (~/.claude/linkedin-studio.local.md) break is consolidated here. Existing editions and analytics data are unaffected (state shapes are additive; posts/streak/history preserved). The/linkedin:*command namespace is unchanged.
[3.1.0] - 2026-05-29
Summary
An adversarial review package becomes part of the long-form pipeline (Endring 9). The Del 4 production run (Maskinrommet, 2026-05-29 — the Security Champions pivot, v8 → v11) shipped a high-quality article, but its quality assurance leaned on one good editor + KTG's availability to read it several times — it did not scale. The root cause: the editor and the persona sweep ran in the same session as drafting, sharing the conversation history (which versions passed, what was deliberately cut, which flags had been raised). They were therefore not adversarial — they carried framing-bias. Three concrete symptoms: (1) the persona resonance sweep effectively judged an early version, not the one that shipped; (2) editor-approval was single-source; (3) the fact-check was post-hoc relative to the late pivot, so the pivot could build on an unverified premise. v3.1.0 answers KTG's explicit question — how do I start sessions with no context from the main session, to review both content and language? — and makes per-artifact personas a first-class input.
Added
/linkedin:headless-reviewcommand — runs the cold adversarial review package on a FROZEN draft. Designed to be invoked in a fresh session for maximum isolation (the parent then has no drafting transcript); reconstructs everything from disk (frozen draft + writing contract + personas). Flags--draft,--type {content|language|fact|persona-resonance|persona-conversion|all},--persona,--article,--output.- Three new headless review archetypes (all Opus, each with an explicit cardinal context-isolation block that refuses drafting-session framing as "context pollution"):
content-reviewer(color maroon, Read+Grep) — argument integrity: C1 logical holes · C2 unsupported assumptions · C3 argument-level contradiction · C4 missing concretization · C5 unanswered «what about X?». ≤8 flags BLOCK/REWORK/NICE.language-reviewer(navy, Read+Grep) — Norwegian language: L1 verbatim repetition · L2 anglicisms · L3 stiff bureaucratic register · L4 language-level self-contradiction · L5 clang/rhythm. ≤10 flags. Deliberate cold re-take ofeditorial-reviewer's prose axis.fact-reviewer(gold, Read+WebSearch) — cold re-verification on the frozen/pivoted version: F1 verifiable claims · F2 quote precision · F3 number attribution · F4 source quality. Carries overfact-checker's 5-dimension scoring + 🔴/🟡/🟢 sort + contradiction sweep + post-cutoff mandate, adds a pivot-risk subsection. Deliberate redundancy withfact-checkerto catch a pivot premise that arrived after Step 5.
- Step 6.5 (headless-review) in
/linkedin:newsletter— fans the package out in parallel after the in-session persona sweep (Step 6), on a frozen draft snapshot, BEFORE lock; consolidated report surfaced viaSendUserFile; converged flags (two independent cold reviewers agreeing) marked as the strongest signal. Pipeline 15 → 16 phases. /linkedin:pivotcommand + pivot-detection gate — a pivot re-opens the pipeline so the cleared gates (fact-check 5 → editorial 5.5 → persona 6 → headless 6.5) re-run on the changed version before lock. Heuristic: a draft that drifted > 20 % in word count OR gained > 2 sections since Step 6 cleared triggers the gate (enforced as a Step 8 lock precondition). Worked example: the Del 4 v8→v11 run (+42 %, 2 new sections) would have fired the gate and forced the re-sweep.- Per-artifact personas —
articles.NN.personasinedition-state.json: one or more readers configurable per edition, resolved in Step 1 in order (edition-state →<serie>/linkedin/personas.mdper-series file → pluginpersonas.local.md/template → interactive definition). Feeds both the Step 6 sweep and the Step 6.5 package.config/personas.template.mddocuments the resolution order. - Three fasit fixtures + three structural lint tests for the new agents (Del 4 / Security Champions worked cases), mirroring the
editorial-reviewerfixture discipline. All 35 agent-fixture assertions green.
Changed
config/edition-state.template.json— additive: per-articlepersonas[],pivots[],headlessReviewobject; newheadless-reviewphase string (16 phases total);personaSweep.resonance.wordCountrecorded at Step 6 as the pivot-detection baseline.commands/newsletter.md— Step 0/1 persona resolution reworked to per-artifact; new Step 6.5; Step 8 lock preconditions add the headless gate + pivot-detection gate; pipeline + resumption tables updated (persona-sweep-prelock→ resume at Step 6.5; newheadless-review→ Step 7).- Counts: 24 → 26 commands; 16 → 19 agents; 15 → 16 newsletter phases.
Compatibility
Backward-compatible: every state-shape change is additive (existing editions resume by currentPhase; persona-sweep-prelock now resumes at Step 6.5 — an intended deterministic improvement). Reload required before the three new agents resolve (the plugin agent set is built at session start). No new runtime code beyond the agents/commands/fixtures; the render pipeline, hooks, and short-form surface are untouched.
[3.0.0] - 2026-05-29
Summary
Plugin renamed linkedin-thought-leadership → linkedin-studio ("LinkedIn Thought Leadership" → LinkedIn Studio). The old display title read as pompous; the new name is plain and matches how the plugin already describes itself ("LinkedIn content engine"). This is a breaking change — the marketplace slug, the agent namespace (linkedin-studio:<agent>), and the runtime state-file path all change — so it bumps to a major version. Functionality is byte-for-byte identical to v2.4.0; this release is pure identity.
Changed (breaking)
- Slug / directory / manifests:
plugins/linkedin-thought-leadership/→plugins/linkedin-studio/;plugin.jsonand rootmarketplace.jsonname/sourceupdated. Reinstall required. - Agent namespace: commands invoke plugin agents as
linkedin-studio:<name>(waslinkedin-thought-leadership:<name>). Functional change incommands/newsletter.md; docs updated to match. - Runtime state path:
~/.claude/linkedin-thought-leadership.local.md→~/.claude/linkedin-studio.local.md. Hardcoded inhooks/scripts/{state-updater,session-start,posting-reminder,user-prompt-context}.mjs,hooks/prompts/topic-rotation-gate.md, andconfig/state-file.template.md. Existing state migrated in place (post metrics, streak, content history preserved). - Catch-all skill
skills/linkedin-thought-leadership/→skills/linkedin-studio/(frontmattername: linkedin-studio); the five functional skills (linkedin-analytics,-content-creation,-networking,-strategy,-voice) are unchanged.
Not changed (explicit non-deltas)
- Command namespace
/linkedin:*— set per-command in frontmatter (name: linkedin:post), already independent of the plugin slug. Every command (/linkedin:post,/linkedin:newsletter, …) is invoked exactly as before. 24 commands, 16 agents — counts unchanged. - All hooks, scripts, renderers, agent contracts, content — bit-for-bit identical to v2.4.0.
- History preserved:
config-auditv5.0.0 test snapshots and thedocs/build artifacts retain the old slug as point-in-time records and were intentionally not rewritten.
[2.4.0] - 2026-05-29
Summary
An editor's craft gate becomes an explicit pipeline phase in /linkedin:newsletter. The Del 4 production run (Maskinrommet, 2026-05-28) exposed a gap: the persona resonance sweep returned 15 flags across three personas and every persona reported PASS / ready-to-publish — yet the editor (KTG) found eight fresh editorial points on first reading, and only ~25 % overlapped anything the personas had touched. The other six — a missing theory anchor (SDT), a broken series-title link, a stranded small-business addressee, verbatim repetitions, em-dash over-density, an internal contradiction — were craft and narrative-architecture blind spots no agent measured. persona-reviewer measures reader response (does it land?); it does not measure prose craft or narrative architecture (is it well-made?). Two different roles; only one existed. A persona PASS was mis-reporting "ready for the editor's reading", costing an extra editorial round per article. v2.4.0 adds Step 5.5 — Editorial review, between fact-check (Step 5) and the persona sweep (Step 6), and a new editorial-reviewer agent (Opus) that mirrors the Maskinrommet writing-contract §C2. Pipeline 14 → 15 phases; 15 → 16 agents. Backward-compatible: the only state-shape change is additive (editorialReview), and existing editions resume by currentPhase (factcheck-sweep now resumes at Step 5.5 instead of Step 6 — an intended deterministic improvement). Doc/orchestration-only for the pipeline wiring; the new agent + its fasit fixture + structural lint test are the only new files.
Added
agents/editorial-reviewer.md(new, Opus, orange) — an editor, not a reader. Judges two axes: prosa-håndverk (P1 em-dash density · P2 verbatim repetition · P3 postulated numbers without source/hedge · P4 internal contradiction · P5 versal-tic — mostly grep-able) and narrativ-arkitektur (A1 concrete instantiation · A2 theory-anchored hypotheses · A3 series-title symmetry · A4 equally-usable action per addressee · A5 un-overloaded conclusion — evaluative). Returns ≤10 flags as direction (never rewritten copy — the jury judges, the writer writes), each with a quote/line-ref and a severity: BLOCK / REWORK / NICE. ToolsRead+Grep. The checklist is the operationalized mirror of the Maskinrommet skrivekontrakt §C2 (bidirectional mirror rule: §C2 is the source of truth). New agent — requires a session reload before it is invokable.- Step 5.5 — Editorial review in
commands/newsletter.md, between Step 5 (fact-check) and Step 6 (persona sweep). Runs a single foregroundeditorial-reviewerTaskcall, writes the report to<serie>/NN-editorial-review.md, surfaces it to the operator viaSendUserFile(the Endring-5 / Step-7.5 operator-gate pattern), folds approved flags in by tightening (rule 6) → v(n+1), and optionally re-runs the agent on the cleaned version. Why before the persona sweep: the personas measure response — if the prose is locally messy the persona flags become noise; clean the craft first so Step 6 measures what it was built to measure. editorial-reviewphase string +articles.NN.editorialReviewschema +_doc.editorialReviewnote inconfig/edition-state.template.json_doc.phases(14 → 15 phases). Additive;editorialReview: nulluntil Step 5.5 runs. The craft companion tofactcheckLog(truth) andpersonaSweep(response).agents/fixtures/editorial-reviewer-cases.md(new) — fasit fixture: the Del 4 v5 gold standard. KTG's eight editorial points mapped to the two axes + severities (3 BLOCK / 5 REWORK), with the persona-overlap column showing 6/8 were editorial-only blind spots. The calibration target for acceptance-criterion #8 (a live run needs a session reload + Maskinrommet read access; until then the fixture is the gold-standard of record).agents/__tests__/editorial-reviewer-fixture.test.mjs(new) — structural lint mirroring the persona-reviewer / fact-checker fixture tests: asserts both axes, all ten checks (P1–P5 + A1–A5), the three severities, the eight Del 4 cases, the §C2 tie, the direction-not-copy boundary, and the blind-spot rationale. 7 tests, green.
Changed
/linkedin:newsletterpipeline overview — 14 → 15 phases; the overview table, build-status note, and reference-file list reflect Step 5.5.- Resumption table in
commands/newsletter.md—currentPhase: "factcheck-sweep"now resumes at Step 5.5 (was Step 6); neweditorial-reviewrow resumes at Step 6. (Spec saidcurrentPhase: "fact-check"; the canonical key in this plugin isfactcheck-sweep— wired to the real key.) - Step 5 hand-off + ordering note — fact-check now hands off to Step 5.5; the BEFORE-lock note names editorial review (5.5) and the persona sweep (6) as the two gates the fact-check precedes.
- Step 6 intro — now reads on the "editorially-cleaned, fact-checked draft"; the persona sweep judges response, not craft (that was 5.5).
- README, CLAUDE.md, root README, root CLAUDE.md, plugin.json version + descriptions.
Not changed (explicit non-deltas)
persona-reviewercontract — bit-for-bit unchanged. Editorial review is supplementary: one agent measures craft (5.5), one measures response (6). The role boundary is sharp —editorial-reviewernever flags "this won't resonate",persona-reviewernever flags em-dash density.- Steps 0–5, 6 body, 7, 7.5, 8–10 — contract unchanged apart from the Step 5→5.5→6 wiring and the Step 6 intro line.
- Renderers, hooks, scripts, command count (24) — all unchanged. No new
.mjsruntime code (the only new code is the fixture lint test).
[2.3.0] - 2026-05-28
Summary
Visual assets become an explicit pipeline phase in /linkedin:newsletter. Until now images (cover + inline figures) were produced ad-hoc outside the 13-phase pipeline and referenced manually from edition-config.json + linkedin/NN/cover.png — even though a cover is mandatory (KTG cover-directive 27.05: «TLDR on top + at least one figure per article») and must coordinate with the text. v2.3.0 adds Step 7.5 — Visual assets, between annotation (Step 7) and lock (Step 8), so the cover is generated, operator-gated, and approved before lock — render/build-linkedin.mjs picks up linkedin/NN/cover.png at lock, so generating images after lock would force a re-render and break the lock. Pipeline 13 → 14 phases. Doc/orchestration-only — no new code; mcp-image is the default generation route but the interface stays pluggable (external cover-raw.png accepted), and the carousel branch reuses the existing render/build-carousel.mjs. Backward-compatible: the only state-shape change is additive (visualAssets), and existing editions resume by currentPhase (annotation now resumes at Step 7.5 instead of Step 8 — an intended deterministic improvement).
Added
- Step 7.5 — Visual assets in
commands/newsletter.md(between Step 7 annotation and Step 8 lock). Decides image needs from the article type (method-heavy → 1–2 inline figures, diagnosis-heavy → cover only), writes a per-image brief, generates via two routes (defaultmcp__mcp-image__generate_image→cover-v<N>-kandidat.png; external →cover-raw.png), runs the operator-gate (candidates surfaced viaSendUserFile, approval copied to the fixedcover.pngname — the same render+annotate pattern as Steps 2.5/3a), and records credit + caption. Explicit carousel branch (format: "carousel"): render the deck viarender/build-carousel.mjsinstead of cover+inline. visual-assetsphase string +articles.NN.visualAssetsschema inconfig/edition-state.template.json_doc.phases(13 → 14 phases) —{ format, cover: { brief, route, candidates[], approved, status }, figures: [ { id, brief, placement, status } ], carousel }. Additive; defaultformat: "standard".config/image-credit-caption.template.md(new) — cover motif + credit + caption table, modelled on the established Seres-serienimage-credit-caption.md. Honest-about-AI credit per the verification duty; documents the cover/figure naming convention.- Naming convention documented in
commands/newsletter.mdStep 7.5 —cover.png(approved, fixed) /cover-v<N>-kandidat.png(attempts) /cover-raw.png(external pre-edit source) /fig<N>.png(inline). Consistent with existing series use.
Changed
/linkedin:newsletterpipeline overview — 13 → 14 phases; the overview table, build-status note, and reference-file list reflect Step 7.5.- Resumption table in
commands/newsletter.md—currentPhase: "annotation"now resumes at Step 7.5 (was Step 8); newvisual-assetsrow resumes at Step 8.persona-sweep-prelockflows Step 7 → Step 7.5. - Step 8 lock preconditions now require the gated
visualAssets(approvedcover.pngforstandardformat, or approvedcarousel.pdfforcarouselformat) alongside the existing fact-check (no open 🔴) and primær-JA gates. - README, CLAUDE.md, root README, root CLAUDE.md, plugin.json version + descriptions.
Not changed (explicit non-deltas)
- Steps 0–7, 8 body, 9, 10 in
/linkedin:newsletter— contract unchanged apart from the Step 7→7.5→8 wiring and the additive Step 8 precondition. - Renderers —
render/build-linkedin.mjs,build-html.mjs,build-carousel.mjsuntouched (Step 7.5 calls them; no code change).build-linkedin.mjsstill readscover.pngby fixed name and does not embedfig<N>.png(figures are referenced in the draft and uploaded manually) — Step 7.5 documents this actual behavior rather than overstating it. - Hooks, scripts, command count (24), agent count (15) — all unchanged.
[2.2.0] - 2026-05-28
Summary
Longform gates hardened with the lessons from the second /linkedin:newsletter production run (Seres-serien). A chronicle built as a model/name catalog passed persona review (its flags were read as notes, not stop-signs) and nearly shipped; the rewrite was stronger but introduced fresh factual errors. v2.2.0 closes six concrete weaknesses: the persona gate becomes blocking with an explicit hard-fail list, fact-check is made orthogonal to narrative strength (more polish → more verification) with a post-cutoff web-search mandate, a new Norwegian-chronicle de-AI voice-scrubber is added and wired into Step 4, operator gates become render+annotate rounds, and per-edition production state is reconciled with the global STATE.md continuity system (no more edition-HANDOVER.md). 14 → 15 agents; commands unchanged (24). Backward-compatible — the only state-shape change is additive.
Added
agents/voice-scrubber.md(new, Opus) — aggressive de-AI scrubber + voice-drift corrector for long-form Norwegian chronicle drafts. Pass 1 strips objective AI-tells («la meg være ærlig», reflex rule-of-three, em-dash-spam, self-referential overhead, modell-/navne-katalog); Pass 2 corrects drift toward the chronicle voice; Pass 3 appends to a chronicle-voice-drift-log so it sharpens over editions. Calibration rule (cardinal): gold standard = the approved Norwegian editions, NEVERassets/voice-samples/authentic-voice-samples.md(English short-form, forbids the em-dash). New agent — requires a session reload before it is invokable.- De-AI / voice scrub sub-pass in
commands/newsletter.mdStep 4 — fans outvoice-scrubber(foreground, namespaced) with the draft + approved-Norwegian-edition paths as the gold standard. - Blocking hard-fail list in
agents/persona-reviewer.md+config/personas.template.md— primær «mistet meg» / doesn't own the action / sjargong-mur / modell-/navne-katalog → BLOCK regardless of other axes. «JA med store forbehold» = NEI. - Post-cutoff fact-check mandate + high-frequency-error checklist in
agents/fact-checker.md— claims dated after the model's knowledge cutoff MUST be web-searched; explicit checks for person titles, org-varying "standards", over-credited studies, source scope, and founding/release years. Fact-check declared orthogonal to narrative strength. - Render+annotate operator gates in
commands/newsletter.mdSteps 2.5 + 3a — HTML annotation viarender/build-html.mjs→file://link is the primary operator-review flow;AskUserQuestionbecomes a receipt + fallback. - Avoid-patterns — modell-/navne-katalog, completeness-over-reader-action, self-referential overhead openings added to
references/longform-quality-rules.md(rules 1 + 3) andconfig/user-profile.template.md. personaSweep.skeleton+immutableRulesfields inconfig/edition-state.template.json(additive).
Changed
- Edition production state reconciled with STATE.md (ONE-system).
commands/newsletter.mdStep 0 now reads<serie>/STATE.md(auto-injected by the session-start hook); every phase writes narrative status to<serie>/STATE.md(overwrite) and machine state (fact-check log, persona verdicts, immutable rules) toedition-state.json. AllHANDOVER §4/§5/§6references replaced. agents/fact-checker.mdprinciple 3 strengthened to make web search mandatory for post-cutoff claims.- README, CLAUDE.md, root README, plugin.json version + descriptions.
Removed
config/edition-HANDOVER.template.md— deleted. The plugin no longer ships or requires a separate handover mechanism;<serie>/STATE.md+edition-state.jsoncarry its content per the global continuity rule.
[2.1.0] - 2026-05-28
Summary
Skeleton gate before prose in /linkedin:newsletter. Two new pipeline phases (Step 2.5 — Skeleton + section pitch; Step 3a — Spine prose) split the old Step 3 into pre-prose / spine-prose / full-prose stages, each with an operator-gate. Adds a third persona-reviewer mode (skjelett) that judges the five-line skeleton + section pitches BEFORE prose is written. Empirically motivated by the Seres-serien Del 3 + Del 4 production: spine errors caught post-prose cost ~1 day; the same error caught at the skeleton stage costs 5–15 minutes. Backward-compatible: existing editions stop at currentPhase: "research" and now resume at Step 2.5 instead of Step 3 — an intended deterministic improvement, never a contract break.
Added
- Step 2.5 — Skeleton + section pitch in
commands/newsletter.md. Writes<serie>/NN-skjelett.mdwith the five-line spine (premiss / problem / anbefaling / gevinst / vei videre) + one-line section pitches. Operator-gate (JA / REVIDER / NEI) AND parallel persona-skjelett-sweep must both return JA before the pipeline advances. Encodes the Maskinrommet writing-contract §A discipline into the pipeline itself. - Step 3a — Spine prose in
commands/newsletter.md. One paragraph per section against the gated skeleton, ~20–30 % of final edition length. Operator-gate on whether the axis lands now that there is prose on it. Cheap second checkpoint before full expansion. - Step 3b — Full prose expansion in
commands/newsletter.md. Splits the old Step 3 (Draft) into spine prose (3a) and full prose expansion (3b). 3b owns the existing draft-cursor logic for multi-session expansion; 3a is short enough to restart on interruption. persona-reviewerskjelett-mode (third mode alongsideresonansandkonverter). Five spine axes (Premiss / Problem / Anbefaling / Gevinst / Vei videre) scored HOLDER / TVILER / MANGLER, ≤3 direction-only flags, per-pitch section-pay-in check, gate ladder PASS / REWORK / BLOCK. Caller passesmode: skjelett.skeleton-pitch+spine-prosephase strings inconfig/edition-state.template.json_doc.phases— 11 → 13 phases. Resumption table incommands/newsletter.mdextended with deterministic rows for both new phases.- Rule 8 — Skjelett før prosa in
references/longform-quality-rules.md. Documents the skeleton-before-prose pre-condition that all other rules implicitly rely on, with the same five-slot format the pipeline enforces.
Changed
/linkedin:newsletterpipeline overview — 11 → 13 phases; pipeline tables incommands/newsletter.mdandCLAUDE.mdreflect the new ordering (0, 1, 2, 2.5, 3a, 3b, 4–10).- Resumption table in
commands/newsletter.md—currentPhase: "research"now resumes at Step 2.5 (was Step 3). Two new rows added forskeleton-pitch(→ Step 3a) andspine-prose(→ Step 3b). Draft-cursor note clarifies that the cursor applies only to Step 3b. agents/persona-reviewer.mddescription, principles, and anti-patterns — extended to cover the third mode (skjelett). Existing resonans + konverter modes unchanged in contract.CLAUDE.mdheader + persona-reviewer row + newsletter command row — reflect v2.1.0 surface.
Not changed (explicit non-deltas)
- Step 1, Step 2, Steps 4–10 in
/linkedin:newsletter— bit-for-bit unchanged in contract. - Renderers —
render/build-html.mjsandrender/build-linkedin.mjsuntouched; both still consumeNN-utkast.md(3a writes the spine state, 3b overwrites with the full state, but onlycurrentPhase: "draft"triggers rendering). - Hooks, scripts, command count (24), agent count (14) — all unchanged.
[2.0.0] - 2026-05-28
Summary
Full-spectrum LinkedIn content engine — short-form feed posts AND long-form newsletter editions in one cohesive surface, with net-fewer commands and net-stronger pipeline. Built across 21 Voyage sessions (S1..S20+S1a) with 1 step = 1 session discipline. Locked decisions A–H in docs/voyage-build-brief.md §3.
Added
/linkedin:newsletter— long-form orchestrator command. Multi-session pipeline: load → calibrate → research fan-out → draft → consistency/quality → fact-check sweep → persona sweep → annotate → lock → delivery → hook-gate → schedule. Maintainededition-state.jsonacross sessions. Supports newsletter editions, essays, and series articles/linkedin:outreach— outreach orchestrator (absorbed/linkedin:collaband/linkedin:speaking). Covers collaborations, partner pitches, and CFPs/speaking opportunities in one surfaceagents/fact-checker.md(Opus, brown) — verifies every factual claim in long-form drafts against primary sources. Outputs 🟢/🔴/🟡 verdicts per claim. Runs BEFORE lockagents/persona-reviewer.md(Opus, olive) — evaluates reader-persona resonance + hook-conversion gate. Two modes: per-persona deep review, multi-persona scoreboard. Runs BEFORE lockrender/pipeline migrated in-plugin —build-html.mjs,build-pdf.mjs,build-linkedin.mjs,build-carousel.mjs. Self-hosted fonts (Newsreader, Inter, JetBrains Mono) under OFL-1.1 withrender/OFL.txt. WeasyPrint degradation: missing binary → skip-signal, not throwconfig/personas.template.md— reader persona library. Knowledge level, time-pressure, resonance criteria per persona. Consumed bypersona-reviewerconfig/edition-state.template.json— schema for long-form edition state across sessionsreferences/longform-quality-rules.md— quality bar specific to long-form (different from short-form rules)- Router gating —
/linkedin:monetizeand/linkedin:outreachsurface "unlocks at ~1K followers" guidance and point sub-1K users at/linkedin:strategyfirst docs/agents-capability-matrix.md— single source of truth for which agent owns which capability. Pipeline diagram + intent table + model tier table
Changed
- Agent merges (16 → 14):
performance-reporter→analytics-interpreter(interpret + report modes, same data sources, mode-selector by trigger phrase)comment-strategist→engagement-coach(5x5x5 + first-hour + CEA method + target scoring + daily routine + comment quality scorecard; upgraded haiku → sonnet since the agent now handles deeper work)content-tracker→ absorbed bystate-updater.mjs+analytics-interpreterpersonalization-scorer→ absorbed bypersonalization-score.mjs(deterministic, no AI)
- Command merges (27 → 24):
/linkedin:templates→ mode in/linkedin:quick(8 post-type templates)/linkedin:publish→ action in/linkedin:calendar(mark scheduled posts as published)/linkedin:authority→ absorbed into/linkedin:strategy(canon for authority building, trajectory dedup)/linkedin:collab+/linkedin:speaking→/linkedin:outreach
/linkedin:importStep 6 analysis — delegated to/linkedin:report(both consume the sametrendsCLI; no more duplicated analysis pipeline)commands/linkedin.mdrouter — newsletter row added, removed-command rows pruned, gating-rule paragraph for monetize/outreach- All 6 skill catalogs reconciled —
linkedin-content-creation,linkedin-analytics,linkedin-strategy,linkedin-networking,linkedin-thought-leadership,linkedin-voiceall reflect the v2.0.0 command/agent set
Removed
commands/templates.md(absorbed intocommands/quick.md)commands/publish.md(absorbed intocommands/calendar.md)commands/authority.md(absorbed intocommands/strategy.md)commands/collab.md(absorbed intocommands/outreach.md)commands/speaking.md(absorbed intocommands/outreach.md)agents/content-tracker.mdagents/personalization-scorer.mdagents/performance-reporter.mdagents/comment-strategist.md
Fixed
references/glossary.md"Authority Score" entry — corrected stale ref tocommands/authority.md(removed) →commands/strategy.md(canon)scripts/test-runner.shEXPECTED_AGENTSlist — reconciled to 14 agents
Migration notes
- Plugin remains fully backward-compatible from a user-perspective: removed commands now route to their absorbing command via
commands/linkedin.md - v1.x users who had
commands/templates.mdetc. in muscle memory will be auto-redirected by the router
[1.2.0] - 2026-04-11
Summary
Friction reduction release. Fewer interactive steps, auto-clipboard, deterministic state management, and progressive onboarding.
Added
clipboard-helper.mjs— cross-platform clipboard utility (macOSpbcopy, Linuxxclip/xsel, WSLclip.exe). All 8 content commands auto-copy output to clipboardstate-updater.mjs— deterministic state mutations:updatePostTracking,pruneContentHistory,updateFollowerCount. Pure functions with 19 tests. No AI involvement in state updatesical-generator.mjs— RFC 5545 calendar file generation for batch scheduling. VALARM reminders, VTIMEZONE support, line folding, special character escaping. 16 tests- MCP image carousel pipeline —
/linkedin:carouselgenerates professional slide images via mcp-image (1080x1350, 3:4 ratio) with text overlays. Mermaid Chart and text-based fallbacks - Progressive onboarding — personalization score hidden until 3+ posts; voice guardian suppressed until 5+ voice samples; reasonable defaults in state template
- iCal integration in batch —
/linkedin:batchgenerates.icsfile importable into macOS Calendar, Google Calendar, and Outlook - Auto-prune content history — session-start dynamically imports
pruneContentHistoryto remove entries older than 90 days
Changed
- Reduced interactive steps — angle, format, and post type inferred from context. Max 2 questions per post (down from 4-6) in
post,quick,react,pipeline - State management — Stop hook and 8 commands now reference
state-updater.mjsfor deterministic writes instead of AI-driven YAML editing - State file template — default expertise area changed from domain-specific to
"general"for better new-user experience
[1.1.0] - 2026-04-08
Summary
Q2 2026 feature release. 9 improvements across onboarding, content quality, and analytics pipeline.
Added
/linkedin:onboarding— multi-step onboarding wizard: profile → setup → first-post as one guided flow/linkedin:carousel— structured multi-slide carousel generator with 5 templates and design specs- Voice drift scoring — 6-dimension rubric (sentence structure, word choice, openings, storytelling, tone, formatting) with AUTHENTIC/CAUTION/ALERT/REWRITE verdicts in voice-guardian hook
- Industry angle variants — 48 concrete variants (6 industries × 8 angles) in thought-leadership-angles reference
- Multi-URL comparison —
/linkedin:reactnow supports 2-3 URL synthesis with contrarian and pattern analysis angles - Day-of-week heatmap —
heatmapCLI command andHeatmapReporttype in analytics pipeline - Month-over-month reports —
report --month YYYY-MMCLI command with MoM deltas, weekly breakdown, top performers - Automated week-rollover — session-start hook now writes
posts_this_week: 0and updatescurrent_weekon ISO week change - Collected Post Samples — Stop hook passively accumulates published posts in voice-samples file for drift scoring
Changed
- README Quick Start — replaced 4-step manual flow with single
/linkedin:onboardingentry point /linkedin:report— Step 2 now offers report type choice (weekly/monthly/heatmap)/linkedin:post— Step 2 shows industry-specific angles when user-profile has industry set; Step 3 redirects to carousel when appropriate/linkedinrouter — added onboarding and carousel to menus and direct routing- Command count — 25 → 27 (onboarding, carousel)
[1.0.0] - 2026-04-07
Summary
Public release for open-source marketplace. All runtime bugs fixed, documentation aligned, agent model tiering implemented.
Fixed
- Agent model assignments — all 16 agents corrected from opus to proper tiering (12 Sonnet, 4 Haiku)
- Queue manager references — 10 stale
queue-manager.shreferences replaced withqueue-manager.mjsNode.js invocations - Quick-import references — 2 stale
quick-import.shreferences updated to.mjs - Personalization score import bug — standalone execution block now guarded to prevent stdout contamination on import
- Regex anchor — invalid
\ZJavaScript regex replaced with$in user-prompt-context.mjs - Agent color mismatches — 8 agent frontmatter colors unified with CLAUDE.md documentation
- Version inconsistency — unified from 3 conflicting versions (0.6.0/1.7.0/2.0.1) to 1.0.0
Added
- plugin.json — added
license,repository,keywordsfields for marketplace compliance - README — attribution note, "What This Plugin Does Not Cover" section, Node.js 18+ prerequisite, hooks badge
- CONTRIBUTING.md — replaced GitHub PR template with solo-project boilerplate
- Quality scorecard — added "Voice Authenticity" criterion (total now /81)
- Commands —
/linkedin:reactand/linkedin:first-postadded to README command tables - agents/README.md — updated from 14 to 16 agents, added personalization-scorer and post-feedback-monitor
- SKILL.md — added 5 missing commands to router command table
Changed
- CLAUDE.md — compacted from 237 to 90 lines, removed duplicated content
- All hooks — 100% Node.js (.mjs), no bash dependencies (cross-platform: macOS/Linux/Windows)
- Error handling — added JSON.parse guards in queue-manager.mjs and analytics storage.ts
Removed
- Skill version fields — removed non-standard
version:from all 6 SKILL.md frontmatter - Development artifacts — removed internal evaluation note from collab.md
- Orphaned files — deleted outdated docs/commands-reference.md
- BACKLOG.md and DEVELOPMENT-LOG.md — gitignored (internal development files)
[0.6.0] - 2026-02-07
Note
First formal version. Previously unversioned.
What exists today
- 20 commands covering full content lifecycle
- 15 specialized agents
- 8 hooks for workflow automation
- Analytics system with CSV import
- Profile/topic-relevance optimization
- Content matrix system (40+ post ideas from single topic)
- Personalization engine
- 20 reference documents for LinkedIn best practices
- Full content pipeline from ideation to post-publish monitoring