fix(linkedin-studio): N10 — konfigurerbart målnivå-spenn [skip-docs]
C-8: gjør «praktisk anvendbar på alle nivå» til en konfigurerbar gate-akse og fjerner den hardkodede primær-personaen. 6-fils scope (KTG-valgt) — gjør targetLevel til en EKTE ende-til-ende-dimensjon i stedet for et fantomfelt: - references/longform-quality-rules.md: «non-technical line manager» → brukerens konfigurerte target-level span (domene-generelt). - config/personas.template.md: «primær trumfer» krever nå obligatorisk sekundær i MOTSATT ende av spennet; sekundær-NEI kan kun avskrives som «signal, ikke svikt» med eksplisitt ceiling-begrunnelse. Ny tekniker-ende-seed (Persona 4, Løsningsutvikler/AI-ingeniør) — tidligere kun 3 leder-personas. - config/edition-state.template.json: additivt articles.NN.targetLevel-slot (default null, INGEN schemaVersion-bump — samme mønster som sourceTrendId/language). - commands/newsletter.md: persister resolvert targetLevel ved Step 1.5-checkpointet. - agents/persona-reviewer.md: leser articles.NN.targetLevel og plasserer personaene på spennet (fallback til persona-ekspertise om feltet er null). Premiss-korreksjon: planens 4-fils scope antok targetLevel fantes i edition-state via N7-broen; det stemte ikke (fantes kun i trend-store + fritekst-mapping). +2 filer (edition-state-slot + newsletter-persist) gjør konsumet reelt. TDD: ny Section 16q i test-runner (9 UNCOND. .md/.json-greps + non-vacuity self-test); en vacuity-bug i egen edition-state-check fanget og skjerpet (grep slot-literal "targetLevel": null, ikke bare ordet — sourceTrendId-docstringen inneholder allerede "targetLevel"). test-runner 154→163/0, anti-erosion floor 137→146. Øvrige fem suiter uendret grønne (trends 300 · brain 134 · hooks 140 · tests 35 · render 60). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014bE7VbkmR3cqHFEeGfzgwb
This commit is contained in:
parent
34c6c854c0
commit
08106317db
6 changed files with 186 additions and 17 deletions
|
|
@ -33,7 +33,8 @@
|
|||
"pivots": "Per-article pivot log (Endring 9c). A pivot is a substantive change to a draft AFTER a gate had already cleared — e.g. a new argument anchor / section added late (the Del 4 Security Champions case: +~530 words, 2 new sections, +42 %). Each /linkedin:pivot invocation appends one entry and moves currentPhase back so the cleared gates (Steps 5–6.5) re-run on the pivoted version before lock. Heuristic (documented, checked at the Step 8 lock precondition): if the current draft's word count differs > 20 % from the version that last cleared Step 6, OR it has > 2 new sections, a pivot-reopen is suggested/required. Each entry: { timestamp, reason, fromPhase, toPhase, wordCountBefore, wordCountAfter, deltaPct, newSections, gatesToRerun: [phase…] }. Default [].",
|
||||
"foldIns": "Per-article accumulation queue (slice 2 of fix #1 — «rettelser fester seg»). Each correction KTG makes during an edition that is NOT yet a contract rule is captured here, then routed by the JA-promoter (maskinrommet/docs/skrivekontrakt.md §E) to a permanent home so it never has to be re-discovered: a MECHANICAL correction → a rules.ts gate rule (BLOCK/WARN) + a §B-row/§C1/§C2-box + a §E-manifest row (the contract-gate `ratify` check then asserts rules.ts ↔ §E-manifest stay in bijection); a JUDGMENT correction → a §C2-box only (stays with editorial-reviewer, no gate rule). Capture is per-article (provenance = which article surfaced it); promotion is series/contract-wide. Each entry: { id, date (ISO-8601), correction (what KTG corrected, near-verbatim), trigger (where/why it surfaced), classification: \"mechanical-block\" | \"mechanical-warn\" | \"judgment\" | null (set at the classify step), decision: \"pending\" | \"promoted\" | \"rejected\" (the JA-promoter outcome), ruleId: <rules.ts id> | null (set on promote for mechanical), note?: where a judgment/rejected fold-in landed }. Default []. Rejected fold-ins are kept for traceability, never deleted.",
|
||||
"language": "Review language for this series/edition (additive, default \"en\"). Threads into the long-form review agents so they grade against THIS language's rules: language-reviewer applies Norwegian-specific checks (anglicism→Norwegian idiom, «kanselli-stil») only when language == \"no\"; voice-scrubber's gold standard is the approved editions IN this language; any other value → the agents apply that language's equivalents and never grade prose against Norwegian idiom. \"no\" = Norwegian (the author's case). Resolved at Step 1 / load-context and passed to the language-dependent agents.",
|
||||
"sourceTrendId": "Per-article provenance link to the trend this edition was started from (N7 trend→newsletter bridge, MR-F3). Additive-optional (default null, NO schemaVersion bump — an edition started manually never sets it, and Step 10 reads its absence as \"no source trend\"). Set at the Step 1.5 checkpoint when Step 1's trend-intake read a candidate from the trends store (scripts/trends) to prefill the brief (angle / targetLevel / key-points / source-URLs). Its ONE runtime consumer is Step 10 (scheduling): when the article reaches scheduling AND sourceTrendId is set, the command flips that trend's store status to \"acted\" (trends CLI `act --id <sourceTrendId>`), closing the discovery→production loop deterministically instead of by hand. Value = the trend's store id (normalized title+url, as shown in the /linkedin:trends brief and `CLI list --json`)."
|
||||
"sourceTrendId": "Per-article provenance link to the trend this edition was started from (N7 trend→newsletter bridge, MR-F3). Additive-optional (default null, NO schemaVersion bump — an edition started manually never sets it, and Step 10 reads its absence as \"no source trend\"). Set at the Step 1.5 checkpoint when Step 1's trend-intake read a candidate from the trends store (scripts/trends) to prefill the brief (angle / targetLevel / key-points / source-URLs). Its ONE runtime consumer is Step 10 (scheduling): when the article reaches scheduling AND sourceTrendId is set, the command flips that trend's store status to \"acted\" (trends CLI `act --id <sourceTrendId>`), closing the discovery→production loop deterministically instead of by hand. Value = the trend's store id (normalized title+url, as shown in the /linkedin:trends brief and `CLI list --json`).",
|
||||
"targetLevel": "Per-article target-level for the edition (N10 / C-8). Additive-optional (default null, NO schemaVersion bump — same pattern as sourceTrendId/language; an edition that never resolves one leaves it null and the reader agents fall back to each persona's own `ekspertise` field). Fixes WHERE this edition sits on the configured target-level span (references/longform-quality-rules.md + config/personas.template.md): it tells persona-reviewer which end is the reader-facing (primær) end and which is the mandatory-secondary end, so «practically usable at all levels» is judged from both ends rather than one baked-in reader role. Set at Step 1 of /linkedin:newsletter — the N7 trend bridge / N6 proposal layer pre-fills it from the trend record's `targetLevel` (scripts/trends), the operator confirms or edits it during calibration, and it is persisted here at the Step 1.5 checkpoint (alongside sourceTrendId). Free-text level descriptor (e.g. \"line leader → solution engineer\", \"beginner → practitioner\"), NOT an enum — the span is domain-general and defined by the operator's persona set, never hardcoded."
|
||||
},
|
||||
"schemaVersion": 1,
|
||||
"series": {
|
||||
|
|
@ -92,7 +93,8 @@
|
|||
"foldIns": [],
|
||||
"locked": false,
|
||||
"scheduled": null,
|
||||
"sourceTrendId": null
|
||||
"sourceTrendId": null,
|
||||
"targetLevel": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ cp config/personas.template.md config/personas.local.md
|
|||
```
|
||||
|
||||
`personas.local.md` is gitignored (via `*.local.md`) so your active overrides
|
||||
stay local. The template ships the three Seres seed personas below; clone,
|
||||
stay local. The template ships the four Seres seed personas below; clone,
|
||||
trim, or extend them per series.
|
||||
|
||||
---
|
||||
|
|
@ -23,11 +23,16 @@ trim, or extend them per series.
|
|||
- **Per-project selection.** `/linkedin:newsletter` (Step 1) picks the relevant
|
||||
personas from this library and marks the primary in the edition brief.
|
||||
- **«primær trumfer».** Exactly one persona is the **primær** reader. On
|
||||
conflict between personas, the primær weighs highest. A *secondary* NO caused
|
||||
by role mismatch or an expertise ceiling («this I already know cold») is a
|
||||
SIGNAL that the gate works — accept it, do not distort the text to chase it.
|
||||
A *primær* NO is **not** accepted: the text is revised until the primær
|
||||
reaches a clean YES.
|
||||
conflict between personas, the primær weighs highest. But the active set MUST
|
||||
include a **mandatory secondary at the opposite end of the target-level span**
|
||||
from the primær (a technical reader when the primær is non-technical, and vice
|
||||
versa) — one reader alone cannot certify a text «practically usable at all
|
||||
levels», so a lone primær JA is not enough. A *secondary* NO caused by role
|
||||
mismatch or an expertise ceiling («this I already know cold») is a SIGNAL that
|
||||
the gate works — but it may be waived as «signal, not failure» **only with an
|
||||
explicit ceiling justification** that names which end of the span hit its
|
||||
ceiling; an unexplained secondary NO is a real flag, not a free pass. A *primær*
|
||||
NO is **not** accepted: the text is revised until the primær reaches a clean YES.
|
||||
- **Two sweep modes** (same `persona-reviewer` agent): resonance mode (Step 6,
|
||||
BEFORE lock — «does the point land for this reader?») and conversion mode
|
||||
(Step 9, after lock — binary «would YOU click?» on the hook only).
|
||||
|
|
@ -64,8 +69,9 @@ can be promoted to a reusable block by pasting them into `personas.local.md`
|
|||
|
||||
The persona sweep is not advisory — it returns a **blocking verdict**
|
||||
(PASS / REWORK / BLOCK), and the bar is the **primær reader's genuine, unqualified
|
||||
JA**. The three Seres seed personas are the canonical set: **A = IT-divisjonsdirektør**
|
||||
(sekundær), **B = KI-seksjonsleder** (sekundær), **C = Linjeleder** (PRIMÆR — trumfer).
|
||||
JA**. The four Seres seed personas are the canonical set: **A = IT-divisjonsdirektør**
|
||||
(sekundær), **B = KI-seksjonsleder** (sekundær), **C = Linjeleder** (PRIMÆR — trumfer),
|
||||
**D = Løsningsutvikler/AI-ingeniør** (sekundær — the mandatory technical end opposite C).
|
||||
|
||||
- **Bar = C ekte JA.** A clean, unqualified yes from the primær. **«JA med store
|
||||
forbehold» = NEI.**
|
||||
|
|
@ -143,6 +149,27 @@ pipeline and the structural check key off them:
|
|||
- **sjargong** — Lav toleranse for teknisk sjargong; setter pris på presise,
|
||||
hverdagsnære formuleringer.
|
||||
|
||||
### Persona 4 — Løsningsutvikler/AI-ingeniør (sekundær)
|
||||
|
||||
> **Technical end of the target-level span** (opposite the primær persona). The
|
||||
> mandatory secondary the «primær trumfer» rule requires: if the primær (Linjeleder)
|
||||
> anchors the reader-facing end, this persona anchors the technical end, so a text
|
||||
> that claims to work «at all levels» is judged from both ends, not just one.
|
||||
|
||||
- **rolle** — Bygger og drifter AI-løsningene i praksis (utvikler, ML-ingeniør eller
|
||||
løsningsarkitekt); skriver koden, velger modellene, eier integrasjonene.
|
||||
- **avkobler** — Ledelses-abstraksjoner uten teknisk substans; «AI-magi» uten hvordan;
|
||||
påstander om hva som er mulig som ikke tåler et implementasjons-blikk; nedlatende
|
||||
forenkling av ting hen kan fra innsiden.
|
||||
- **overbeviser** — Konkret hvordan-det-faktisk-virker, ærlige begrensninger og
|
||||
feilmodi, reelle avveininger (latency/kost/kvalitet), og respekt for at
|
||||
dømmekraften i systemdesign er ekte fag.
|
||||
- **ekspertise** — Høy teknisk. Ekspertise-tak på grunnleggende forklaringer: en
|
||||
«hva er en API»-passasje faller flatt (sekundær-NEI her er et signal — men bare
|
||||
med eksplisitt ceiling-begrunnelse, jf. «primær trumfer»).
|
||||
- **sjargong** — Høy toleranse for teknisk/kode-sjargong; lav for lederspråk og
|
||||
konsulent-buzzwords.
|
||||
|
||||
---
|
||||
|
||||
## Adding a persona
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue