okf-gem · blog
Release · 1.12.0

Bundles que você agrupa, um grafo que você lê: okf 1.12.0

RS Rodrigo Serradura · ·6 min de leitura
🇺🇸 Read in English

Chegando agora: a okf é uma gem Ruby para o Open Knowledge Format, onde um bundle é um diretório de arquivos markdown e cada arquivo é um conceito, uma ideia com frontmatter e links para os vizinhos dela (comece por aqui).

Duas coisas na okf 1.12.0 mudam o que um conjunto de bundles pode ser. O registry deixa de ser uma conveniência por máquina e vira algo que você versiona ao lado do seu código, e um grupo nomeado de bundles ganha um slug único que você busca, serve e aninha.

A terceira muda o que a página do grafo te entrega quando o bundle é denso: uma espinha que você lê, em vez de todas as setas de uma vez.

Um registry que mora no repositório

$ okf registry init

Isso cria um .okf-registry.json local ao projeto no diretório atual. Dali em diante a okf o descobre subindo a partir de onde você estiver, e toda operação de registry e todo @slug resolvem por ele em vez do global em $OKF_HOME.

O efeito prático: um okf server pelado dentro de um repositório serve os bundles daquele repositório sem nenhuma configuração global na máquina. Um colega clona e os nomes já funcionam.

Isso só vale se os caminhos viajarem, então eles viajam. Um bundle dentro da própria árvore do registry é escrito relativo ao .okf-registry.json, o que significa que o arquivo pode ser versionado e um checkout em outra máquina, ou um container que o monta, resolve os mesmos bundles sem mudança. Um bundle fora da árvore mantém um caminho absoluto, porque ele não consegue viajar e fingir o contrário quebraria no primeiro clone. Os caminhos continuam sendo lidos como absolutos em todo lugar onde a CLI os reporta; a forma relativa vive só em disco.

Vale saber se você versiona o arquivo: uma entrada local absoluta que já existia migra para relativa na próxima escrita, então um .okf-registry.json que você já tinha pode reescrever os próprios caminhos na primeira vez que você mexer nele. O registry global do $OKF_HOME não é afetado e guarda caminhos absolutos como antes.

Registries aninhados resolvem do mais próximo para fora, o okf registry list nomeia o arquivo local que encontrou, e OKF_NO_DISCOVERY=1 força o global para quem chama de um diretório de trabalho fixo, como a CI.

Grupos: um slug para um conjunto de bundles

$ okf registry group backend @orders @billing @shared-vocab
$ okf search @backend "idempotency"

Um grupo é um slug de registry que nomeia uma lista de membros, e membros podem ser bundles ou outros grupos, então eles aninham. Ele resolve recursivamente e deduplicado por caminho até as folhas que são bundles.

O okf search @backend funde os membros num ranqueamento só, em vez de grampear listas por bundle uma na outra, e o okf server @backend monta cada um deles, o primeiro em /. Ambos pulam um membro cujo diretório sumiu, com uma nota, exatamente como o @all já fazia.

Todo verbo de bundle único recusa um grupo e sai com 2. É a mesma regra que recusa um segundo bundle, pela mesma costura. O ungroup remove membros, esvaziar um grupo o apaga, e o del e o rename também alcançam um slug de grupo, então um rename cascateia por toda lista de membros e um del derruba o slug e apaga qualquer grupo que ele esvazie.

O grafo abre na espinha dele

Um bundle de 28 conceitos unidos por 178 links é ilegível quando você desenha tudo, e a razão são as setas, não os pontos. Então os links viraram uma camada com três quantidades: todo link, a espinha, ou nenhum.

A página do grafo do okf com todos os links desenhados. Trinta nós redondos de conceito ficam soterrados sob uma teia densa de setas cinza que cruza a tela inteira, então nenhum caminho é legível. O controle de quantidade de links da barra está em All links. O cabeçalho diz okf, 30 conceitos, 191 links. A página do grafo do okf com todos os links desenhados. Trinta nós redondos de conceito ficam soterrados sob uma teia densa de setas cinza que cruza a tela inteira, então nenhum caminho é legível. O controle de quantidade de links da barra está em All links. O cabeçalho diz okf, 30 conceitos, 191 links.
Todo link de uma vez: 191 arestas sobre 30 conceitos, ilegível por causa das setas, não dos pontos.

A espinha é a aresta mais forte de cada conceito, escolhida de modo a tocar todo conceito ligado e não deixar ninguém para trás. Um bundle denso agora abre ali em vez de receber quem lê com o emaranhado, e um conceito selecionado sempre mostra os próprios links por inteiro.

O mesmo grafo nas mesmas posições, com só a espinha desenhada: cada conceito mantém seu único link mais forte, então a teia afina para uma forma legível que ainda alcança todo nó. O controle está em Spine. O cabeçalho diz okf, 30 conceitos, 191 links. O mesmo grafo nas mesmas posições, com só a espinha desenhada: cada conceito mantém seu único link mais forte, então a teia afina para uma forma legível que ainda alcança todo nó. O controle está em Spine. O cabeçalho diz okf, 30 conceitos, 191 links.
O mesmo layout na espinha: só a aresta mais forte de cada conceito, então a forma se lê num relance. É aqui que um bundle denso agora abre.

