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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue