okf 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +493 -133
- data/README.md +101 -10
- data/lib/okf/bundle/folder.rb +4 -0
- data/lib/okf/bundle.rb +25 -1
- data/lib/okf/cli/catalog.rb +66 -0
- data/lib/okf/cli/command.rb +495 -0
- data/lib/okf/cli/files.rb +68 -0
- data/lib/okf/cli/graph.rb +82 -0
- data/lib/okf/cli/index.rb +127 -0
- data/lib/okf/cli/lint.rb +139 -0
- data/lib/okf/cli/loose.rb +78 -0
- data/lib/okf/cli/registry.rb +229 -0
- data/lib/okf/cli/render.rb +66 -0
- data/lib/okf/cli/search.rb +285 -0
- data/lib/okf/cli/server.rb +179 -0
- data/lib/okf/cli/skill.rb +57 -0
- data/lib/okf/cli/stats.rb +88 -0
- data/lib/okf/cli/tags.rb +122 -0
- data/lib/okf/cli/types.rb +37 -0
- data/lib/okf/cli/validate.rb +66 -0
- data/lib/okf/cli.rb +418 -1703
- data/lib/okf/render/graph/template.html.erb +1020 -61
- data/lib/okf/render/graph.rb +46 -2
- data/lib/okf/server/app.rb +10 -4
- data/lib/okf/server/hub/not_found.rb +663 -0
- data/lib/okf/server/hub.rb +504 -38
- data/lib/okf/skill/SKILL.md +14 -10
- data/lib/okf/skill/playbooks/curate.md +3 -1
- data/lib/okf/skill/playbooks/maintain.md +3 -2
- data/lib/okf/skill/playbooks/menu.md +5 -0
- data/lib/okf/skill/playbooks/refine.md +92 -0
- data/lib/okf/skill/reference/cli.md +22 -4
- data/lib/okf/version.rb +1 -1
- metadata +19 -1
data/lib/okf/skill/SKILL.md
CHANGED
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
working in a repo that already carries an OKF bundle — a `.okf/` directory or a
|
|
14
14
|
root `index.md` carrying `okf_version`.
|
|
15
15
|
user-invocable: true
|
|
16
|
-
argument-hint: "[search|produce|migrate|maintain|consume|curate|doctor|<okf-cli-verb>] [dir|@slug] [--flags]"
|
|
16
|
+
argument-hint: "[search|produce|migrate|maintain|refine|consume|curate|doctor|<okf-cli-verb>] [dir|@slug] [--flags]"
|
|
17
17
|
allowed-tools: Read Write Edit Grep Glob Bash
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -123,10 +123,12 @@ when you need chapter and verse.
|
|
|
123
123
|
|
|
124
124
|
**No subcommand?** Infer intent: "document this / capture X" → `produce`;
|
|
125
125
|
"convert / migrate / OKFy these existing docs into a bundle" → `migrate`; "the
|
|
126
|
-
code changed, update the docs" → `maintain`; "
|
|
127
|
-
is
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
code changed, update the docs" → `maintain`; "restructure / rebalance the
|
|
127
|
+
bundle / is the structure right / get more out of it" → `refine`; "what do we
|
|
128
|
+
know about X / where is X documented" → `search`; a repo already carrying a
|
|
129
|
+
bundle plus a task needing its knowledge → `consume`; "check / graph / preview
|
|
130
|
+
it" → run the matching CLI verb and interpret the result. When genuinely
|
|
131
|
+
ambiguous, ask.
|
|
130
132
|
|
|
131
133
|
**Which target?** A leading `@` is a *registry ref*, not a path: `@slug` names a
|
|
132
134
|
bundle registered with `okf registry set`, bare `@` the default — route it
|
|
@@ -158,15 +160,17 @@ Read the referenced playbook before executing — it *is* the procedure.
|
|
|
158
160
|
| `produce` | Author | create or extend a bundle | [playbooks/produce.md](playbooks/produce.md) |
|
|
159
161
|
| `migrate` | Author | convert existing docs in place: frontmatter + reserved files, bodies verbatim | [playbooks/migrate.md](playbooks/migrate.md) |
|
|
160
162
|
| `maintain` | Author | sync the bundle's content with reality after a change | [playbooks/maintain.md](playbooks/maintain.md) |
|
|
163
|
+
| `refine` | Author | optimize the bundle's structure: evidence-driven, cohesion-first; proposes, never auto-applies | [playbooks/refine.md](playbooks/refine.md) |
|
|
161
164
|
| `consume` | Use | use the bundle as context for a task | [playbooks/consume.md](playbooks/consume.md) |
|
|
162
165
|
| `curate` | Curate | structural upkeep as it stands: validate + lint + loose | [playbooks/curate.md](playbooks/curate.md) |
|
|
163
166
|
| `doctor` | Setup | install and verify the CLI, then doctor the bundle | [playbooks/doctor.md](playbooks/doctor.md) |
|
|
164
|
-
| `<okf-cli-verb>` | Read | validate, lint, loose, index, catalog, files, tags, types, stats, graph, server, render, registry, skill | `okf <verb> --help` + [reference/cli.md](reference/cli.md) |
|
|
167
|
+
| `<okf-cli-verb>` | Read | validate, lint, loose, index, catalog, files, tags, types, stats, graph, server, render, registry, skill — **plus any verb an installed extension adds** (`okf help` is authoritative, this list is not) | `okf <verb> --help` + [reference/cli.md](reference/cli.md) |
|
|
165
168
|
|
|
166
|
-
|
|
167
|
-
the *content* no longer matches reality, that is `maintain
|
|
168
|
-
|
|
169
|
-
the
|
|
169
|
+
Three boundaries worth keeping sharp: `curate` is structural upkeep only — when
|
|
170
|
+
the *content* no longer matches reality, that is `maintain`, and when the
|
|
171
|
+
content is right but the *shape* underserves retrieval, that is `refine` — and
|
|
172
|
+
`doctor` is the one playbook that does not assume the CLI is installed. In
|
|
173
|
+
Claude Code with the okf plugin, `/okf:gem` routes these same verbs.
|
|
170
174
|
|
|
171
175
|
## The lifecycle is a flywheel, not phases
|
|
172
176
|
|
|
@@ -9,7 +9,9 @@ reachability, backlog, completeness, hygiene. It is not `maintain`, the
|
|
|
9
9
|
skill's workflow for when the project changed and the bundle's *content*
|
|
10
10
|
must catch up with reality; reach for that one when what is written stopped
|
|
11
11
|
being true. Curating can surface semantic staleness, and when it does,
|
|
12
|
-
switch to `maintain` for those concepts.
|
|
12
|
+
switch to `maintain` for those concepts. And it never moves knowledge: when
|
|
13
|
+
the content is right but the shape underserves retrieval — fat areas,
|
|
14
|
+
mis-homed hubs, an uncurated tag layer — that is [refine](refine.md).
|
|
13
15
|
|
|
14
16
|
1. Locate the bundle: the directory you were given, if any; otherwise a
|
|
15
17
|
`.okf/` directory or a root `index.md` whose frontmatter carries
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Playbook: maintain — keep a bundle in sync with reality
|
|
2
2
|
|
|
3
3
|
Reach for this when the project changed and the bundle's *content* must catch
|
|
4
|
-
up.
|
|
5
|
-
[
|
|
4
|
+
up. Restructuring the bundle itself — moving concepts, adding areas — is
|
|
5
|
+
[refine](refine.md), not maintain. The modelling craft behind steps 3 and 7
|
|
6
|
+
lives in [authoring.md](../reference/authoring.md).
|
|
6
7
|
|
|
7
8
|
1. **Orient before hunting.** Run `okf index <dir>` (the §6 map — every directory's
|
|
8
9
|
index body, rollups, and listings), read `log.md` (the §7 baseline: what changed
|
|
@@ -33,6 +33,11 @@ is the lede.
|
|
|
33
33
|
the working tree has uncommitted changes to the code the bundle describes
|
|
34
34
|
(`git status`), prefer **`maintain`**: that is exactly the drift it exists
|
|
35
35
|
to close.
|
|
36
|
+
- **clean, but the shape strains** — one area dwarfing the rest in
|
|
37
|
+
`okf stats`, tags spread thin across areas in `okf tags --by area`, hubs
|
|
38
|
+
whose inbound links are mostly foreign in `okf graph --hubs` → offer
|
|
39
|
+
**`refine`** (evidence-driven restructuring; it proposes before it
|
|
40
|
+
touches anything).
|
|
36
41
|
4. **Freshness is off by default.** If the bundle carries timestamps, note that a
|
|
37
42
|
plain `lint` said nothing about staleness and `okf lint <root> --stale-after
|
|
38
43
|
90d` is the check that would.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Playbook: refine — restructure a bundle to get the most from OKF
|
|
2
|
+
|
|
3
|
+
Reach for this when the bundle's *content* is right but its *shape* may not be:
|
|
4
|
+
areas grown fat by additive passes, hubs homed by history, a tag layer that
|
|
5
|
+
never became the second index. Refine optimizes the projection — the same
|
|
6
|
+
knowledge, arranged to serve progressive disclosure, the emergent graph,
|
|
7
|
+
cross-cutting tags, and capture-once-link-many. It is not [curate](curate.md)
|
|
8
|
+
(upkeep of the structure as it stands) and not [maintain](maintain.md) (content
|
|
9
|
+
catching up with reality): refine changes where knowledge lives, never what it
|
|
10
|
+
says. Its permitted edits are structural — move a concept, extract a duplicated
|
|
11
|
+
fact to one home, section an index, retag, relink, and write the connective
|
|
12
|
+
sentence a link lives in; summarizing, updating, or correcting a body is
|
|
13
|
+
maintain's job, reached by switching verbs, not by stretching this one.
|
|
14
|
+
|
|
15
|
+
The frame that governs every move: the directory tree is a **lossy projection
|
|
16
|
+
of the link graph**. A tree gives each concept one parent, so the tree encodes
|
|
17
|
+
only the single dominant decomposition; every genuinely many-to-many
|
|
18
|
+
relationship rides links and tags, never new directories. And cohesion outranks
|
|
19
|
+
balance — a move has semantic cost, so balance is a tiebreaker and a fatness
|
|
20
|
+
alarm, never the objective. <!-- rule:okf-cohesion-over-balance -->
|
|
21
|
+
|
|
22
|
+
1. **Orient.** `okf index <dir|@slug> --no-body` (areas, fan-out, depth),
|
|
23
|
+
`log.md` (how the bundle grew), `okf stats` (totals). Additive growth
|
|
24
|
+
optimizes each pass locally, never the whole — that is the drift this
|
|
25
|
+
playbook corrects.
|
|
26
|
+
2. **Measure — the CLI is the evidence.** Baseline `validate` / `lint
|
|
27
|
+
--stale-after` / `loose` first: refine assumes a sound bundle, and hard
|
|
28
|
+
errors are [curate](curate.md)'s job. Then the two structural reads:
|
|
29
|
+
- `okf tags <dir> --by area` — each row carries `count/total`, so a tag's
|
|
30
|
+
**locality** reads directly: a tag wholly inside one area names a *domain*
|
|
31
|
+
(the directories are right); one spread across areas names a *concern*.
|
|
32
|
+
- `okf graph <dir> --hubs` — concepts ranked by inbound links, each with
|
|
33
|
+
the areas those links come from: the **origin test** for every hub.
|
|
34
|
+
3. **Diagnose — you are the judgment.** The measurements are evidence, never
|
|
35
|
+
verdicts:
|
|
36
|
+
- **Concerns never become containers.** A directory built around a spread
|
|
37
|
+
tag ("everything async") prunes nothing — most needs would enter it.
|
|
38
|
+
The cross-cut stays a tag. <!-- rule:okf-concern-not-container -->
|
|
39
|
+
- **A directory must prune.** The positive test for any area, existing or
|
|
40
|
+
proposed: does knowing "it's in there" eliminate a large, even slice? A
|
|
41
|
+
good node splits its parent into chunks that are nameable, mutually
|
|
42
|
+
exclusive, and roughly comparable in size. And small is not merge-worthy
|
|
43
|
+
on its own — a two-concept area that is a genuinely distinct domain
|
|
44
|
+
stays. <!-- rule:okf-directory-prunes -->
|
|
45
|
+
- **The hub origin test.** Inbound majority from the hub's own area:
|
|
46
|
+
well-homed, leave it. A dominant *foreign* area: that area is the better
|
|
47
|
+
home. Foreign majority with *no* dominant area: a shared primitive — the
|
|
48
|
+
only admission ticket into a shared-core area (without that test, a
|
|
49
|
+
`foundation/` rots into a `misc/`). Two comparable strong ties, one of
|
|
50
|
+
them home: stay and carry the other as a tag — moving trades one
|
|
51
|
+
imbalance for another. And in a design bundle expect the central
|
|
52
|
+
decisions to fail this test wholesale: that is centrality, not
|
|
53
|
+
mis-homing.
|
|
54
|
+
- **Fatness alarm, not fatness rule.** A fat area (≳20–25 concepts) wants
|
|
55
|
+
**heading sections inside its `index.md`** first — the same prune as
|
|
56
|
+
sub-directories, for zero extra hops and no new enumeration to keep
|
|
57
|
+
sound. Directory nesting pays only at hundreds of concepts, and only
|
|
58
|
+
where the index's own headings already form separable, nameable
|
|
59
|
+
sub-groups — fatness alone never justifies depth; the sections that
|
|
60
|
+
formed are the evidence the split exists.
|
|
61
|
+
- **Duplication.** Read the area overviews for a fact re-explained in
|
|
62
|
+
several (drifting tables are the tell); capture-once-link-many says
|
|
63
|
+
extract it into one concept and link from the rest. Extraction is the one
|
|
64
|
+
refine move that touches bodies, and it redistributes rather than
|
|
65
|
+
rewrites: assemble the canonical concept from the copies, keep every
|
|
66
|
+
copy's unique domain-specific detail (in the extract, or in the one-line
|
|
67
|
+
note left beside each link), and where the copies *disagree*, which is
|
|
68
|
+
true is a [maintain](maintain.md) question — verify against reality or
|
|
69
|
+
flag the conflict in the proposal, never silently pick a winner while
|
|
70
|
+
merging. <!-- rule:okf-extract-not-rewrite -->
|
|
71
|
+
- **Vocabulary twins.** The [maintain](maintain.md) tag-curation recipe
|
|
72
|
+
(twins, echoes, singletons) applies to `type` too — `okf types <dir>`.
|
|
73
|
+
4. **Plan — tier by leverage ÷ churn, free levers first.** Tag curation,
|
|
74
|
+
index heading-sectioning, and extraction before any file move; a move only
|
|
75
|
+
when the origin test demands one, and each gated by **do-nothing**: skip it
|
|
76
|
+
unless its value beats its churn. Record what you *declined* and why — the
|
|
77
|
+
decline list is what stops the next pass from re-proposing it.
|
|
78
|
+
5. **Propose — never auto-apply.** Refine's output is a short report (the
|
|
79
|
+
evidence, the tiers, the declines) plus a ready-to-run execution prompt the
|
|
80
|
+
user can hand back later: a scope line, the governing principles above, the
|
|
81
|
+
explicit prohibitions, the closeout gate as acceptance. Analysis and
|
|
82
|
+
execution are separate on purpose — the judgment is spent once, frozen, and
|
|
83
|
+
then executed without re-derivation. <!-- rule:okf-refine-proposes -->
|
|
84
|
+
6. **Execute only on approval**, then walk the
|
|
85
|
+
[Closeout gate](../reference/authoring.md#closeout--the-finishing-gate):
|
|
86
|
+
every touched `index.md` re-enumerated, links absolute bundle-relative so
|
|
87
|
+
they survived the moves, a dated `log.md` entry carrying the *why*,
|
|
88
|
+
validate/lint/loose clean, and a before/after of step 2's evidence.
|
|
89
|
+
|
|
90
|
+
Two traps: never split a cohesive cluster (a deliberately paired mirror flow)
|
|
91
|
+
to hit a size band, and never tag a concept with its own directory's name — a
|
|
92
|
+
group-name echo adds no edge.
|
|
@@ -20,6 +20,12 @@ The surface is self-describing — `okf --help` maps every verb, `okf <verb> --h
|
|
|
20
20
|
its flags. Ask the tool for what exists; this file carries only what `--help`
|
|
21
21
|
cannot: each verb's semantics, its traps, and its JSON shape.
|
|
22
22
|
|
|
23
|
+
**The verb list is open, not closed.** An installed extension gem adds verbs of
|
|
24
|
+
its own, listed under `installed extensions:` in `okf help`. So a verb that
|
|
25
|
+
`--help` shows and this file does not document is **normal, not a documentation
|
|
26
|
+
error** — ask `okf <verb> --help` for it, and expect nothing here about its
|
|
27
|
+
semantics or JSON. Everything below documents the built-ins only.
|
|
28
|
+
|
|
23
29
|
**`--json` is compact by design.** Every emitting verb prints single-line JSON —
|
|
24
30
|
the token-efficient substrate you consume; `--pretty` (which implies `--json`)
|
|
25
31
|
indents it for a human. The bytes differ, the JSON is identical, so parse either.
|
|
@@ -296,10 +302,14 @@ in/out link degree). Add `--json` to any for a machine substrate.
|
|
|
296
302
|
- **`tags`** — every tag with the concepts that carry it, ordered by count
|
|
297
303
|
descending. The "what themes dominate" view. JSON: `{ bundle, count, tags: [{ tag,
|
|
298
304
|
count, concepts: [id, …] }] }`. `--by type|area` regroups the list per concept
|
|
299
|
-
dimension with **within-group** counts (a tag spanning groups appears in each)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
dimension with **within-group** counts (a tag spanning groups appears in each);
|
|
306
|
+
each row also carries the tag's **total** across the narrowed set, printed
|
|
307
|
+
`count/total` when they differ — so a tag's locality reads per row (a plain
|
|
308
|
+
count = wholly local; `2/7` = a cross-cutting spread). The substrate for tag
|
|
309
|
+
curation and for [refine](../playbooks/refine.md)'s domain-vs-concern read;
|
|
310
|
+
the judgment recipes live in the [maintain playbook](../playbooks/maintain.md)
|
|
311
|
+
and the [refine playbook](../playbooks/refine.md). JSON: `{ bundle, count, by,
|
|
312
|
+
groups: [{ <dim>, count, tags: [{ tag, count, total, concepts }] }] }`.
|
|
303
313
|
- **`types`** — every type with the concepts that carry it, ordered by count
|
|
304
314
|
descending. The "what kinds of knowledge" view. JSON: `{ bundle, count, types:
|
|
305
315
|
[{ type, count, concepts: [id, …] }] }`.
|
|
@@ -427,3 +437,11 @@ drops each node's body, and `--minimal` ships only `id`/`title` plus the type/ta
|
|
|
427
437
|
indexes — the lean shape the `server` page boots from. Reach for the full dump
|
|
428
438
|
only when the task truly consumes every body; for one question, the
|
|
429
439
|
[search verb](#search--ranked-text-retrieval-metadata--body) is orders cheaper.
|
|
440
|
+
|
|
441
|
+
`--hubs` swaps the dump for the **inbound ranking**: every concept with at
|
|
442
|
+
least one inbound link, ranked by inbound degree, each with its links grouped
|
|
443
|
+
by *source area* (`core/status ×3 flows 2, billing 1`) — the evidence for
|
|
444
|
+
[refine](../playbooks/refine.md)'s hub origin test ("is this hub well-homed?").
|
|
445
|
+
A source at the bundle root counts under `(root)`. JSON: `{ bundle, count,
|
|
446
|
+
hubs: [{ id, area, inbound, by_area: { <area>: n } }] }`. Advisory read, exit 0;
|
|
447
|
+
`--minimal`/`--no-body` shape node payloads and change nothing here.
|
data/lib/okf/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: okf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rodrigo Serradura
|
|
@@ -86,6 +86,22 @@ files:
|
|
|
86
86
|
- lib/okf/bundle/validator/result.rb
|
|
87
87
|
- lib/okf/bundle/writer.rb
|
|
88
88
|
- lib/okf/cli.rb
|
|
89
|
+
- lib/okf/cli/catalog.rb
|
|
90
|
+
- lib/okf/cli/command.rb
|
|
91
|
+
- lib/okf/cli/files.rb
|
|
92
|
+
- lib/okf/cli/graph.rb
|
|
93
|
+
- lib/okf/cli/index.rb
|
|
94
|
+
- lib/okf/cli/lint.rb
|
|
95
|
+
- lib/okf/cli/loose.rb
|
|
96
|
+
- lib/okf/cli/registry.rb
|
|
97
|
+
- lib/okf/cli/render.rb
|
|
98
|
+
- lib/okf/cli/search.rb
|
|
99
|
+
- lib/okf/cli/server.rb
|
|
100
|
+
- lib/okf/cli/skill.rb
|
|
101
|
+
- lib/okf/cli/stats.rb
|
|
102
|
+
- lib/okf/cli/tags.rb
|
|
103
|
+
- lib/okf/cli/types.rb
|
|
104
|
+
- lib/okf/cli/validate.rb
|
|
89
105
|
- lib/okf/concept.rb
|
|
90
106
|
- lib/okf/concept/file.rb
|
|
91
107
|
- lib/okf/markdown/citations.rb
|
|
@@ -97,6 +113,7 @@ files:
|
|
|
97
113
|
- lib/okf/render/graph/template.html.erb
|
|
98
114
|
- lib/okf/server/app.rb
|
|
99
115
|
- lib/okf/server/hub.rb
|
|
116
|
+
- lib/okf/server/hub/not_found.rb
|
|
100
117
|
- lib/okf/server/runner.rb
|
|
101
118
|
- lib/okf/skill.rb
|
|
102
119
|
- lib/okf/skill/SKILL.md
|
|
@@ -107,6 +124,7 @@ files:
|
|
|
107
124
|
- lib/okf/skill/playbooks/menu.md
|
|
108
125
|
- lib/okf/skill/playbooks/migrate.md
|
|
109
126
|
- lib/okf/skill/playbooks/produce.md
|
|
127
|
+
- lib/okf/skill/playbooks/refine.md
|
|
110
128
|
- lib/okf/skill/playbooks/search.md
|
|
111
129
|
- lib/okf/skill/reference/APACHE-2.0.txt
|
|
112
130
|
- lib/okf/skill/reference/SPEC.md
|