Kjeden /okr:rapport -> /okr:sporing -> status.md var beskrevet i prosa, men manglet et mekanisk ledd: ingenting foerte en generert rad inn i status.md -- fila coaching-hook teller at-risk-KR i, /okr:moeter bygger agenda fra, og /okr:oppsett arkiver leser sluttscorer fra. Rot-aarsaken var at HELE sporings-stien var lesende (ingen Write/Edit/Bash i allowed-tools). scripts/syklus-status.mjs tar confidence som JSON paa stdin og bygger radene gjennom statusrapport() i lib/syklus-rapport.mjs -- samme kode som tertialrapporten. Aritmetikken kan derfor ikke drifte fra /okr:rapport, fordi det ikke finnes en andre implementasjon av den. En LLM skriver ikke av et tall paa veien, og en maskin utleder ikke et trafikklys: beslutning 9 staar, presist formulert som at generatoren PLASSERER en etikett den faar inn som data og UTLEDER aldri en. Haandhevet i kode, ikke i prosa: lukket vokabular (On Track/At Risk/Off Track), full dekning (en tom confidence-celle ville lest som groenn hos hver konsument), typo-fangst paa ukjente KR-navn, og kuratert-fil-vern -- en status.md uten provenans-noekkelen `kilde: sporing` er haandholdt og overskrives aldri (samme mekanikk som innboks-write bruker med `kilde: innboks`). Suite 329 -> 343. Fem vakter mutasjons-verifisert: rad-drift mot tertialrapporten, vokab, dekning (baade alene og sammen med vokab-vakten som overlapper den), og kuratert-vernet.
109 lines
10 KiB
Markdown
109 lines
10 KiB
Markdown
# OKR Offentlig Sektor v1.10.0
|
|
|
|
Expert OKR guidance for Norwegian public sector. Google/Doerr methodology adapted for 4-month tertial cycles.
|
|
|
|
## Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `/okr:skriv` | Write new OKR with guided Objective and KR creation |
|
|
| `/okr:kvalitet` | Quality check OKR against rubric and antipatterns |
|
|
| `/okr:kaskade` | Cascade OKR from org to team, visualize alignment |
|
|
| `/okr:sporing` | Track progress, calculate scores, generate check-ins. Owns the *confidence assessment* and writes `status.md` through `scripts/syklus-status.mjs` — never by hand, so the arithmetic cannot drift from `/okr:rapport` |
|
|
| `/okr:møter` | Plan OKR workshops, check-ins, reviews, 1:1s |
|
|
| `/okr:innføring` | OKR adoption planning, resistance handling, maturity |
|
|
| `/okr:governance` | Tildelingsbrev translation, Riksrevisjon compliance |
|
|
| `/okr:gap` | Automatic gap analysis between tildelingsbrev and current OKR |
|
|
| `/okr:analyse` | Cross-cycle analytics with Mermaid trend visualizations |
|
|
| `/okr:oppsett` | Configure plugin: onboarding interview (full/mvp), cycle archival, profile update. Args: `full\|mvp\|arkiver\|oppdater\|vis` |
|
|
| `/okr:innboks` | Ingest documents dropped in `.claude/okr/innboks/` into the OKF tree — deterministic convert/split/frontmatter/index, per-document security gate |
|
|
| `/okr:rapport` | Generate a report from cycle data. Args: `tertial` \| `arsrapport` (annual report part III) \| `etatsstyring` (agency-governance meeting brief). Owns arithmetic and formatting invariants — never confidence, and never the assessment fields it reserves for the organization |
|
|
| `/okr:export` | Export OKR deliverables (quality review, gap matrix, status report, retrospective) to print-ready PDF via weasyprint |
|
|
| `/okr:arkivklar` | Assessment basis against bevaringsforskrifta (§§ 7/30, safety-net § 3) — what in the tree likely falls under the preservation duty and should be *considered* for transfer to the case/archive system. Read-only by tool list (no `Write`/`Edit`); never decides, never deletes |
|
|
| `/okr:freshen-references` | KB self-evaluator: score 18 of the 19 domain reference files against an anchored rubric — the quality rubric itself is excluded, since scoring the scoring instrument is circular — + currency-poll public sources |
|
|
| `/okr:help` | Full overview of all commands, agents, and recommended cycle workflow |
|
|
|
|
## Agents
|
|
|
|
| Agent | Model | Color | Tools | Role |
|
|
|-------|-------|-------|-------|------|
|
|
| kvalitetssjekker | sonnet | blue | Read, Glob | Score OKR quality against rubric |
|
|
| kaskadebygger | sonnet | green | Read, Glob | Build OKR cascades between levels |
|
|
| fremdriftssporer | sonnet | yellow | Read, Glob, ToolSearch | Calculate scores and generate reports |
|
|
| møtefasilitator | sonnet | magenta | Read, Glob | Generate meeting agendas and materials |
|
|
| styringsrådgiver | opus | cyan | Read, Glob | Tildelingsbrev analysis, governance |
|
|
| gapanalytiker | sonnet | red | Read, Glob | Tildelingsbrev gap analysis and coverage matrix |
|
|
| trendanalytiker | sonnet | purple | Read, Glob | Cross-cycle trend analysis and Mermaid visualization |
|
|
|
|
## Hooks
|
|
|
|
| Event | Type | Purpose |
|
|
|-------|------|---------|
|
|
| SessionStart | command | Proactive coaching based on cycle position and OKR status |
|
|
| UserPromptSubmit | command | Inject org profile (expanded YAML), current cycle, `.claude/okr/` summary, and archived cycle count |
|
|
| PreCompact | prompt | Preserve OKR draft state during compaction |
|
|
|
|
## Skills
|
|
|
|
| Component | Location |
|
|
|-----------|----------|
|
|
| SKILL.md (okr-offentlig-sektor) | `skills/okr-offentlig-sektor/SKILL.md` |
|
|
| References (19) | `skills/okr-offentlig-sektor/references/` |
|
|
| SKILL.md (okr-second-brain-search) | `skills/okr-second-brain-search/SKILL.md` |
|
|
|
|
The second skill (`okr-second-brain-search`) does on-demand retrieval over the user's OKF-compatible wiki (native Glob/Read/Grep, no MCP) — see OKF Knowledge Layout below.
|
|
|
|
## State Management
|
|
|
|
User configuration: `.claude/okr.local.md` in the project directory (not in plugin root).
|
|
Org profile (reinstall-surviving): `~/.claude/okr/org/profil.md` — machine-global org identity (`organisasjon:`/`program:`), written atomically (temp + `renameSync`) by `scripts/write-org-profile.mjs` during `/okr:oppsett`. Resolution is most-specific-wins: project-local `.claude/okr.local.md` overrides the home profile (the backwards-compatible fallback when no project config exists; read side `hooks/scripts/inject-okr-context.mjs`). Home-write failure → circuit-break to the gitignored project-local file. Only the org *profile* migrates to home; cycle/`historikk` data stays cwd-bound.
|
|
Template: `templates/okr.local.md.template`
|
|
Context tree: `.claude/okr/` — `strategisk-kontekst/`, `syklus/[id]/`, `historikk/`, `dokumenter/`
|
|
Onboarding state: `onboarding_status` field in okr.local.md (`partial` | `fullfort`)
|
|
Cycle archival: `/okr:oppsett arkiver` — moves `syklus/` to `historikk/`, generates `retrospektiv.md`
|
|
|
|
## OKF Knowledge Layout
|
|
|
|
Context files carry OKF v0.1 Documents-style frontmatter (conforms to the OKF v0.1 minimal contract, canonized in `catalog/docs/okf-second-brain/spec.md`): a Title-Case `type` (`Organisasjonsprofil`, `Tildelingsbrev`, `Virksomhetsplan`, `Overordnede OKR`, `OKR`, `Retrospektiv`, `Status`) plus recommended `resource`/`title`/`description`/`tags`/`timestamp`. Only `type` is de-facto required. The flat frontmatter parser reads only single-line keys (`type`, profile/config fields); tree files may carry multi-line `tags` lists without breaking it. Files written by inbox ingestion additionally carry the provenance extension key `kilde: innboks`.
|
|
|
|
**Two bundle roots** with distinct lifecycles: project `.claude/okr/` (cwd-bound cycle/work) and home `~/.claude/okr/org/` (reinstall-surviving org identity). Each root carries its own `index.md` (`# H1` + `* [title](link) - description`) and, on the root index, two distinct markers (OKF spec §12): `okf_version` (the upstream OKF version targeted, currently `0.1`) and `okf_layout` (this plugin's own layout revision, currently `kb-layout-2026-06`). The two markers sit on **different surfaces** by decision 6: `okf_version` in the root index's frontmatter (the machine-readable contract consumers outside the plugin read), `okf_layout` in its body. Sub-level indexes carry no frontmatter and no markers. `okf-check` reads `okf_version` from **both** placements — frontmatter first, body as fallback — since bundles on disk do not migrate simultaneously. `okf-index`/`okf-check` run per root; retrieval Globs both roots as a union — never a short-circuit — with project content winning on conflict (`skills/okr-second-brain-search/SKILL.md:35,46,95` is the authoritative procedure). Only the org *profile* resolves by precedence (`hooks/scripts/inject-okr-context.mjs:54-56` short-circuits on the project hit).
|
|
|
|
- `lib/frontmatter.mjs` — shared frontmatter parser/writer; both hooks route through it (strips trailing ` #…` only from unquoted values).
|
|
- `scripts/okf-index.mjs` — regenerate a root's per-level `index.md` (verbatim OKF index format).
|
|
- `scripts/okf-check.mjs` — validate each concept file carries `type:` (exit 1 + count otherwise); echo `okf_version` + `okf_layout` per root (pure echo, no value validation).
|
|
- `scripts/compose-org-profile.mjs` — build the nested org-profile YAML with top-level OKF keys (`type`/`resource`/`timestamp`) before piping to `write-org-profile.mjs`.
|
|
- `scripts/syklus-status.mjs` — deterministic writer for `syklus/[id]/status.md` (`/okr:sporing`): reads confidence as JSON on stdin (KR name → `On Track` | `At Risk` | `Off Track`), builds the rows through `statusrapport()` in `lib/syklus-rapport.mjs` — the same code the tertial report uses, so the arithmetic has no second implementation to drift from. Full coverage is required (an empty confidence cell would read as green to every consumer), the vocabulary is closed, and an existing `status.md` without the provenance key `kilde: sporing` is treated as hand-curated and never overwritten. Atomic write; `OKR_NOW` makes runs byte-identical.
|
|
- `scripts/innboks-ingest.mjs` — inbox-ingestion orchestrator (`/okr:innboks`): walks `.claude/okr/innboks/`, converts (txt/md/docx/eml/pdf via `lib/convert/index.mjs`), heading-splits, stamps OKF frontmatter + `kilde: innboks`, routes by type, then gates each document with `okf-check --strict-ingest` — a failing document is discarded alone (staging + per-document rollback), survivors get relations and index entries. Non-destructive (originals stay in the inbox), idempotent by construction (timestamp = source mtime), path-confined (realpath). Binary formats need `npm install --ignore-scripts` (4 exact-pinned pure-JS deps); txt/md run dependency-free.
|
|
|
|
Retrieval is on-demand via the `okr-second-brain-search` skill. The UserPromptSubmit hook no longer pre-injects the full context-file enumeration — it emits the core profile plus one resolved pointer to `index.md` (< 512 B, independent of file count).
|
|
|
|
## Language Policy
|
|
|
|
- Commands, agents, user-facing text: Norwegian
|
|
- Code, config, technical identifiers: English
|
|
- SKILL.md: English (for broader LLM comprehension)
|
|
|
|
## Architecture
|
|
|
|
```
|
|
/okr:skriv ──→ kvalitetssjekker (auto)
|
|
/okr:kvalitet ──→ kvalitetssjekker
|
|
/okr:kaskade ──→ kaskadebygger
|
|
/okr:sporing ──→ fremdriftssporer ──→ scripts/syklus-status.mjs (skriver status.md) ──→ Linear MCP (optional)
|
|
/okr:møter ──→ møtefasilitator
|
|
/okr:governance ──→ styringsrådgiver
|
|
/okr:innføring ──→ (inline, no agent)
|
|
/okr:gap ──→ gapanalytiker
|
|
/okr:analyse ──→ trendanalytiker
|
|
/okr:oppsett ──→ (inline wizard: full/mvp/arkiver/oppdater/vis)
|
|
/okr:oppsett arkiver ──→ cycle archival + retrospektiv-generering
|
|
/okr:innboks ──→ scripts/innboks-ingest.mjs (convert → split → frontmatter → per-doc gate → relations → index)
|
|
/okr:rapport ──→ scripts/syklus-rapport.mjs ──→ lib/syklus-data.mjs (read + score) + lib/syklus-rapport.mjs (render)
|
|
/okr:export ──→ scripts/export-pdf.py (weasyprint, documented prerequisite)
|
|
/okr:arkivklar ──→ scripts/arkivklar.mjs ──→ lib/arkivklar.mjs (traverse + classify + render) + lib/path-confinement.mjs (read boundary)
|
|
/okr:freshen-references ──→ (inline KB-evaluator + currency-polling via WebSearch/Task)
|
|
/okr:help ──→ (inline command/agent/workflow overview)
|
|
SessionStart ──→ coaching-hook.mjs (proactive coaching)
|
|
UserPromptSubmit ──→ inject-okr-context.mjs (core profile + resolved index.md pointer)
|
|
okr-second-brain-search (skill) ──→ Glob/Read/Grep over .claude/okr/ + ~/.claude/okr/org/ (on-demand retrieval)
|
|
```
|