okf 1.13.0 → 2.0.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +195 -0
  3. data/README.md +25 -6
  4. data/lib/okf/bundle/folder.rb +27 -1
  5. data/lib/okf/bundle/graph.rb +12 -3
  6. data/lib/okf/bundle/linter.rb +470 -47
  7. data/lib/okf/bundle/reader.rb +10 -4
  8. data/lib/okf/bundle/references.rb +111 -0
  9. data/lib/okf/bundle/row_filter.rb +53 -0
  10. data/lib/okf/bundle/search.rb +20 -2
  11. data/lib/okf/bundle/validator/result.rb +6 -3
  12. data/lib/okf/bundle/validator.rb +267 -26
  13. data/lib/okf/bundle/writer.rb +1 -1
  14. data/lib/okf/bundle.rb +105 -4
  15. data/lib/okf/cli/catalog.rb +1 -1
  16. data/lib/okf/cli/command.rb +27 -8
  17. data/lib/okf/cli/files.rb +1 -1
  18. data/lib/okf/cli/index.rb +1 -1
  19. data/lib/okf/cli/lint.rb +70 -12
  20. data/lib/okf/cli/references.rb +97 -0
  21. data/lib/okf/cli/search.rb +2 -1
  22. data/lib/okf/cli/stats.rb +3 -39
  23. data/lib/okf/cli/tags.rb +6 -43
  24. data/lib/okf/cli/types.rb +1 -1
  25. data/lib/okf/cli/validate.rb +3 -3
  26. data/lib/okf/cli.rb +4 -1
  27. data/lib/okf/concept.rb +362 -10
  28. data/lib/okf/markdown/citations.rb +41 -4
  29. data/lib/okf/markdown/frontmatter.rb +1 -1
  30. data/lib/okf/markdown/links.rb +67 -7
  31. data/lib/okf/render/graph/template.html.erb +173 -41
  32. data/lib/okf/render/graph.rb +11 -3
  33. data/lib/okf/server/app.rb +47 -15
  34. data/lib/okf/server/hub.rb +1 -1
  35. data/lib/okf/skill/SKILL.md +14 -12
  36. data/lib/okf/skill/playbooks/curate.md +8 -3
  37. data/lib/okf/skill/playbooks/doctor.md +3 -1
  38. data/lib/okf/skill/playbooks/maintain.md +7 -6
  39. data/lib/okf/skill/playbooks/menu.md +5 -4
  40. data/lib/okf/skill/playbooks/migrate.md +31 -8
  41. data/lib/okf/skill/playbooks/produce.md +16 -9
  42. data/lib/okf/skill/playbooks/search.md +2 -2
  43. data/lib/okf/skill/reference/SPEC.md +739 -187
  44. data/lib/okf/skill/reference/authoring.md +154 -35
  45. data/lib/okf/skill/reference/cli.md +155 -42
  46. data/lib/okf/skill/templates/attested-computation.md +41 -0
  47. data/lib/okf/skill/templates/concept.md +13 -6
  48. data/lib/okf/skill/templates/root-index.md +1 -1
  49. data/lib/okf/version.rb +1 -1
  50. data/lib/okf.rb +22 -2
  51. metadata +5 -1
@@ -39,7 +39,9 @@ Verify with `okf --version` before moving on.
39
39
  directory, or a root `index.md` whose frontmatter carries `okf_version`.
40
40
  2. Found one? Run `okf validate <root>` and `okf lint <root>`, then summarize
41
41
  in a few lines: conformant or not (and the errors if not), the warning
42
- count, and the top curation findings by category.
42
+ count, the top curation findings by category, the trust/status posture the
43
+ lint stats report, and — when the Migration category fires — that the bundle
44
+ still writes v0.1 spellings and the skill's migrate playbook can move them.
43
45
  3. No bundle? Offer to bootstrap one. The okf skill knows how (its "produce"
44
46
  workflow); do not scaffold anything without the user's yes.
45
47
 
