Commit graph

740 commits

Author SHA1 Message Date
3235c4f166 docs(linkedin-studio): reconcile discoverability surfaces + skill naming
Wave 3 / Step 12 of the remediation plan (Phase 1 — usable by a non-author).

Fix the discoverability defects the audit flagged:
- skills/linkedin-studio/SKILL.md (the auto-activating router): self-naming 'the
  LinkedIn thought leadership plugin' -> 'LinkedIn Studio' (v3.0 rename leftover);
  the 'All Agents' table corrected from 14 to the real 19 (added editorial-reviewer,
  voice-scrubber, content-reviewer, language-reviewer, fact-reviewer); the 'All
  Commands' table completed to 26 (added headless-review, pivot, carousel) so it
  routes to newsletter/headless-review/pivot/react.
- commands/onboarding.md: '25 commands' -> '26 commands' (x2); pillar count '3-5
  expertise areas' -> '5 expertise areas' (reconciles onboarding's 3-5 with
  setup.md's '5 core topics' and the CLAUDE.md '5 core expertise areas' rule).
- commands/linkedin.md: router table + numbered option list gain headless-review
  and pivot.

Scope note (operator decision, this session): the plan's Verify grep
'grep -rni "thought leadership" skills/ -> no matches' is broader than the brief's
actual criterion (which targets only the router skill's self-naming). 'thought
leadership' is a plugin-wide DOMAIN term — the '8 Thought Leadership Angles'
framework lives in references/thought-leadership-angles.md and is referenced by ~40
files (glossary, agents, post/video/batch commands). Renaming it only inside skills/
would create cross-file inconsistency; renaming it plugin-wide is a separate
vocabulary migration outside Step 12's discoverability scope. Per operator choice,
the router SELF-NAMING is fixed (brief criterion met) and the 4 remaining skills/
hits (linkedin-content-creation headings + one linkedin-strategy phase cell) are
legitimate domain usage kept consistent with the rest of the tree.

setup.md needed no edit: its pillar number was already '5'; reconciliation was a
one-sided fix in onboarding.

Verify: router no longer says 'thought leadership plugin'; grep -nc 'headless-review'
commands/linkedin.md -> 2; onboarding pillar count '5' matches setup.md; SKILL.md
agent table 19 rows, command table 26 rows; structural lint exit 0 (61 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 01:05:19 +02:00
4052b649f2 docs(linkedin-studio): remove independently-reviewed claim, honest reframe
Wave 3 / Step 11 of the remediation plan (Phase 1 — usable by a non-author).

The README claimed 'the version that ships is the version that's actually been
independently reviewed' — an overclaim the operator correction flagged: the cold
review is a CAPABILITY the pipeline can run, not a guarantee every shipped edition
received. Reframe to the honest capability:
- Long-Form Engine bullet: the draft CAN be frozen and re-read by reviewers with no
  drafting-session context (argument, language, facts, reader-fit) before lock, so a
  cold pass catches what the framing-biased in-session gates miss; run inline (Step
  6.5) or via /linkedin:headless-review for maximum independence. No claim about what
  every shipped edition went through.
- Pipeline diagram annotation '(independent re-read)' -> '(cold, headless)'.

Verify: grep -ni 'independently reviewed' README.md -> no matches.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:59:31 +02:00
86e4d5109b docs(linkedin-studio): honest dated API/auto-publish/analytics boundaries
Wave 3 / Step 10 of the remediation plan (Phase 1 — usable by a non-author), per
research/02.

State what the plugin can and cannot do for a PERSONAL profile, dated 'as of
2026-05', without replacing one false claim with another:
- README.md: new 'Boundaries (as of 2026-05)' section. (a) post-level analytics API
  EXISTS but is partner-gated (vetted Community Management app + verified org +
  Page) — not self-serve; CSV is the practical floor; saves visible natively
  (count-only, ~Sept 2025) with no self-serve API pull. (b) auto-publish is
  technically POSSIBLE self-serve (w_member_social) but deliberately NOT built — a
  design + ToS choice, explicitly 'not an impossibility' (avoids the new false
  'cannot auto-publish' claim). (c) dwell internal-only for organic, not exportable.
- commands/calendar.md: the publish action now states plainly it marks a post YOU
  posted manually as published — the tool does not post on your behalf.
- commands/report.md: dated the saves/no-self-serve-API note ('as of 2026-05').
- commands/import.md: dated 'Why CSV' note — API is partner-gated, CSV is the floor.

Verify: grep -niE 'cannot auto-publish|only way to (get|access)' README.md
commands/*.md -> no matches; grep -ni 'as of 2026' README.md -> 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:58:05 +02:00
8d2968a482 feat(linkedin-studio): make long-form review language configurable [skip-docs]
Wave 3 / Step 9 of the remediation plan (Phase 1 — usable by a non-author).

The long-form review layer shipped Norwegian-locked: language-reviewer graded
unconditional Norwegian, voice-scrubber's gold standard was 'approved Norwegian
editions', and the editorial/content craft gates pointed at a 'skrivekontrakt §C2'
that does not ship. A non-Norwegian adopter would get English prose graded against
Norwegian idiom and a gate that depends on an unshipped contract.

- config/edition-state.template.json: add additive 'language' field (top-level,
  default 'en') + a _doc entry. Threads into the language-dependent agents.
- agents/language-reviewer.md: new 'Language parameter' section — Norwegian-specific
  checks (anglicism->Norwegian idiom, kanselli-stil) apply only when language=='no';
  any other value grades that language's equivalents and never flags idiomatic
  English as an anglicism. Default 'en'.
- agents/voice-scrubber.md: gold standard reframed to 'approved editions in the
  configured language'; the Norwegian-chronicle calibration is the language=='no'
  instantiation.
- agents/editorial-reviewer.md + agents/content-reviewer.md: the in-tree checklist
  is now the operative, self-contained source of truth; Maskinrommet §C2 is an
  optional upstream contract that does NOT ship (available only on the author's
  runs). The gates work for an adopter without it.
- commands/newsletter.md: thread 'language' through the Step 6.5 cold-inputs and the
  per-reviewer call inputs; the writing contract is now 'if it ships'.

Norwegian remains fully working when language: no (the author's case).

fact-reviewer.md was in the plan's file list but needed no change on inspection:
its F1-F4 checks (claims/quotes/numbers/sources) are language-agnostic; its
'Norwegian' mentions are boundary notes vs language-reviewer, which stay correct.

[skip-docs]: three-doc + version reconciliation is Step 21 (pre-review-gate); these
intermediate Wave commits are not pushed before the /trekreview gate.

Verify: edition-state JSON parses + has top-level language 'en'; language-reviewer
has 'language ==' references and no unconditional-Norwegian assertion; editorial
§C2 reframed to in-tree fallback ('operative source', 'does not ship'); agent
fixtures 35/35 pass; structural lint exit 0 (61 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:55:04 +02:00
305b99c0e4 feat(linkedin-studio): parameterize series path + de-brand render output [skip-docs]
Wave 3 / Step 8 of the remediation plan (Phase 1 — usable by a non-author).

The flagship long-form engine shipped bespoke-as-general: a maintainer-private
absolute series path and a hardcoded 'Maskinrommet' brand in the renderers. Both
are now generalized so a non-author can run the pipeline without inheriting the
author's filesystem or publication identity.

- commands/newsletter.md + config/edition-state.template.json: series-root default
  /Users/ktg/repos/maskinrommet/serier -> $HOME/linkedin-series; reconciled the
  prose that called the maskinrommet folder 'the default' so it no longer
  contradicts the new neutral default. LTL_SERIES_ROOT override contract preserved.
- render/build-linkedin.mjs + render/build-carousel.mjs: brand is now an LTL_BRAND
  env-var (empty default -> generic). Samle-post title, carousel footer brand-span,
  and cover-eyebrow fallback are de-branded; empty brand renders clean chrome. The
  operator sets LTL_BRAND=Maskinrommet in their own env to re-brand (same pattern
  as LTL_SERIES_ROOT).
- config/image-credit-caption.template.md: 'Maskinrommet-/serie-badge' -> generic
  'serie-badge'.

Out of scope (Step 9): the residual 'Maskinrommet skrivekontrakt §C2/§A'
references in newsletter.md are the writing-contract generalization, handled next.

[skip-docs]: three-doc + version reconciliation is Step 21 (pre-review-gate, per
plan: 'LAST so it captures everything'). These intermediate Wave commits are NOT
pushed before the /trekreview gate, so the three-doc obligation (which governs
pushed changes) is satisfied at Step 21, not per local checkpoint commit.

Verify: grep -rIn '/Users/ktg' config/ commands/ render/ (excl .local) -> no
matches; grep -rn 'Maskinrommet' render/ -> no matches (de-branded); node --check
on both render scripts -> OK; LTL_SERIES_ROOT still present in newsletter.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:46:05 +02:00
6ed3e2f5a6 fix(linkedin-studio): honest saves/dwell wording, no false tracking claim
Wave 2 / Step 7 of the remediation plan (research/02 D2/D4).

The tool parses the LinkedIn analytics CSV export, which has no saves/dwell — and
there is no self-serve API to pull them. Stop implying it tracks them:
- report.md: replace "Saves (10x weight) and expert comments (7-9x) are the
  highest-impact signals" with honest wording — saves rank highest in the
  engagement ORDER (cite references/algorithm-signals-reference.md, not a restated
  coefficient), but are visible only in native LinkedIn post analytics (count-only,
  ~Sept 2025+) with no self-serve API, so this tool does not auto-track them; dwell
  is internal to LinkedIn for organic posts.
- types.ts: document why PostMetrics intentionally omits saves/dwell (no ingest
  source) so a future contributor does not "add the missing fields".
- strategy.md: reconcile two saves references (signature-content criterion +
  authority scorecard) to say the count is read from native LinkedIn analytics, not
  captured by this tool.

No new metric field, no manual-entry feature (operator Q3).

Verify: report.md has no "Saves (10x"/"highest-impact signals" and does say "no
self-serve API"; tsc --noEmit clean; analytics suite 106/106; structural lint
0 failed (report.md cites the reference, so stat-consistency stays green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:28:23 +02:00
55bfe309eb fix(linkedin-studio): downgrade A/B significance claim to directional
Wave 2 / Step 6 of the remediation plan.

Organic personal-post A/B tests gather a handful of posts per variant — far below
the volume a significance test needs — so the tool must not imply statistical
significance:
- Rename the results-table "Significant?" column to "Directional?" and define it
  as "clears the ~20% minimum-meaningful-difference AND points the same way across
  most posts" — a direction to test further, not a significant result.
- Reword the "20% significance rule" to a minimum-meaningful-difference effect-size
  heuristic (explicitly NOT statistical significance).
- Replace the "3 = Medium, 5+ = High" confidence ladder with a directional-only
  confidence section: treat every result as directional (not significant) given
  realistic volume is well under ~50 conversions/variant; name a direction, not a
  winner.

The 20% minimum-meaningful-difference threshold itself stays — it is a legitimate
effect-size heuristic; only the significance framing was the false claim.

Verify: no "Significant?"/"20% significance" remain; "directional" present;
structural lint 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:25:26 +02:00
911871ff53 fix(linkedin-studio): ship placeholder voice profile, gitignore real, sentinel detection
Wave 2 / Step 5 of the remediation plan (coupled criticals: voice-leak +
placeholder-detection).

Voice profile (the adopter-default leak):
- Ship a PII-free placeholder at authentic-voice-samples.md carrying a
  <!-- VOICE_PLACEHOLDER --> sentinel + neutral default voice principles.
- Migrate the author's real profile to gitignored authentic-voice-samples.local.md
  (already matched by *.local.md; added an explicit, commented .gitignore entry so
  the intent is unmissable). NO git-history rewrite — the historical file is
  attributed authorship, not a secret (per the plan threat model).
- Add authentic-voice-samples.template.md — a clean fill-in template for adopters.
- personalization-score.mjs: detect the sentinel (deterministic) instead of the
  unreliable `[Your Name]` heuristic, so the placeholder scores 0 voice points and
  a populated profile (sentinel removed) earns the 25.
- Both voice writers replace-not-append on the placeholder: setup.md (merge ->
  replace-if-placeholder) and onboarding.md (append -> replace-if-placeholder), so
  populating removes the sentinel; updated setup.md's stale heuristic table.

Operator decisions (deviations from plan-literal, approved this session):
- KEEP the plugin.json author name. The plan said scrub author -> neutral/org, but
  that contradicts its own LICENSE reasoning (intentional MIT attribution) and all
  5 sibling plugins keep author = the author; scrubbing only this one would create
  inconsistency for zero security gain (the name is public-by-design). The voice
  placeholder fully fixes the adopter-inheritance bug.
- Scrub the stale "January 2026 360Brew" brand from the plugin.json description and
  the "360brew" keyword (locked decision: no publishable model name/date). This is
  a Wave-1 propagation miss surfaced here because plugin.json was in Step 5's
  touch-scope.

Flagged for follow-up (NOT done here — out of Session 2 scope):
- The lint's stat-consistency grep (scripts/test-runner.sh) scans references/,
  commands/, skills/, hooks/prompts/, CLAUDE.md, README.md — but NOT
  .claude-plugin/plugin.json, which is why the 360Brew brand slipped Wave 1.
  Needs a Session-1-scoped lint extension to add plugin.json to the scan set.
- Readers (user-prompt-context.mjs, voice-guardian.md, state-update-reminder.md)
  read the tracked .md (placeholder), per the plan. The operator's real voice now
  lives in the gitignored .local.md, which nothing reads. To use it, readers + the
  voice score should prefer .local.md (matching the user-profile.local.md
  precedent). Deferred as a coherence follow-up for operator review.

Test-first: hooks/scripts/__tests__/personalization-score.test.mjs (red on the
placeholder scoring 25 under the old heuristic, green after the sentinel fix). Hook
suite 62/62, structural lint 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 00:23:32 +02:00
798484bf0c fix(linkedin-studio): anchor analytics root on plugin marker + surface npm install
Wave 2 / Step 4 of the remediation plan (docs/remediation/plan.md).

PRIMARY (the real fresh-clone failure):
- scripts/analytics/node_modules is gitignored, so a fresh clone has neither
  tsx nor csv-parse. Surface an idempotent `npm install --silent` prerequisite
  at point-of-use in report.md (Step 1b) and import.md (Step 4).

DEVIATION FROM PLAN (correction-in-scope, to satisfy the plan's own Verify gate):
- The plan assumed prepending `npm install` was sufficient. Verified it is NOT:
  the commands invoke the CLI with an absolute src/cli.ts path but from the
  user's arbitrary CWD, and `node --import tsx` resolves the `tsx` specifier
  relative to CWD, not the script. There is no global tsx, so the call still
  fails with ERR_MODULE_NOT_FOUND from any CWD other than scripts/analytics.
- Complete fix: invoke the locally-installed tsx by its absolute
  node_modules/.bin/tsx path in all CLI calls (report.md x10, import.md x3), so
  they resolve from any working directory once the install above has run.
  Verified: 0 ERR_MODULE_NOT_FOUND running `report` from /tmp.

SECONDARY (latent correctness / hardening):
- Add findPluginRoot(): walks up to the dir holding .claude-plugin/plugin.json
  and anchors getAnalyticsRoot() on it, falling back to the legacy 4-up count.
  MEASURED that ../../../../ already resolved to the plugin root from BOTH
  src/utils and build/utils (both 4 levels deep), so the plan's "src-vs-build
  depth miscalibration" premise was false — this is correct-by-construction
  hardening (survives a future source move), not a live-bug fix.
- Reconcile cli.ts usage/help text: `node build/cli.js` -> `node --import tsx
  src/cli.ts` (the real runtime).
- Fix report.md troubleshooting: "Verify tsx is available" -> the actual
  install command on ERR_MODULE_NOT_FOUND.

Test-first: scripts/analytics/tests/storage-root.test.ts (red on missing
findPluginRoot export, green after). Full suite 106/106, tsc --noEmit clean,
structural lint 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 21:18:33 +02:00
4700248cc4 fix(linkedin-studio): propagate reconciled algorithm numbers, cite-not-restate
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:32:17 +02:00
a6e2f26913 chore(voyage): consolidate continuity into STATE.md
Remove REMEMBER.md / TODO.md / ROADMAP.md / NEXT-SESSION-PROMPT.local.md
mechanisms per ~/.claude/CLAUDE.md (2026-05-26 rule): the three layers
are STATE.md + auto-memory + plugin-CLAUDE.md; local mechanisms are
abolished and consolidated into the layers + git + docs/-reference.

- .gitignore: drop REMEMBER.md / TODO.md / ROADMAP.md entries; add STATE.md
  (gitignored — overskrives ved sesjonsslutt, lokal state-of-play).
- CLAUDE.md: cross-cutting-invariant note now points to STATE.md instead
  of ROADMAP.md (linter update, same theme).

Forward-looking version specs (v5.2 TDD, v5.3 sesjons-konsolidering,
v5.4 brief-format public contract, v5.5 brief framing alignment) lived
in the gitignored ROADMAP.md and are NOT recoverable from git. If
reactivated they go through the brief→plan pipeline (proper Voyage
discipline anyway).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 20:29:51 +02:00
970f45bd68 fix(linkedin-studio): reconcile algorithm-signals to one sourced statement
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:21:24 +02:00
2f2df94acb fix(linkedin-studio): rebuild dead structural lint to real v3.1 layout
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:18:24 +02:00
a61b818578 docs(linkedin-studio): Voyage remediation setup — brief + research + plan (Phase 0-3)
Audit-remediation Voyage project authored end-to-end this session:
- brief.md (reviewer PROCEED; validator pass) — full Phase 0-3 scope, phased,
  with success criteria refined by research
- research/01-03 — high-effort external swarm + Gemini (Topic 1); reconciled the
  external bar and corrected several audit feature-premises (no publishable model
  name/date; saves UI-visible not API-pullable; auto-publish possible-not-built;
  9:16 not mandatory; newsletter notifications deduplicated not triple; CLI crash
  = missing npm install, depth-bug latent)
- plan.md (21 steps, 7 sessions, 5 waves; validator pass; A- 88/100) — plan-critic
  REVISE (3 blockers + majors) addressed; scope-guardian ALIGNED; gemini Pass-2
  folded in 2 blind spots (git-history decision; lint stat-grep sequencing)

Execution is future sessions (one wave each) via /trekexecute, /trekreview as the
release gate. Audit report stays local until the article ships.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 19:49:27 +02:00
90fcc1069d docs(linkedin-studio): add honest "not a shortcut" caveat to intro
Set expectations up front: the plugin systematizes the work, it doesn't
substitute for the human effort. Letting AI drive lands you in the
forgettable middle; the judgment, genuine engagement, and effort that
make content worth reading stay with the user. Reinforces the README's
no-hype tone and filters for serious adopters over a viral shortcut.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 14:39:17 +02:00
10870107e4 docs(linkedin-studio): drop top What's New section, lead with motivation
The standalone "What's New in v3.1.0" section opened with internal
development narrative (Endring 9, Del 4 run, framing-bias) that means
nothing to a prospective adopter — still leading with a changelog, the
exact pattern the rewrite set out to fix. Follow llm-security: motivation
first, version detail only in the Version History table at the bottom.

- Remove the "## What's New in v3.1.0" section and its TOC entry
- README now flows intro → Why LinkedIn Studio Exists → What Is This?
  → Two Engines → Quick Start
- Nothing lost: v3.1.0 remains in the Version History table

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 13:50:43 +02:00
82c5249ca8 docs(linkedin-studio): rewrite README to match marketplace pattern
The README led with a ~600-word version-by-version wall and stacked
seven "What's New in vX.Y.Z" sections before reaching "What Is This?",
reading as a changelog rather than motivating adoption.

Restructure to the sibling-plugin pattern (config-audit / llm-security
/ voyage):
- Concise motivating intro paragraph (no version enumeration)
- Keep only the latest "What's New" (v3.1.0); full history stays in the
  Version History table at the bottom
- New "Why LinkedIn Studio Exists" section: the real pain (blank-page
  paralysis, inconsistency, algorithm opacity, generic AI slop, the
  360Brew shift) mapped to what the plugin does about each
- New "Two Engines" section framing feed vs. long-form, with the
  pre-lock quality gauntlet as the long-form differentiator
- Refresh "What Is This?" to the LinkedIn Studio / content-engine framing
- Swap the unverified "40+ ideas / Content Matrix" claim for the
  documented "8 universal angles" (verification duty)

All accurate tables (26 commands, 19 agents, 9 hooks, 24 reference
docs) and the full Version History preserved verbatim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 13:46:20 +02:00
e69ea1f4c9 feat(linkedin-studio): v3.1.0 — Endring 9 adversarial review-pakke + per-artefakt personas
Cold, adversarial review package for the long-form pipeline + configurable
per-edition personas. Motivated by Del 4 (Security Champions pivot): the
in-session editor + persona sweep shared the drafting session's framing-bias,
so the shipped version was never independently re-reviewed.

Headless package (9a/9b):
- New Step 6.5 (headless-review) in /linkedin:newsletter, after the persona
  sweep, before lock — the independence layer the in-session gates can't be.
- New standalone /linkedin:headless-review command (run in a fresh session for
  maximum isolation; reconstructs frozen draft + contract + personas from disk).
- 3 new Opus archetypes, each with a cardinal context-isolation block that
  refuses drafting-session framing as "context pollution":
  - content-reviewer (argument integrity C1–C5, ≤8 flags)
  - language-reviewer (Norwegian language L1–L5, ≤10 flags)
  - fact-reviewer (cold re-verification F1–F4, risk-sort + pivot-risk, WebSearch)
- Deliberate redundancy with fact-checker / editorial-reviewer documented so
  the pairs are never de-duplicated.

Pivot-reopen (9c):
- New /linkedin:pivot command: logs articles.NN.pivots[], resets currentPhase,
  un-locks, marks gates to re-run.
- Pivot-detection gate in Step 8 lock precondition (>20% word-count change or
  >2 new sections re-opens cleared gates). Del 4 v8→v11 worked example.

Per-artifact personas (new requirement):
- articles.NN.personas with resolution order (edition-state → series file →
  plugin library → interactive). One or more readers configurable per edition.

Schema/docs:
- edition-state.template.json: additive personas[], pivots[], headlessReview,
  headless-review phase (16 phases); personaSweep.resonance.wordCount baseline.
- 3 fasit fixtures + 3 structural lint tests (Del 4 worked cases).
- Counts: 24→26 commands, 16→19 agents, 15→16 newsletter phases.
- README + CLAUDE.md (plugin + root) + CHANGELOG synced.

Verification: 35 agent-fixture + 59 hook + 20 render tests green. Backward-
compatible (additive state); reload required before the 3 new agents resolve.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 13:01:24 +02:00
e162cdce38 chore: gitignore STATE.md (per-plugin continuity files stay local, not tracked)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 12:20:18 +02:00
66709b0867 feat(human-friendly-style): v1.1.0 — always show irreversible actions verbatim + discoverability docs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 11:53:00 +02:00
b6bb61246b refactor(linkedin)!: rename plugin linkedin-thought-leadership → linkedin-studio (v3.0.0)
BREAKING CHANGE: the marketplace slug, the agent namespace
(linkedin-studio:<agent>), and the runtime state-file path
(~/.claude/linkedin-studio.local.md) all change. Reinstall required;
existing state migrated in place (post metrics, streak, history preserved).
The /linkedin:* commands are unchanged — the command namespace is set
per-command in frontmatter and was always independent of the plugin slug.
Functionality is byte-identical to v2.4.0; this release is pure identity.

- dir + manifests: plugins/linkedin-studio + plugin.json + root marketplace.json
- agent namespace updated in commands/newsletter.md (only functional invoker)
- state path updated in 4 hook scripts + topic-rotation prompt + state template
- catch-all skill dir renamed skills/linkedin-studio (5 functional skills unchanged)
- docs + version bump to 3.0.0 across README badge, CHANGELOG, root README/CLAUDE.md
- historical records (CHANGELOG past entries, docs/ build artifacts,
  config-audit v5.0.0 snapshots) intentionally retain the old slug

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 11:32:02 +02:00
9df3de795c feat(linkedin): v2.4.0 — editorial-reviewer agent + Step 5.5 craft gate in /linkedin:newsletter
Endring 8 from the change spec (Del 4 production, Maskinrommet). The persona
resonance sweep measures reader-response (does it land?); nothing measured prose
craft or narrative architecture (is it well-made?). In Del 4 every persona
reported PASS, yet the editor found 8 fresh editorial points on first reading —
~6/8 craft/architecture blind spots no agent could see. v2.4.0 adds the missing
editor role.

New Step 5.5 (editorial-review) runs between fact-check (Step 5) and the persona
sweep (Step 6): a new editorial-reviewer agent (Opus) judges two axes —
prosa-handverk (em-dash density, verbatim repetition, postulated numbers,
contradictions, versal-tic) + narrativ-arkitektur (concrete instantiation,
theory-anchored hypotheses, series-title symmetry, equal action per addressee,
un-overloaded conclusion). Returns <=10 flags as direction (never copy), each
BLOCK/REWORK/NICE, operator-gated via SendUserFile. Runs before the persona
sweep so the personas measure resonance instead of stumbling on craft noise.
Mirrors the Maskinrommet writing-contract section C2 (bidirectional mirror rule).

- agents/editorial-reviewer.md (NEW, Opus, orange) + fasit fixture
  (editorial-reviewer-cases.md: Del 4 v5 gold standard, 8 points -> 2 axes +
  severities, 3 BLOCK / 5 REWORK, 6/8 blind spots) + structural lint (7 tests).
- Step 5.5 wired into commands/newsletter.md; pipeline 14 -> 15 phases.
- editorial-review phase + additive editorialReview state in
  config/edition-state.template.json; resumption: factcheck-sweep -> Step 5.5,
  editorial-review -> Step 6 (spec said fact-check; canonical key is
  factcheck-sweep).
- persona-reviewer contract unchanged: editorial-reviewer is supplementary
  (one measures craft, one measures response).
- All doc levels synced (plugin + root README/CLAUDE.md, CHANGELOG, plugin.json
  2.3.0 -> 2.4.0; agents 15 -> 16). 94 tests green.

Acceptance-criterion #8 (live run on Del 4 v5) delivered as fasit fixture:
a live run needs a session reload (new agent not invokable until then) + read
access to the Del 4 v5 draft in Maskinrommet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 06:17:50 +02:00
7ebd28cb0b feat(linkedin): v2.3.0 — Step 7.5 visual-assets phase in /linkedin:newsletter
Endring 7 from the change-spec: make visual assets an explicit pipeline
phase. New Step 7.5 (visual-assets) between annotation (Step 7) and lock
(Step 8): cover (+ optional inline figures) or carousel deck, generated and
operator-gated BEFORE lock so build-linkedin.mjs picks up cover.png at lock
without a post-lock re-render. Pipeline 13 → 14 phases.

- commands/newsletter.md: Step 7.5 section, pipeline overview + build-status,
  resumption table (annotation → 7.5; new visual-assets → 8), Step 8
  precondition, reference-file list.
- config/edition-state.template.json: visual-assets phase + additive
  articles.NN.visualAssets schema (format / cover / figures / carousel).
- config/image-credit-caption.template.md (new): motif + credit + caption
  table, honest-about-AI credit, naming convention.
- Two generation routes, no lock-in: default mcp-image (cover-v<N>-kandidat.png)
  or external cover-raw.png. Operator-gate via SendUserFile → cp to cover.png.
  Carousel branch reuses render/build-carousel.mjs.
- Doc/orchestration-only — no new code. Commands (24) + agents (15) unchanged.
- Version sync 2.2.0 → 2.3.0 across plugin.json, CHANGELOG, README, CLAUDE.md,
  root README + root CLAUDE.md.

Correction: spec claimed build-linkedin.mjs handles fig1-4; verified it does
NOT — it embeds only cover.png by fixed name; figures are referenced in the
draft markdown and uploaded manually. Step 7.5 documents actual behavior.

All 8 acceptance criteria met. JSON valid (14 phases); 20/20 render tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:49:19 +02:00
4ed9717627 feat(linkedin): v2.2.0 — harden longform gates from 2nd production run
Implements the 6-change spec from the Seres-serien production
(linkedin-plugin-endringsspec.md). All acceptance criteria met.

1. Avoid-patterns (modell-/navne-katalog, completeness-over-reader-action,
   self-referential overhead openings) → longform-quality-rules.md (rule 1+3)
   + user-profile.template.md.
2. Persona gate now BLOCKING with explicit hard-fail list (primær mistet meg /
   doesn't own action / sjargong-mur / modell-navne-katalog → BLOCK;
   "JA med store forbehold" = NEI) → persona-reviewer.md + personas.template.md.
3. Fact-check declared orthogonal to narrative strength + post-cutoff
   web-search mandate + high-frequency-error checklist → fact-checker.md.
4. NEW agent voice-scrubber.md (Opus) — de-AI scrub + Norwegian-chronicle
   voice-drift; gold standard = approved Norwegian editions, NOT the English
   post corpus. Wired into newsletter.md Step 4.
5. Operator gates = render+annotate rounds (build-html.mjs to file://) as
   primary flow, AskUserQuestion as receipt/fallback → newsletter.md 2.5+3a.
6. Edition state reconciled with STATE.md (ONE-system). edition-HANDOVER
   template deleted; narrative to <serie>/STATE.md, machine data
   (factcheckLog, personaSweep, immutableRules) to edition-state.json.

Agents 14 to 15; commands unchanged (24). Backward-compatible (additive
state-shape only). Docs updated across all three levels + CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 20:50:56 +02:00
2a27a7cd6a feat(linkedin): v2.1.0 — skeleton + spine-prose gates BEFORE prose in /linkedin:newsletter
Two new pipeline phases gate the spine before any prose is written:

- Step 2.5 — Skeleton + section pitch: writes <serie>/NN-skjelett.md with
  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 can advance.
- Step 3a — Spine prose: 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. Old Step 3 (Draft) split into
  3a (spine) and 3b (full expansion); 3b owns the multi-session
  draft-cursor logic.

Third persona-reviewer mode added: skjelett (alongside resonans + konverter).
Five spine axes scored HOLDER / TVILER / MANGLER, max 3 direction-only flags,
per-pitch section-pay-in check. Reads the skeleton + pitches only.

Pipeline grows from 11 to 13 phases; commands (24) and agents (14) counts
unchanged. Encodes the Maskinrommet writing-contract section A discipline
(premiss / problem / anbefaling / gevinst / vei videre) into the pipeline.

Empirically motivated by the Seres-serien Del 3 + Del 4 production:
a spine error caught at the skeleton stage costs 5-15 min, the same
error caught at Step 6 (resonance) costs 4-12 h, post-lock it costs a
day of cascading rework (delingstekst, hooks, carousel, doc refs).

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. Steps 1, 2, 4-10 bit-for-bit
unchanged. Renderers (build-html.mjs, build-linkedin.mjs) untouched.

New phase strings in edition-state.template.json _doc.phases:
- skeleton-pitch (between research and draft)
- spine-prose (between skeleton-pitch and draft)

Files changed (10):
- plugin.json: 2.0.0 -> 2.1.0
- CHANGELOG.md: new [2.1.0] entry
- CLAUDE.md (plugin + marketplace): pipeline 11->13 phases noted
- README.md (plugin + marketplace): What's New v2.1.0 + version row
- agents/persona-reviewer.md: third mode skjelett added; resonans + konverter unchanged
- commands/newsletter.md: Step 2.5 + 3a + 3b sections, resumption + pipeline tables
- config/edition-state.template.json: 11 -> 13 phases in _doc.phases
- references/longform-quality-rules.md: Rule 8 (Skjelett foer prosa)

Verification: 9/9 criteria PASS pre-commit. Phase strings consistent
across template + command + resumption table. Renderer files git-untouched.
All 11 original step headings preserved (Step 0/1/2/4-10).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 10:09:47 +02:00
8de481399e chore(linkedin): v2.0.0 — import trim, router gating, full doc pass (S20) 2026-05-28 06:53:55 +02:00
930836597e refactor(linkedin): merge analytics + engagement agents 2→1 each (S19)
- analytics-interpreter absorbs performance-reporter (interpret/report modes,
  identical data sources): mode-selector + both output templates kept inline.
- engagement-coach absorbs comment-strategist (5x5x5 + first-hour + CEA
  commenting + target selection + scoring + quality scorecard + daily
  routine). Self-ref at engagement-coach.md:24 rewritten — target is now
  in-file. Model upgraded from haiku to sonnet (absorbed deeper work);
  tools union: Read, Glob, WebSearch.
- 7 ref-files reconciled: commands/linkedin.md (router rules merged),
  skills/linkedin-analytics (row dropped), skills/linkedin-thought-leadership
  (2 rows merged), skills/linkedin-networking (row dropped), CLAUDE.md
  (agents table 16→14, merged rows), README.md (agents table, flow diagram,
  intent table, analytics consumers line), references/glossary.md (3 'Used in'
  refs), scripts/test-runner.sh (EXPECTED_AGENTS list reconciled to current
  14 — also closed lingering S5/S6 gaps for fact-checker/persona-reviewer/
  video-scripter, removed already-deleted content-tracker/personalization-scorer),
  docs/agents-capability-matrix.md (full restructure: header count 16→14,
  agent table, capability grid columns + capabilities, pipeline diagram,
  intent table, model selection table — fixed STATE residual #1 on the
  tracker/pers-scorer stale columns in the same pass).
- Q2 decision (video-scripter → content-repurposer?): KEEP separate.
  Distinct invocation paths (/linkedin:video vs format conversion), distinct
  outputs (timed video script with pacing+captions vs format-translation
  artifact), and newsletter.md already uses content-repurposer for prose
  drafting independently of video-scripter. Net agents/ 16→14.
- agents/README.md dropped from Files (moved to docs/agents-capability-matrix.md
  in S14); literal Verify exits 2 on missing path (logged), corrected Verify
  passes 4/4 predicates. Manifest audit: 2/2 expected paths exist, 13 'CEA'
  occurrences in engagement-coach.md.
- gitleaks: clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 06:19:20 +02:00
0b44f219b6 refactor(linkedin): absorb authority into strategy + profile canon (S18)
- commands/strategy.md: extend frontmatter with authority triggers; insert
  Step 3.6 Authority Building (signature content map, greatest hits, derivative
  planning, content + network signals, action plan, monthly scorecard); add
  algorithm-signals-reference.md to Reference Files.
- commands/audit.md: Step 5.5 trajectory-review and Step 7 report-block
  trajectory section now route to /linkedin:strategy (the canon); Step 6
  profile-alignment routes to /linkedin:profile (the canon); drop
  trajectory-strategy-adjustments.md + algorithm-signals-reference.md from
  loaded references (canons own them).
- commands/analyze.md: 'If Profile-Content Mismatch' subsection routes to
  /linkedin:profile for the per-section checklist; quick-triage list kept.
- commands/authority.md: removed (absorbed by strategy.md).
- commands/linkedin.md: drop authority table row, merge 'Build authority'
  into AskUser item #10 (Growth strategy & authority), renumber 14-23 to
  13-22, broaden strategy routing trigger keywords, drop standalone
  authority routing rule.
- skills/linkedin-strategy/SKILL.md, skills/linkedin-thought-leadership/SKILL.md,
  CLAUDE.md, README.md: drop /linkedin:authority rows; widen /linkedin:strategy
  descriptions to reflect new scope.

Verification:
- Literal Verify (plan.md:704) exits 1 (expected inversion).
- Corrected predicate (test ! -f && ! grep -rqn …) exits 0 — clean.
- Manifest: commands/strategy.md present; [Aa]uthority match count = 24.
- Hooks: python3 hooks/scripts/compile-hooks.py --check → clean.
- Command count: 25 → 24.
- End-to-end Verification §849 (templates|publish|authority|collab|speaking)
  grep across commands/ agents/ skills/ hooks/ README.md CLAUDE.md → empty.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 06:01:43 +02:00
d5ee9d19fa refactor(linkedin): merge collab + speaking into outreach (S17)
Step 18 (fasit S17): merged commands/collab.md + commands/speaking.md
into a single commands/outreach.md covering both tracks under one
outreach/pitch paradigm. Structural twins: same outreach/pitch flow
(readiness → identify → score → format/abstract → outreach by
temperature → production/portfolio → engagement-pod warning →
pipeline tracker → network/progression → results dashboard) with
track-specific detail at each step.

Capability checklist: every function of both predecessors preserved:
- Collab: 5-item readiness, partner search + 25-pt rubric,
  12 formats across 4 maturity tiers, cold/warm/established outreach,
  DM amplification protocol, 5-phase co-creation workflow,
  shared drafting ground rules, pipeline board, health signals,
  Inner Circle tiers, long-term partnership framework.
- Speaking: 100-pt readiness scorecard, event/CFP search +
  research template, Nordic/European tech conference calendar,
  4 talk abstract templates, speaker positioning content calendar,
  demo reel strategy, speaker bio variants (50/100/200 words),
  CFP cover note + organizer outreach (cold/warm),
  post-speaking follow-up sequence, pipeline tracker,
  progression ladder (4 levels).
- Both: engagement-pod warning (post-Mar-2025), quarterly results
  dashboard with both tracks.

Removed commands/collab.md, commands/speaking.md.

Reconciled all 16 route-refs across plugin (collab 8, speaking 8):
- commands/linkedin.md: table row, priority list (items 16-17 → 16),
  routing rules (lines 177-178 → one rule), removed 'outreach' keyword
  from network-builder agent suggestion (now belongs to /linkedin:outreach).
- skills/linkedin-thought-leadership/SKILL.md: pillar table + all-commands
  table (lines 30, 140, 142).
- skills/linkedin-networking/SKILL.md: commands table (lines 29-30).
- CLAUDE.md: commands table (lines 63-64).
- README.md: feature bullet (line 68), commands table (lines 168-169),
  skills pillar table (line 289), ToS table (line 514).

Verify: corrected predicate (test ! -f X && test ! -f Y && ! grep -rqn)
exit 0. Literal Verify (plan.md:681) exit 1 due to the same exit-inversion
bug observed at Step 16/17 — logged for plan-pass at Step 21.

Manifest audit PASS: commands/outreach.md present; [Ss]peaking 40 hits;
min_file_count=1 satisfied; forbidden/bash checks vacuous.

Net commands/: 26 → 25 (matches plan).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 05:41:09 +02:00
e4aa5a61c2 refactor(linkedin): merge publish into calendar — reconcile hook refs (S16)
Step 17 of voyage-build (S16 in plan). publish.md absorbed into calendar.md
as an inline action (Mark as Published flow: queue update, state update,
first-hour battle plan) reusing the same queue-manager.mjs + state-updater.mjs
primitives that publish.md called. calendar.md frontmatter triggers extended
with the publish trigger words; quick-routing block jumps straight to the
publish action when the user prompt names it.

All 21 route-refs reconciled across the 9 expected files, with the 9
hook-script refs (5 in session-start.mjs, 2 in posting-reminder.mjs, 1 in
user-prompt-context.mjs, 1 in hooks/prompts/state-update-reminder.md)
rewritten to call /linkedin:calendar so the runtime guidance no longer
points at a dead command. compile-hooks.py --check reports clean (no
type: prompt hook changes touched hooks.json).

Verify (intent: zero stray refs, file gone): exit 0. Literal Verify in
plan.md:727 logged exit 1 (same exit-inverted && pattern as S15 plan.md:635
— logged for plan-pass at Step 21).

Manifest audit: PASS (expected_paths=calendar.md present; must_contain
[Pp]ublish: 17 matches in calendar.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 05:27:36 +02:00
ddd84e4501 refactor(linkedin): merge templates into quick (S15) 2026-05-28 00:07:09 +02:00
92e0a0b4f5 fix(linkedin): close dogfood friction (S14)
Close all 9 friction points from the S13 newsletter dogfood (operator
elected to fix F6-F9 rather than defer):

- F1: namespace all subagent_type calls in newsletter.md to
  linkedin-thought-leadership:<name> (4 sites + canonical note)
- F2: document agent invocation form + reload requirement in CLAUDE.md
  + README.md (reload itself is an operator action)
- F3: add edition-config / edition-delingstekst / edition-HANDOVER
  templates under config/ + wire into Steps 0 and 8 + footer
- F4: reconcile draft path to <serie>/NN-utkast.md (series root)
- F5: de-hardcode series root (explicit arg / LTL_SERIES_ROOT / default)
- F6: config-derive carousel editions (remove Seres CAROUSEL set);
  correct samle comment
- F7: build-html.mjs exits non-zero when zero HTML produced
- F8: guard parseDelingstekst (graceful ENOENT) + correct Step 8 wording
- F9: relocate agents/README.md -> docs/agents-capability-matrix.md

Re-tested: 87/87 plugin tests pass; build-html/build-linkedin behavior
re-verified live. Per-item outcomes logged in dogfood-S13-friction.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 23:37:39 +02:00
adfa2085fc test(linkedin): dogfood newsletter pipeline end-to-end (S13)
Dogfood mot throwaway-fixture (docs/review/dogfood-serie/, gitignored),
syntetisk tema. Deterministisk ryggrad (build-html/build-linkedin) kjørt
ekte og passerte; gate-laget (fact-check/persona) BLOKKERT — escalert, ikke
tvunget grønt. 9 friksjonspunkter (2 BLOCKER, 3 MAJOR, 4 MINOR) med order-proof
(persona-sweep wiret FØR lås) og per-punkt implicated file for S14 revert-mål.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 22:57:13 +02:00
8d25dd908e feat(linkedin): longform quality rules + edition resumption wiring (S12) 2026-05-27 22:30:42 +02:00
e031fae3de refactor(linkedin): single newsletter entry + skill trigger + router row (S11) 2026-05-27 22:08:16 +02:00
f24c6e30f7 feat(linkedin): newsletter Step 7-10 lock, delivery, hook-gate, schedule (S10) 2026-05-27 21:42:22 +02:00
fba70870ce feat(linkedin): newsletter Step 5-6 fact-check + persona sweep before lock (S9) 2026-05-27 21:33:43 +02:00
39ae875b96 feat(linkedin): newsletter Step 3-4 draft + consistency (S8) 2026-05-27 21:25:42 +02:00
9b1669a3f6 feat(linkedin): newsletter command skeleton Step 0-2 (S7) 2026-05-27 21:10:39 +02:00
ca5aa4e698 refactor(linkedin): edition-state schema + retire 2 deterministic agents to scripts (S6)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 20:26:14 +02:00
1faffac303 feat(linkedin): add persona-reviewer agent (2 modes) + fixture (S5) 2026-05-27 20:08:06 +02:00
be03d44c52 feat(linkedin): add fact-checker agent + fixture (S4) 2026-05-27 19:42:41 +02:00
0dc3f903f9 feat(linkedin): add reusable persona library template (S3) 2026-05-27 19:34:39 +02:00
36ad116e43 docs(ltl): add Maskinrommet field-experience brief for upgrade
Krav fra produksjonserfaring (Seres-serien): blokkerende persona-gate,
voice unngaa-moenstre, paastands-ledger + verifiseringsdisiplin, artikkel-skjelett.
Komplementaer til brief-fullspektrum-innholdsmotor.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 00:52:05 +02:00
6e6ed7dd4e feat(linkedin): generalize build-linkedin to read edition-config.json (S2) 2026-05-26 23:15:26 +02:00
c225ea1dba feat(linkedin): generalize build-html annotation renderer — tables, headings, inline code (S1a)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 23:05:54 +02:00
b4aaf7ae82 docs(linkedin): restructure v2.0.0 plan Execution Strategy → 21 discrete sessions (1 step = 1 session)
Each Session N now maps 1:1 to Step N so /trekcontinue advances exactly one step per session and never runs a full wave at once. Steps + manifests unchanged; validator valid:true. Deprecate NEXT-SESSION-PROMPT in favor of STATE.md handoff.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 22:27:08 +02:00
6eff5e8e21 feat(linkedin): migrate render scripts + fonts into plugin (S1)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 22:11:38 +02:00
098726d397 docs(linkedin): Voyage executable plan for v2.0.0 build (21 sessions)
Production plan for lifting LTL v1.2.0 -> v2.0.0 (full-spectrum content
engine + /linkedin:newsletter + render migration + net-fewer commands/agents).

- docs/voyage-build/{brief.md,plan.md}: Voyage project dir. plan.md = 21 steps
  (S1..S20+S1a), each with a per-step Manifest. Validator: valid, 0 warnings.
- docs/{brief,plan}-fullspektrum-innholdsmotor.md + voyage-build-brief.md:
  the directional brief, hardened fasit (authoritative WHAT), and Voyage input.
- Built via /trekplan: confirmatory swarm verified the fasit against real files
  (13 corrections folded in); scope-guardian ALIGNED; plan-critic REPLAN ->
  revised (3 blockers + 5/6 major + 4/5 minor closed).
- plan.html (annotation surface) left untracked: regenerable via annotate.mjs.

Next: /trekexecute --fg --project docs/voyage-build (fresh session) -> S1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 21:38:52 +02:00
03b8885b6e chore(llm-security): v7.7.2 — language consistency pass v7.7.2
~/.claude/CLAUDE.md specifies English for code and documentation,
Norwegian for dialog only. Norwegian had crept into surface text
across v7.5-v7.7. Translated to English in eight surfaces.

No scanner, hook, or behavior changes — purely surface text.

- 18 skill commands: the HTML Report-step now reads "HTML report:
  [Open in browser]" instead of "HTML-rapport: [Åpne i nettleser]"
- scripts/lib/report-renderers.mjs: key-stat labels, lede defaults,
  table headers, maturity-ladder descriptions, action-tier labels,
  clean buckets, dry-run/apply copy, and JS comments. Regex
  alternations /^high|^høy/ and /resolution|løsning/i preserved.
- playground/llm-security-playground.html: same renderer changes
  mirrored bit-identical, plus playground-only UI strings (catalog,
  breadcrumb aria-label, theme toggle, builder-modal hint,
  guide-panel "no projects yet", delete confirmation, alert/copy).
  Demo-state fixture content for dft-komplett-demo preserved
  (intentional Norwegian persona).
- agents/skill-scanner-agent.md + agents/mcp-scanner-agent.md:
  Generaliseringsgrense + Parallell Read-strategi sections translated
  to Generalization boundary + Parallel Read strategy.
- README.md: playground architecture prose + Recent versions table
  (v7.5.0 — v7.7.1).
- CLAUDE.md: v7.7.1 highlights translated, new v7.7.2 highlights
  added.
- ../../README.md: llm-security v7.5.0 — v7.7.1 bullets.
- ../../CLAUDE.md: llm-security catalog entry.
- docs/scanner-reference.md: six runnable-examples table cells.
- docs/version-history.md: new v7.7.2 entry. v7.5-v7.7 narrative
  sections left in original language (deferred per operator).
- Version bumped 7.7.1 → 7.7.2 in package.json,
  .claude-plugin/plugin.json, README badge + Recent versions,
  CLAUDE.md header + state, docs/version-history.md, playground
  renderHome hardcoded string, root README + CLAUDE.md llm-security
  entries.

Tests: 1820/1820 green. CLI smoke-test: 18/18 commandIds produce
>138 KB self-contained HTML. Browser-dogfood verified.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 06:47:44 +02:00