fix(linkedin-studio): N24.5 — mekanisk gjeldssveip (plugin.json, CHANGELOG-dublett, de-niche, KTG, Step 9-nøkler) [skip-docs]

Fem grep-lokaliserte gjeldsposter fra STATE FUNN, pluss to anti-erosjons-lints
som gjør to av dem terminale i stedet for gjenoppdaget en gang til.

1. .claude-plugin/plugin.json description — v4.0.0-arvet release-notat med
   historiske tellinger («→ 19 agents», «→ 27 commands», «→ 29 commands»)
   erstattet av en beskrivelse av hva pluginen ER. Dette er teksten /plugin
   viser. Ingen tellinger i teksten: de drifter, og CHANGELOG.md eier historikken.

2. CHANGELOG hadde TO «## [0.6.0]»-overskrifter (2026-07-17 = ekte, 2026-02-07 i
   halen). Halens datert om til «## [0.6.0-legacy]». Sjette gangs gjenoppdagelse
   — derfor lint, se punkt 6.

3. De-niche: 7 «thought leader»-treff utenfor commands/ rettet — README (mot
   kommandoens egen frontmatter-ordlyd), skills/linkedin-networking (2:
   FUNN-listen navnga bare :9, men :185 var samme defekt), analytics-interpreter,
   analytics-tools-guide, collaborations-guide, linkedin-visual-style.
   BEVISST BEHOLDT: de 5 blocklist-linjene, de to negative eksemplene
   (opportunity-generation, det ironiske sitatet i video-strategy-guide), og
   network-builder:562 — et WebSearch-uttrykk som treffer hvordan ANDRE
   merker seg selv, allerede paret med «Creator».