@@ -6,8 +6,8 @@ up. Restructuring the bundle itself — moving concepts, adding areas — is
6
6
  lives in [authoring.md](../reference/authoring.md).
7
7
 
8
8
  1. **Orient before hunting.** Run `okf dirs <dir>` (the shape), then `okf index
9
- <dir> --dir <branch>` on the branch the change touches (the §6 map: its index
10
- body, rollups and listing), read `log.md` (the §7 baseline: what changed
9
+ <dir> --dir <branch>` on the branch the change touches (the §8 map: its index
10
+ body, rollups and listing), read `log.md` (the §9 baseline: what changed
11
11
  last), and `okf stats <dir>` (size and shape) *before* you grep. It is the
12
12
  cheapest context and it primes the hunt — and it is the only reliable way to
13
13
  catch enumeration drift, because **grep cannot find an index entry that is
@@ -19,7 +19,8 @@ lives in [authoring.md](../reference/authoring.md).
19
19
  cannot express — and `okf graph <dir> --json --minimal` to pull the edges (the
20
20
  concepts that link *to* the ones you're touching) without paying for every body.
21
21
  Let search and the graph find them so nothing drifts silently.
22
- 3. Update bodies and `timestamp`; fix or add cross-links; create new concepts for
22
+ 3. Update bodies and `generated.at` (and `generated.by` who is making this
23
+ change, in §7's spelling); fix or add cross-links; create new concepts for
23
24
  new assets; mark retired assets with a `**Deprecation**` note rather than
24
25
  silently deleting the context that explains them.
25
26
  4. **Update every enumeration that names what you changed — including `index.md`
@@ -28,9 +29,9 @@ lives in [authoring.md](../reference/authoring.md).
28
29
  is how you verify this — re-run `okf index` and confirm each listing matches
29
30
  reality.
30
31
  5. Run `validate`, then `lint` to catch the curation drift the change introduced —
31
- new orphans, broken citations, dangling index entries. Add `--stale-after`
32
- (e.g. `90d`) if concepts carry timestamps: freshness is off by default, so a
33
- plain `lint` will not tell you what the change left stale.
32
+ new orphans, broken sources, dangling index entries, footnotes that lost
33
+ their source. `expired` reports out of the box; add `--stale-after`
34
+ (e.g. `90d`) when you also want an age cutoff, which stays off by default.
34
35
  6. **Review loose files** <!-- check:unlinked --> — run `okf loose <dir>` (the
35
36
  folder-grouped view of `lint`'s `unlinked` check): the concepts with **no
36
37
  cross-links in or out**, which
@@ -21,7 +21,7 @@ is the lede.
21
21
  text views, which are lighter than `--json` when you are reading a report
22
22
  rather than extracting structure from it. Then recommend by what they
23
23
  report, most-blocking first:
24
- - **`validate` has errors** → lead with **`curate`**: §9 conformance errors are
24
+ - **`validate` has errors** → lead with **`curate`**: §11 conformance errors are
25
25
  the only hard failures, and curate fixes them before anything else.
26
26
  - **clean `validate`, but `lint`/`loose` findings** → lead with **`curate`** to
27
27
  settle the curation debt (reachability, backlog, completeness, hygiene),
@@ -39,9 +39,10 @@ is the lede.
39
39
  with almost no internal traffic in `okf graph --traffic` → offer
40
40
  **`refine`** (evidence-driven restructuring; it proposes before it
41
41
  touches anything).
42
- 4. **Freshness is off by default.** If the bundle carries timestamps, note that a
43
- plain `lint` said nothing about staleness and `okf lint <root> --stale-after
44
- 90d` is the check that would.
42
+ 4. **The age cutoff is off by default.** A plain `lint` already reports concepts
43
+ past their own declared `stale_after` (`expired`), but says nothing about
44
+ *age*; when the bundle records change times, note that `okf lint <root>
45
+ --stale-after 90d` is the check that would.
45
46
 
46
47
  Keep it to two or three pointed picks, each with the exact `/okf:gem <verb>` to
47
48
  run and a one-line reason from the signals. Never auto-run a workflow from here.
@@ -20,23 +20,46 @@ non-trivial migration; its type and tag rules apply here unchanged.
20
20
  block of [templates/concept.md](../templates/concept.md): a small `type`
21
21
  vocabulary derived from what the documents *are* (reuse before minting —
22
22
  check `okf types <dir>` as you go), `title`/`description` from each
23
- document's own heading and purpose line, `timestamp` from the document's own
24
- date when it carries one, `tags` only where connective.
23
+ document's own heading and purpose line, `generated: { by: <actor>, at: … }`
24
+ from the document's own history when it carries one (the actor in §7's
25
+ spelling — never invented), `tags` only where connective.
25
26
  3. **Keep the directory topology** — it is already domain knowledge. Default
26
27
  one file = one concept. When a file shows split signals (two `type`s
27
28
  fighting for the frontmatter, two audiences), flag it for a later `curate`
28
29
  pass; never split, rename, or restructure during migration.
29
30
  4. **Reserved files.** A bundle-root `index.md` from
30
31
  [templates/root-index.md](../templates/root-index.md) (frontmatter is
31
- `okf_version: "0.1"` and nothing else), a nested `index.md` per directory
32
+ `okf_version: "0.2"` and nothing else), a nested `index.md` per directory
32
33
  from [templates/index.md](../templates/index.md), and `log.md` with a dated
33
34
  **Creation** entry naming where the documents came from.
34
35
  5. **Links.** The documents' existing relative links become the graph's edges —
35
36
  verify they resolve inside the bundle and repoint only what a move broke.
36
- Links pointing outside the bundle are tolerated (§5.3); leave them.
37
+ Links pointing outside the bundle are tolerated (§6.1); leave them.
37
38
  6. **Close out** — walk the
38
39
  [Closeout gate](../reference/authoring.md#closeout--the-finishing-gate):
39
- `validate` zero errors, `lint` (pass `--stale-after` when you stamped
40
- timestamps), `loose`, tag review, index eyeball. Then prove the promise:
41
- each concept with its frontmatter block stripped is byte-identical to the
42
- source document.
40
+ `validate` zero errors, `lint`, `loose`, tag review, index eyeball. Then
41
+ prove the promise: each concept with its frontmatter block stripped is
42
+ byte-identical to the source document.
43
+
44
+ ## The other migration: v0.1 spelling → v0.2
45
+
46
+ A bundle already in OKF but written in v0.1's spelling reads correctly forever
47
+ (§13.1), so this pass is convenience — run it when you want the bundle to *write*
48
+ what v0.2 readers expect. Exactly two spellings move, and `lint`'s Migration
49
+ findings name every file carrying either:
50
+
51
+ 1. Run `okf lint <dir>` and read the two Migration findings — `legacy_timestamp`
52
+ and `legacy_citations` list the affected files in their metric.
53
+ 2. **`timestamp` → `generated`.** Move the value under
54
+ `generated: { by: <actor>, at: <the timestamp> }`. The actor is the one thing
55
+ no tool can derive: ask, or write `human:<maintainer>` when the history is
56
+ human — and never let a tool sign a person's name (see
57
+ [produce](produce.md)).
58
+ 3. **`# Citations` → `sources`.** Lift each item into a `sources:` entry —
59
+ a labelled link's text becomes `title`, its URL `resource`; a bare-URL or
60
+ autolink item has no title, so keep `resource` alone or author one. Where
61
+ the body cites a source, add an `id:` to the entry and a `[^id]` footnote at
62
+ the claim. Then delete the section.
63
+ 4. Re-run `okf lint` until the Migration category is clean. The mechanical
64
+ done-check, exit 1 until it is:
65
+ `okf lint <dir> --only legacy_timestamp,legacy_citations --fail-on info`.
@@ -1,23 +1,30 @@
1
1
  # Playbook: produce — create or extend a bundle
2
2
 
3
3
  The craft that makes these steps land well — granularity, choosing `type`, tag
4
- vocabulary, topology, links, citations — lives in
4
+ vocabulary, topology, links, sources — lives in
5
5
  [authoring.md](../reference/authoring.md). Read it before a non-trivial produce.
6
6
 
7
7
  1. Read [SPEC.md](../reference/SPEC.md) if you are unsure of any rule.
8
8
  2. Pick the source(s): **code** (derive concepts from source, READMEs, docstrings,
9
- config), **docs/wiki** (distill pages into concepts; cite the originals under
10
- `# Citations`), **manual** (decisions, playbooks, metrics that live only in
11
- people's heads). If the source documents should survive as the concepts
12
- themselves — verbatim — that is [migrate.md](migrate.md), not produce.
9
+ config), **docs/wiki** (distill pages into concepts; record the originals in
10
+ `sources:` and key claims with `[^id]` footnotes), **manual** (decisions,
11
+ playbooks, metrics that live only in people's heads). If the source documents
12
+ should survive as the concepts themselves — verbatim — that is
13
+ [migrate.md](migrate.md), not produce.
13
14
  3. Choose a domain-based directory layout. One concept per file.
14
- 4. Write each concept from [templates/concept.md](../templates/concept.md): a
15
- descriptive `type` from the bundle's vocabulary, recommended fields filled,
16
- cross-links to related concepts written into prose.
15
+ 4. Write each concept from [templates/concept.md](../templates/concept.md) — or
16
+ [templates/attested-computation.md](../templates/attested-computation.md)
17
+ when the concept *is* a sanctioned computation (§10): a descriptive `type`
18
+ from the bundle's vocabulary, recommended fields filled, cross-links to
19
+ related concepts written into prose. `generated.by` says who produced the
20
+ content, in §7's spelling — and when a tool writes a concept unattended, the
21
+ tool writes **its own** identity, `<producer>/<version>`: `human:<maintainer>`
22
+ from a generator would be a fabricated human attestation, the exact false
23
+ provenance §5 exists to prevent.
17
24
  5. Add or refresh `index.md` per directory from
18
25
  [templates/index.md](../templates/index.md); for the bundle root use
19
26
  [templates/root-index.md](../templates/root-index.md) so it carries
20
- `okf_version: "0.1"`. Append a dated entry to `log.md`.
27
+ `okf_version: "0.2"`. Append a dated entry to `log.md`.
21
28
  6. **Close out** — walk the
22
29
  [Closeout gate](../reference/authoring.md#closeout--the-finishing-gate)
23
30
  (`validate` + `lint` are part of it, see [cli.md](../reference/cli.md))
@@ -3,7 +3,7 @@
3
3
  Reached by `search <query…>` — the query is everything after the verb; given no
4
4
  query, ask what to find. Retrieval matters as much as curation: a bundle nobody
5
5
  can query cheaply is dead weight. The discipline is progressive disclosure
6
- (spec §6): every step pays a few hundred bytes to decide what the next step
6
+ (spec §8): every step pays a few hundred bytes to decide what the next step
7
7
  reads, and full bodies are read last, and only the winners.
8
8
 
9
9
  1. **Just run it — no presence probe.** Point the finder at a path or an `@slug`
@@ -58,7 +58,7 @@ reads, and full bodies are read last, and only the winners.
58
58
  @slugs (`okf search @handbook @notes <terms>`) or `@all` for every registered
59
59
  one — and read the per-row bundle slug before following an id home.
60
60
  4. **Read only the winners.** A match row's `id` is its file: `<dir>/<id>.md`.
61
- Read that file — not its folder, never the whole tree. Follow its links (§5)
61
+ Read that file — not its folder, never the whole tree. Follow its links (§6)
62
62
  one hop at a time; check `log.md` when freshness matters.
63
63
  5. **Answer, then write back.** Cite the concept ids you used. If the answer
64
64
  was missing, stale, or needlessly hard to find — a gap, a broken link, an