A quantidade é um controle que você mexe. Na barra de ferramentas do grafo há um grupo de três botões para quantos links desenhar, com os tooltips "All links", "Spine" e "No links", e ele alterna a qualquer momento, então um grafo que abriu na espinha está a um clique de todas as setas e a mais um de nenhuma. O okf render --map e o okf server --map te colocam na outra ponta do mesmo controle: nenhum link, diretórios em caixas, e os links de um conceito aparecendo quando você o seleciona.

Há um dividendo de velocidade acima de 800 arestas: o primeiro layout roda só na espinha e o resto chega um frame depois, sem re-layout, então você chega mais cedo a algo legível e nada na tela se mexe enquanto o restante aterrissa.

graph --traffic: isso é um assunto ou um depósito?

O --hubs mede conceitos. O julgamento que você de fato faz ao arrumar um bundle é sobre diretórios, e nada media nada nessa granularidade.

O okf graph --traffic colapsa cada conceito no diretório dele e os links entre dois diretórios num arco ponderado só, e então reporta tráfego interno, de saída e de entrada por diretório, com uma coesão, a fatia interna desse total:

$ okf graph @okf-site --traffic

Traffic - @okf-site (8 dirs, 16 of 29 arcs at weight 2 or more)

  Dir         Concepts  Internal   Out    In  Cohesion
  runbooks           2         0    14     7        0%
  properties         4         1    14     9        4%
  upstream           2         1     7     7        7%
  social             2         2     3     7       17%
  pipeline           4         7     7    14       25%
  content            7         9    12    14       26%
  delivery           4         7     5     4       44%
  (root)             0         0     0     0         -

  Arcs
    runbooks   → content     ×6
    properties → content     ×5
    content    → pipeline    ×4
    content    → properties  ×4
    content    → runbooks    ×3
    pipeline   → content     ×3
    properties → delivery    ×3
    properties → pipeline    ×3
    [mais 8 arcos, até o peso 2]

As linhas ordenam por coesão crescente, então os diretórios que têm uma pergunta a responder vêm primeiro, e o bloco Arcs embaixo da tabela nomeia os arcos que sobreviveram ao corte. A pergunta do título, assunto ou depósito, é uma que os números respondem linha a linha. O runbooks fica em 0% de coesão com quatorze links de saída e nenhum entre os seus próprios dois conceitos: isso é um depósito, arquivos agrupados pelo que servem e não um assunto cujas partes se referem umas às outras. O delivery é o oposto, em 44%, o diretório mais autocontido aqui, com os conceitos citando uns aos outros na maior parte, que é a cara de um assunto de verdade. O (root) não tem conceito nem tráfego nenhum, então imprime um traço em vez de um 0% que ele não mereceu.

O corte de arcos é ajustado ao bundle em vez de fixo, porque um limiar só não serve toda árvore: nos dez bundles contra os quais a gem foi medida, o peso 3 variou de 2 arcos a 136. O --cut N sobrescreve, e a coesão é calculada sobre todo arco de qualquer jeito, então estreitar a figura nunca mexe na evidência.

Um rename, e uma correção

O campo derivado area agora é top_dir, no catálogo, na busca, no stats e no graph --hubs. area nunca foi a palavra da spec, que fala apenas de dir, então o rollup agora se nomeia no vocabulário da spec: o dir no nível de cima.

Se você faz parse do --json, estas são as chaves que mudaram: as linhas de catálogo e busca carregam top_dir onde carregavam area, o graph --hubs emite top_dir e by_top_dir, e o stats emite top_dirs e by_top_dir. As flags de entrada depreciadas --area e --by area estão inalteradas, ainda avisando e ainda mapeando para --dir e --by dir. Nenhum comportamento mudou e os números do hub são idênticos.

Corrigido: um servidor local ao projeto agora mantém a âncora de caminho relativo ao reabrir. Antes, o painel de Bundles desenhava todo bundle dentro da árvore como "folder is gone", e uma adição pelo navegador achatava o bundle para um caminho absoluto, desfazendo a portabilidade para a qual o armazenamento relativo existe.

Como obter

$ gem update okf
$ cd seu-projeto
$ okf registry init
$ okf registry set .okf --as your-bundle
$ okf graph @your-bundle --traffic

O registry init cria um registry vazio, então o registry set é o passo que coloca um bundle nele; aponte para qualquer diretório de bundle e o --as nomeia o slug (por padrão ele é o basename do diretório).

No mais, atualizar não tem surpresa: todo comando e flag que você já roda continua funcionando, --area e --by area inclusive, ainda avisando exatamente como antes. A única coisa que pode quebrar é um script que lê a chave antiga area do --json, que agora é top_dir.

O corte --depth, ao lado do qual a espinha trabalha, chegou na 1.11.0. O detalhe completo está no changelog.