4. Hardkodet «KTG» i generisk operatør-tiltale fjernet. FUNN navnga tre linjer i
   language-reviewer; klassen var 21 linjer over 4 agenter, newsletter.md,
   edition-state-templaten og specifics-bank sitt renderte NN-kilder.md-artefakt.
   BEVISST BEHOLDT som proveniens: CHANGELOG, tests/fixtures/* (de ER KTGs
   faktiske redaktørrunde, kalibreringsfasiten), adopter-notatene som ærlig
   flagger KTG-interne verktøy (contract-gate, specifics-bank), «KTG
   cover-directive» og «answers KTG's question» — attribusjon, ikke tiltale.

5. Step 9 persisterte tre nøkler templaten aldri deklarerte: randsoneGate (N9),
   hookForge + personaSweep.deling (N24). Nå deklarert i BÅDE artikkel-shapen og
   _doc. Additivt, schemaVersion forblir 1. _doc.hookForge bærer N22-invarianten
   videre: en variant har målt lengde / krok-type / kroppsspor og ALDRI en
   predikert engagement-score.

6. To nye ubetingede lints (Section 16aa), begge mutasjonstestet mot de FAKTISKE
   filene, ikke bare mot self-testen:
   - CHANGELOG-dublettvakt (+ in-memory non-vakuitets-self-test som skiller en
     ekte dublett fra en bevisst «-legacy»-overskrift)
   - Step 9-nøkkeldeklarasjon (shape + _doc)
   Mutasjon 1 (gjeninnfør dubletten) → rødt. Mutasjon 2 (fjern hookForge fra
   shapen) → rødt. Mutasjon 3 (fjern _doc.randsoneGate, fila fortsatt gyldig
   JSON) → rødt. Restaurert → grønt.

Ti suiter grønne: test-runner 300 → 303 (floor 281 → 284) · trends 300 ·
analytics 202 · hooks 191 · brain 134 · editions 72 · render 63 ·
specifics-bank 45 · tests 35 · contract-gate 33.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vMLTF7J13jJmgqwwJyivt
This commit is contained in:
Kjell Tore Guttormsen 2026-07-31 21:46:35 +02:00
commit e38f71f418
17 changed files with 97 additions and 31 deletions

View file

@ -64,7 +64,7 @@ export function renderKilder(input: RenderKilderInput): string {
out.push(`# Kilder — ${title} (${articleId})`, "");
out.push(
"> Auto-generert fra edition-state `livedSpecifics` + specifics-bank. Per lastbærende påstand: hva backer den.",
"> Levd materiale er KTGs egne ord, aldri AI-oppdiktet (retning §3). Tall er uverifiserte til fakta-sjekket (regel 6/7).",
"> Levd materiale er operatørens egne ord, aldri AI-oppdiktet (retning §3). Tall er uverifiserte til fakta-sjekket (regel 6/7).",
"",
);
out.push("## Lastbærende påstander", "");

View file

@ -62,7 +62,7 @@ describe("renderKilder — the NN-kilder.md artifact", () => {
const expected = `# Kilder — Maskinrommet (05)
> Auto-generert fra edition-state \`livedSpecifics\` + specifics-bank. Per lastbærende påstand: hva backer den.
> Levd materiale er KTGs egne ord, aldri AI-oppdiktet (retning §3). Tall er uverifiserte til fakta-sjekket (regel 6/7).
> Levd materiale er operatørens egne ord, aldri AI-oppdiktet (retning §3). Tall er uverifiserte til fakta-sjekket (regel 6/7).
## Lastbærende påstander

View file

@ -3243,6 +3243,66 @@ fi
echo ""
# --- Section 16aa: Debt-Sweep Anti-Erosion (N24.5) ---
echo "--- Debt-Sweep Anti-Erosion (N24.5) ---"
# Two defects that a one-time fix does NOT make terminal, because nothing watches them:
# (a) CHANGELOG duplicate version heading. A duplicated "## [x.y.z]" makes the changelog
# ambiguous about which entry a version actually is, and it was rediscovered SIX times
# before this lint existed - each time fixed by hand, each time silently reintroduced by
# the next release edit. Structural, so a grep settles it: no version number may head two
# sections. A deliberately retained historical entry keeps a distinct heading (the
# "-legacy" suffix), which is exactly what makes it visible instead of ambiguous.
# (b) Step 9 persisting state keys the schema template never declares. The template IS the
# schema-of-record an adopter copies; a key that only exists because a command writes it
# is undeclared state, and the drift is invisible until someone reads both files side by
# side. N9 set the precedent (randsoneGate), N24 repeated it twice (hookForge,
# personaSweep.deling) - the pattern recurs precisely because the additive keys are
# backward-compatible and therefore cost nothing to forget.
# The (a) predicate carries a non-vacuity self-test (mirrors 16p/16y/16z): a duplicate-detector
# that never fires would pass a duplicated changelog forever. All checks are UNCONDITIONAL.
dup_version_headings() { # reads stdin; echoes each version number that heads more than one section
grep -oE '^## \[[0-9]+\.[0-9]+\.[0-9]+\]' | sort | uniq -d
}
# Self-test (in-memory, no temp files): the detector must fire on a known duplicate and stay
# silent on distinct headings - including the "-legacy" form used to disambiguate a kept entry.
SELFTEST_DUP=$(printf '## [1.2.0] - 2026-01-01\n## [1.1.0] - 2025-12-01\n## [1.2.0] - 2025-06-01\n' | dup_version_headings)
SELFTEST_CLEAN=$(printf '## [1.2.0] - 2026-01-01\n## [1.2.0-legacy] - 2025-06-01\n## [1.1.0] - 2025-12-01\n' | dup_version_headings)
if [ -n "$SELFTEST_DUP" ] && [ -z "$SELFTEST_CLEAN" ]; then
pass "duplicate-heading self-test: repeated version caught, distinct -legacy heading ignored"
else
fail "duplicate-heading self-test failed - the detector no longer distinguishes a duplicate from a distinct heading"
fi
CHANGELOG_DUPS=$(dup_version_headings < CHANGELOG.md)
if [ -z "$CHANGELOG_DUPS" ]; then
pass "CHANGELOG has no duplicated version heading (each '## [x.y.z]' heads exactly one section)"
else
fail "CHANGELOG version heading(s) duplicated - rename the historical entry (e.g. '-legacy') so the version is unambiguous:"
echo "$CHANGELOG_DUPS"
fi
# (b) every key Step 9 persists must be declared in the schema template - shape AND _doc.
if python3 - <<'PYEOF' 2>/dev/null
import json, sys
d = json.load(open("config/edition-state.template.json"))
art = d["articles"]["01"]
doc = d["_doc"]
missing = [k for k in ("hookForge", "randsoneGate") if k not in art]
missing += ["personaSweep.deling"] if "deling" not in art.get("personaSweep", {}) else []
missing += [f"_doc.{k}" for k in ("hookForge", "randsoneGate", "personaSweep") if k not in doc]
sys.exit(1 if missing else 0)
PYEOF
then
pass "edition-state template declares every Step 9 key (hookForge, randsoneGate, personaSweep.deling) in shape + _doc"
else
fail "config/edition-state.template.json is missing a key Step 9 persists - undeclared state drifts from the schema-of-record"
fi
echo ""
# --- Section 18: Assertion-Count Anti-Erosion (SC6) ---
# The lint self-modifies its own checks, so a green run could mask a silently dropped
# assertion. Pin the total pass()+fail() invocations as a monotonic floor; the count
@ -3337,7 +3397,7 @@ echo ""
# the count), so it is bumped only by UNCONDITIONAL new checks — NOT pinned to the
# deps-present TOTAL_CHECKS (that would zero the warn-skip margin and false-fail a fresh
# clone). Runs last so TOTAL_CHECKS sees every prior check.
ASSERT_BASELINE_FLOOR=281
ASSERT_BASELINE_FLOOR=284
TOTAL_CHECKS=$((PASS + FAIL))
if [ "$TOTAL_CHECKS" -ge "$ASSERT_BASELINE_FLOOR" ]; then
pass "assertion-count anti-erosion: $TOTAL_CHECKS checks >= baseline floor $ASSERT_BASELINE_FLOOR"