feat(okr): retrieval-SKILL m/ OKF-mønster + fixtures (SC1,SC4) [skip-docs]

This commit is contained in:
Kjell Tore Guttormsen 2026-06-26 14:39:46 +02:00
commit bf0e463b4a
17 changed files with 420 additions and 0 deletions

View file

@ -0,0 +1,148 @@
---
name: okr-second-brain-search
description: >-
Search the user's personal OKR/organization "second brain" — an OKF-compatible
markdown wiki under .claude/okr/ (project) and ~/.claude/okr/org/ (home) — to
retrieve the right strategic, governance, or cycle context on demand, in free
chat and during /okr:* commands, without pre-injecting everything. Use whenever
the user refers to their own goals, tildelingsbrev, strategy, steering signals,
or a previous cycle and the answer likely lives in their wiki rather than the
prompt. Triggers on: "våre mål", "overordnede mål", "mål dette tertialet",
"tertialmål", "tildelingsbrev", "hva sier OKR-ene våre", "forrige syklus",
"strategi", "styringssignaler".
version: "1.6.0"
---
# OKR Second-Brain Search
Retrieve the *right* personal/organizational OKR context at the *right* moment by
searching a user-owned, OKF-compatible markdown wiki with native tools only —
**Glob, Read, Grep**. No MCP, no search engine, no pre-injection. This is the
on-demand counterpart to the `inject-okr-context` hook: the hook emits only a
tiny pointer; this skill does the actual retrieval when the conversation needs it.
## When to use
Activate when the user references their own goals, governance documents, strategy,
or prior cycles — in free chat **or** under an `/okr:*` command — and the answer
plausibly lives in their wiki rather than in the prompt. Typical Norwegian cues
are listed in `Triggers on:` above ("våre mål", "tildelingsbrev", "forrige
syklus", "styringssignaler", …). Do **not** activate for generic OKR methodology
questions — those belong to the `okr-offentlig-sektor` skill.
## The two bundle roots
The second brain lives in **two roots with different lifecycles**; always search
both, project first:
1. **Project bundle**`.claude/okr/` in the current working directory
(cycle/work data, cwd-bound): `strategisk-kontekst/`, `syklus/<id>/`,
`historikk/`, `dokumenter/`.
2. **Home bundle**`~/.claude/okr/org/` (organization identity, survives
reinstall).
Each root carries its own `index.md` per level and an `okf_version` marker on its
root `index.md`. Project content overrides home content on conflict
(most-specific-wins, mirroring the hook's resolution).
## OKF layout (what you are searching)
The wiki follows the Knowledge Catalog **"Documents / `kb` Layout"** ("Metadata as
Code"). Each **concept file** carries YAML frontmatter in this field order:
```yaml
---
type: Tildelingsbrev # Title-Case human string; the only de-facto required field
resource: https://… # URL/path to the source
title: …
description: …
tags: # YAML list (multi-line) — optional
- styring
timestamp: '2026-01-15T09:00:00+00:00' # ISO-8601, quoted
---
# Heading
…body…
```
`type` values you will encounter: `Tildelingsbrev`, `OKR`, `Retrospektiv`,
`Organisasjonsprofil`, `Virksomhetsplan`, `Status` (and occasionally others —
treat unknown types as valid, never error on them).
Each level has an **`index.md`** with **no frontmatter**, formatted as a heading
plus one bullet per concept file:
```
# Heading
* [title](relative.md) - description
```
The `index.md` is the curated table of contents for its level — use it to
navigate and to break ranking ties (below).
## Retrieval procedure
Adopt the OKF `kb-search` triad (`list_contents` / `read_file` / `search_content`
≡ Glob / Read / Grep) together with the `discovery` quality pattern (semantic
decomposition). Concretely:
1. **Locate & navigate.** Glob both roots — `.claude/okr/**/*.md` and
`~/.claude/okr/org/**/*.md`. Read each level's `index.md` first to understand
what exists before reading any concept file.
2. **Semantic decomposition***do not* grep the user's words verbatim. Generate
**up to 3 query variations** and search all of them:
- **(i) Direct + synonyms** — the literal term plus close synonyms
(e.g. "mål" → "mål", "objective", "OKR").
- **(ii) Domain translation** — map everyday phrasing to the domain/governance
vocabulary actually written in the files (e.g. "hva må vi levere" →
"tildelingsbrev", "styringssignal"; "forrige runde" → "retrospektiv",
"historikk").
- **(iii) Broader category** — fall back to the `type:` or the containing level
(e.g. search `type: OKR` under `syklus/`, or `type: Tildelingsbrev` under
`strategisk-kontekst/`).
3. **Grep** each variation across the concept files (token in body/frontmatter,
or `type:` for category queries). Exclude `index.md` from concept matches.
4. **Merge, dedup, and rank.** Combine the hits from all variations, dedup by
path, then rank by this **deterministic tie-break**:
- **+2** if the token appears in the file's **frontmatter** (`title`/`type`/`tags`).
- **+1** if the token appears in the file's entry in the nearest **`index.md`**.
- On equal score, the file listed **earlier in its `index.md`** wins; final ties
break by path order.
This is exactly the ranking the regression test (`tests/okf-retrieval.test.mjs`)
pins: a frontmatter/index match outranks a body-only match, so a shared token
resolves to the concept that *names* it rather than one that merely mentions it.
5. **Read only the top concept file(s)** — usually one. Do not bulk-read the tree;
the point is selective retrieval. Cite the file path you used.
### Robustness
- **Dangling links** in an `index.md` (a bullet pointing at a missing file): skip
silently, never fail.
- **Unknown `type:`**: accept it; rank and read as normal.
- **Empty/greenfield wiki**: if neither root exists or has concept files, say so
briefly and proceed from the prompt — never fabricate wiki content.
## Trigger smoke-test (Assumption 1 — manual)
Skill activation is model-judged, not unit-testable. Verify it manually:
- **`/doctor`** — confirm `okr-second-brain-search` is listed and its
`description` is not trimmed by the skill-listing budget. If trimmed, raise
`skillListingBudgetFraction` (the `Triggers on:` phrases are placed early in the
description precisely so the highest-signal cues survive trimming).
- **Free-chat probe** — with a populated `.claude/okr/`, send a prompt with **no**
`/okr:*` command, e.g. *"Hva sier tildelingsbrevet vårt om mål dette tertialet?"*
The skill should activate and retrieve from `strategisk-kontekst/` and
`syklus/<id>/` without being told where to look.
- **Fallback** — if activation does not fire, the `inject-okr-context` hook still
emits a deterministic pointer to the resolved `index.md`, and any `/okr:*`
command can invoke this skill explicitly. Retrieval degrades, it does not break.
## Resources
- **Wiki data (project):** `.claude/okr/``strategisk-kontekst/`, `syklus/<id>/`,
`historikk/`, `dokumenter/`, each with an `index.md`.
- **Wiki data (home):** `~/.claude/okr/org/` — organization profile bundle.
- **Index/check tooling:** `scripts/okf-index.mjs` (regenerate `index.md` per root)
and `scripts/okf-check.mjs` (validate every concept file has `type:`).
- **Companion skill:** `okr-offentlig-sektor` for OKR methodology (writing,
scoring, cascading) — this skill only *retrieves* the user's own context.