Skip to content

Releases: na0fu3y/ochakai

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 16:12
Immutable release. Only release title and notes can be modified.
fefc668

破壊的変更は 1 点、推奨型語彙の 9 綴りから 11 綴りへの再整列である(設計
0038)。基準は SPEC §4.1 がプロデューサに求める唯一のこと — 綴りがそれ自体
で説明的であること — を両方向に当てたもの。Semantic Model
Golden Query を退役させ、Skill / Playbook / Policy /
API Endpoint を加えた。ゴールデンクエリは runtime を持つ Attested
Computation そのものなので、SQL は # Computation の本文フェンスに置く。

マイグレーションは走らず、保存済みエントリは 1 件も変わらない。
updated_at は動かないので、保持中の ETag も generated.at もそのまま、再
埋め込みも不要。退役した綴りは書き込みも検索もエクスポートも従来どおりで、
自由型(設計 0005)になっただけである。型を勝手に付け替えないのは、
Attested Computation には runtime が必須で、それを知るのは著者だけだから。
Go API からは domain.TypeModels と domain.TypeQueries が消えた。

追加は 4 つ。

  • prefix — 検索と context に部分木の指定が入った(REST の ?prefix=
    反復、MCP の prefixes、CLI の --prefix、Web UI の各ディレクトリ頁の
    パス欄と「ここを検索」)。id が住所である以上パスは検索範囲でもある、と
    いう理屈(設計 0041)。複数指定は OR、区切りはセグメント境界なので
    metricsmetrics-legacy に届かない。これはフィルタであって
    アクセス制御ではない
    : 誰でも任意の prefix を渡せるし、渡さなければ
    従来どおり全件が返る(設計 0002 は不変)。
  • ochakai mcp-stdio — stdin/stdout で MCP を話し、選択中のサーバへ
    転送する。コマンドしか起動できないクライアントと、Google ID トークンを
    自前で作れないクライアントから Cloud Run に繋ぐための橋(設計 0039)。
    クライアント側に資格情報は書かない。サーバ面は増えず、MCP ツール数も
    同じ。
  • OCHAKAI_READ_ONLY — 書き換えずに知識を配る姿勢。書き込みは全て
    403、MCP は書き込みツールを提示せず、Web UI は失敗するだけのボタンを
    描かない。認可ではなく、運用者も等しく拒む(設計 0040)。
  • OCHAKAI_PUBLIC_READ_ONLY — 誰でも到達してよい配備のための姿勢。
    識別を一切読まない: Authorization ヘッダも委譲も無視し、全員が
    human:anonymous になる。これは緩和ではなく逆で、Cloud Run IAM が前段に
    いなければトークンの署名を誰も検証せず、従来なら偽造トークンの名乗りを
    受け入れつつ、デモの本体である匿名の訪問者だけを追い返していた。
    OCHAKAI_READ_ONLY を含意し、切り離せない(設計 0042)。

いずれも既定は off で、非公開配備の挙動は変わらない。

このほか、ochakai import examples/demo で入る 10 件のデモ知識ベース、
Cloud Run 手順書と同じ配備を差分としてレビューできる Terraform モジュール
(deploy/terraform)、api/openapi.yaml 全体への検証済みリクエスト/
レスポンス例、docs/cli.md の生成、そして Web UI が添付への素のリンクを
描かなかった不具合の修正が入っている。

0.14.0 からは入れ替えるだけでよい。マイグレーションも再埋め込みもない。
Semantic Model / Golden Query を使っているエントリはそのまま動くが、
新しく書くなら Attested Computation に runtime を添えて書く。

変更の全文は CHANGELOG.md を参照。

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 10:26
Immutable release. Only release title and notes can be modified.
0ae12a0

破壊的変更 5 点。いずれも OKF v0.2 のスキーマを ochakai 自身のスキーマと
して受け入れた結果である(設計 0036): 仕様が定義するキー(sources /
usage_window、および Attested Computation の runtime / parameters /
computation / executor / attester)は attrs から出て封筒の第一級フィールド
になり、attrs はプロデューサ拡張キーだけを運ぶ。マイグレーション 0020 が
起動時に値を移す。封筒キーを隠す attrs の書き込みは 400、エクスポートの
frontmatter は SPEC の族順に従い、≤0.12 の status 綴りは読み戻さない。

追加は、宣言された期限と引用元を問い合わせられるようにしたこと(設計
0037): 期限切れを並べる sort=stale_after のフィードと、ある資料から派生
したエントリを引く source= の逆引き。どちらも search_knowledge の
引数として MCP にも届く。Attested Computation が推奨語彙に加わった。

このリリースから、コンテナイメージに加えて linux / macOS / Windows の
バイナリ(checksums と provenance つき)がリリースに添付される。

変更の全文は CHANGELOG.md を参照。

アップグレード

マイグレーション 0020 / 0021 は起動時に自動適用される。0020 は updated_at
を進めないので、保持している ETag と generated.at は影響を受けず、
再埋め込みも不要(埋め込みテキストはこれらのキーを読んでいない)。

attrs.sources などを読んでいるクライアントは、封筒のフィールドを読むよう
に直す必要がある。詳細と全 5 件の破壊的変更は
CHANGELOG.md

インストール

このリリースから、コンテナイメージに加えてバイナリを添付している。

# バイナリ(Go ツールチェーン不要)
# 上の Assets から取得し、checksums.txt と照合する

# Go
go install github.com/na0fu3y/ochakai/cmd/ochakai@v0.14.0

# コンテナ
docker pull ghcr.io/na0fu3y/ochakai:0.14.0

いずれも provenance を検証できる:

gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.14.0 -R na0fu3y/ochakai
gh attestation verify ochakai_0.14.0_linux_amd64.tar.gz -R na0fu3y/ochakai

ochakai 0.13.0

Choose a tag to compare

@na0fu3y na0fu3y released this 26 Jul 12:24
Immutable release. Only release title and notes can be modified.
8fa8ec1

The first release since 0.12.1, and the largest so far: 71 commits, four
migrations, ten new design docs. Two changes are breaking — the compile
surface is gone, and exported bundles now speak OKF v0.2 — and the rest
is the write-back loop finally closing: an agent reports a bad answer, the
entry surfaces in a re-verification feed, a human verifies it, and the
provenance says who did what.

Breaking: compile_sql and the semantic-model surface are gone (design doc 0028)

ochakai never executed SQL (0001), but it did assemble it: compile_sql
turned a semantic-model entry into a query string. That put a
type-specific behavior registry in a product whose own position is that
types are a vocabulary, not a registry — and nobody was using it as of
0.12.1. It is removed rather than deprecated.

  • MCP tool compile_sqlremoved.
  • POST /api/v1/compileremoved.
  • CLI ochakai compileremoved.
  • The Semantic Model type keeps working as an ordinary type: it is
    stored, searched, exported and rendered like everything else. Only the
    behavior attached to it is gone.

Callers that used compile must build their own SQL from the entry body,
which is where that knowledge belonged.

Breaking: exports speak OKF v0.2 (design doc 0034)

OKF moved to v0.2 and gave provenance, trust and lifecycle standard
spellings, so ochakai stops inventing its own. Bundles now declare
okf_version: "0.2" and carry the spec's keys:

generated: { by: agent:analyst@example.iam.gserviceaccount.com, at: 2026-07-26T04:12:00Z }
verified:
  - { by: human:tanaka@example.co.jp, at: 2026-07-26T09:30:00Z }
  • timestampgenerated.at; the body's # Citations heading →
    sources. Both are v0.2's own breaking renames (SPEC §13.1) and the
    v0.1 spellings are no longer written.
  • verified_by / verified_at → a one-element verified list. An entry
    with status verified always emits the key, since its presence is
    what carries the trust tier.
  • status maps to the OKF vocabulary: draftdraft, verified
    stable + verified:, deprecated and rejecteddeprecated with
    a status_note (rejected also keeps rejected_by / rejected_at as
    extension keys).
  • Delegation (0027) rides along as a sibling key: generated: { by: …, via: … }, so by stays a single well-formed actor.

Import still reads v0.1 spellings, so old bundles load. As before, it does
not adopt provenance values from a payload — the one thing it reads is
whether a verified key exists, which decides stable → verified vs
draft.

Two envelope fields come with it, on every surface: updated_by (who
produced the content as it now stands — created_by was a lie after
anyone else edited) and stale_after, v0.2's lifecycle date.

Closing the write-back loop (design docs 0025, 0033)

An agent could already report that an entry led it wrong; nothing consumed
the report. Now failed reports have an exit:

  • sort=failed lists entries by failed outcome reports — a
    re-verification feed, alongside the existing sort=verified_at (oldest
    verification first) and sort=usage.
  • POST /api/v1/verify/{id} and ochakai verify <id> record a human's
    verification against the entry as it stands — promoting a draft,
    re-affirming an already-verified entry (which is what takes it out of
    both feeds), or clearing a rejection. Previously only the Web UI could
    do this.
  • MCP cannot overwrite or delete an entry a human has decided on
    not just verified but the whole human-decided set. Agents write
    freely up to the moment a person signs off.

get_context also changed shape: hits is now purely the ranking behind
the pack, not a second copy of the knowledge, which travels once under
entries (0033). The byte budget covers the whole response, and entries
that do not fit come back as outlines inside that same budget. Search
results are unaffected — there the hits are the answer.

purge: a second stage of delete (design doc 0031)

Delete leaves a tombstone so an id can never be silently reused. Purge is
the deliberate second step that frees it: DELETE /api/v1/knowledge/{id} ?purge=true and ochakai purge <id>. Two calls, deliberately — the
first is reversible, the second is not, and purging a live entry is a
409. It is not exposed over MCP or in the Web UI: destroying history
is a human decision, and an irreversible button next to the reversible
one is a trap. The purge itself is recorded in knowledge_purge — which
id, by whom, how much history went with it — the one table a purge does
not touch. It loses to a concurrent revival, and it does not reclaim
attachment bytes; as with detach, nothing collects them afterwards, which
the docs now say plainly instead of implying otherwise.

Optimistic locking with If-Match (design doc 0030)

If-Match on update, opt-in: send the version you read and a concurrent
edit fails with 412 instead of overwriting. Documented in the OpenAPI
document and exposed in the CLI, so the contract is the same on every
surface.

Identity: delegation and IAP (design docs 0027, 0032)

  • A caller acting for an end user can now pass that user through
    (A via B), so provenance records the human, not just the integration.
    The Web UI shows the "via".
  • serve-ui takes the browser user from the IAP assertion and never from
    the browser — client-supplied identity headers are dropped
    unconditionally.
  • MCP resolves the actor from each call's own HTTP headers, on every
    tool, not only on writes.

Search, embeddings, and the read path

  • Lexical search is rewritten to be answerable and indexable: a stored
    search_text column with a working trigram index (migration 0016),
    query-fragment matching with IDF weighting, and scoring done over an id
    projection. Empty queries are a 400 instead of a Postgres 500, and
    ILIKE wildcards are escaped.
  • HNSW index on the pgvector column when the dimension is within the
    index limit; ef_search is sized to the search's own limit.
  • Embeddings take their input budget from the model, truncate on rune
    boundaries, refuse to start when the configured dimension changes under
    an existing corpus, and reembed now runs to completion — covering
    attachment vectors, paging past entries that always fail, and reporting
    what is actually left.
  • Usage recording is off the read path (0029): buffered and flushed
    periodically instead of writing on every search, with flush failures
    logged rather than swallowed.

Export, move, and correctness

Export streams entries from a single snapshot, can leave attachments out,
and no longer claims a determinism it did not have; failures after the
header are always logged. Move rewrites the moved entry's own relative
links to absolute form, folds that rewrite into the move revision, and
locks the referrers it rewrites. create can no longer resurrect a
tombstone. Verification timestamps are stamped at stored precision, so
what you read back is what was written. Rejections answer in the
documented error envelope; boolean query parameters are rejected rather
than read as unset; serve waits for Shutdown to finish before
returning, and the SIGTERM drain leaves room for the final usage flush.

Upgrade

Four migrations run on start (0016–0019): the search_text column and its
index, delegated-provenance columns, the purge audit table, and
updated_by / stale_after with a backfill from revision history. They
are additive; a rebuild of search_text and the backfill both run over
the full table, so expect the first start on a large corpus to take
longer than usual.

Before upgrading, check for callers of compile_sql, POST /api/v1/compile, or ochakai compile — those break. Consumers that parse
exported bundles need to read v0.2 keys (generated, verified,
sources); ochakai still imports v0.1. Clients reading get_context
should take the knowledge from entries and treat hits as a ranking.
Existing entries keep their embeddings; run reembed only if you change
the model or dimension.

ochakai 0.12.1

Choose a tag to compare

@na0fu3y na0fu3y released this 20 Jul 15:28
Immutable release. Only release title and notes can be modified.
e54ad49

A patch release finishing what 0.12.0 started: the two behaviors it changed each had a gap where the rest of the system had not caught up. No schema changes, no migrations, no breaking changes.

Case-insensitive type filters (design doc 0023 §3.3)

0.12.0 made types the OKF spelling verbatim (BigQuery Table, not a slug) and promised matching would be case-insensitive so the spaces it introduced wouldn't turn every --type into an exact-spelling puzzle. Only the write side delivered: a type filter compared byte-for-byte against the stored spelling, so type=metric and type=METRIC returned zero results against entries stored as Metric.

The matching half is now implemented. domain.FoldType (NFC + trim + lowercase) is the single comparison key, and the store folds the column with SQL lower()type=metric, type=METRIC, and type=Metric all find Metric, and --type "bigquery table" finds BigQuery Table. Free types fold the same way, since 0023 §3.3 widens the tolerance to every entry point, not just the recommended eight. The stored spelling is still exactly what the writer used. This also closes a smaller gap in the same path: type filters were not NFC-normalizing, unlike every other byte-compared key.

Entry links render as links in the Web UI (design doc 0024)

0.12.0 made the body's markdown links the source of an entry's edges, but the Web UI's markdown renderer still only linkified http(s) targets. A link to another entry — [revenue](/metrics/revenue.md), a bare ochakai://metrics/revenue, an autolink — showed as plain text in the body even though it appeared in the Links tab. Now those render as in-app links: bundle-absolute, relative (against the entry's own directory), and canonical-URI forms all resolve, following the same rules the server's extraction does, so what reads as a link is exactly what became an edge.

Alongside this, a pre-existing renderer bug is fixed: markdown inside an inline code span (`[x](/y.md)`) was being rendered as markup. Now emphasis, images, and links apply outside code spans only — matching how the server skips code when extracting links.

Upgrade

Drop-in from 0.12.0. No migrations run and no request or response shapes change; type filters simply match more inputs than before, and the Web UI renders body links it previously left as text.

ochakai 0.12.0

Choose a tag to compare

@na0fu3y na0fu3y released this 20 Jul 13:26
Immutable release. Only release title and notes can be modified.
340451f

Two vocabularies leave ochakai in this release. Types stop being internal slugs translated at every boundary and become the OKF spelling verbatim (design doc 0023, #96). Links stop being a hand-authored field and become what the body actually says (design doc 0024, #100). Both are the same correction: ochakai had invented structure that OKF deliberately left to the document, and paid for it with translation layers that could not round-trip.

Types are the OKF vocabulary (design doc 0023)

The same eight concepts had two names — the internal slug (tables) and the OKF display name (BigQuery Table) — bridged by four mechanisms and converted twice on every read and write. All of it is gone.

Was Is
models Semantic Model
metrics Metric
queries Golden Query
insights Insight
terms Glossary Term
datasets BigQuery Dataset
tables BigQuery Table
references Reference

The original reason for slugs disappeared in 0017: they existed to match the knowledge-catalog reference bundles' directory layout, but paths come from ids alone now and a type never decides a directory name. Worse, the conversion was lossy — slugifyType flattened Data Contract to data-contract, and an okf_type attr existed solely to restore what the flattening destroyed. A mechanism to make round-trips work was cleaning up after a mechanism that broke them.

Import and export are now identity on type. Five mechanisms disappear with the translation: the okfType table, slugifyType, the okf_type attr, displayType/typeFromOKF, and the typeAlias compatibility table. ValidType relaxes to a one-line, slash-free, 128-byte free string, so a foreign bundle's non-ASCII type survives as itself. Matching is case-insensitive at every entry point (--type "bigquery table" works); the spelling you write is the one stored.

Links come from the body (design doc 0024)

Links were a structured field you filled in by hand, independent of the prose. OKF SPEC §5 defines cross-linking as plain markdown links and says the kind of relationship is carried by the surrounding text, not the link. Reading ochakai's own code settled it: nothing branched on Link.Rel — not the context expansion, not the semantic-model traversal (which goes through attrs.model). A typed edge had been introduced, and no machine ever read the type.

The body is the only source of edges. Write [revenue](/metrics/revenue.md) in the prose and the entry links to metrics/revenue. Five forms are read: bundle-absolute (/x.md), relative (./x.md), ochakai:// in a markdown link, autolinks (<ochakai://x>), and bare ochakai://x. External URLs are not entry links, and non-.md file references remain attachments (design doc 0008). Links inside fenced or inline code are examples, not edges, and are skipped.

rel becomes text — the anchor text, not a relationship type. It is optional: a bare ochakai:// reference has none, and then the target's last segment reads as the name, the same fallback titles use (design doc 0022).

The links column survives as a derived index, recomputed on every write, so backlinks and get_context are unchanged — the containment query they run still works exactly as before.

Renaming an entry now repairs the prose. This is a bug fix as much as a feature: Move used to rewrite the links column and attrs.model while leaving the author's markdown links pointing at an id that no longer existed. It now rewrites the body — each notation keeping its own form, code blocks untouched — and re-derives links from the repaired text. Relative targets normalize to bundle-absolute, since where a relative link resolves depends on the referring entry's own location.

Web UI

  • The new-entry form takes one id field (#99), the way the address is one string and the way the Move panel already worked. The + on a tree directory seeds the folder and puts the caret past it.
  • Breadcrumbs link to each ancestor up to the parent directory (#97, #99), and the detail header's actions are more compact.
  • The Links tab is read-only — it shows what the body says, with a note pointing at the body editor. The links textarea is gone.
  • Type comparisons left behind by 0023 are fixed (#98).

Breaking changes

  • type values change across API, MCP, and CLI. No aliases: --type tables does not error, it returns zero results, because it is now a valid free type that nothing uses. Clients switching on type need updating.
  • Types contain spaces. Shell usage needs quoting (--type "Golden Query"), and REST query parameters need URL encoding. Case-insensitive matching softens this in practice.
  • okf_type is no longer emitted.
  • links in a write payload is ignored. Move the relationship into the body as a markdown link. This applies to REST, MCP, and the Web UI alike.
  • Link.rel is now Link.text, and its meaning changes from relationship type to anchor text.
  • Export no longer writes a # Links section — the links are already in the body, and writing them again would duplicate them on re-import.

Migrations 0014 and 0015

Both applied automatically at startup.

0014 renames the eight stored type values and their revision snapshots. It is small because 0011 removed type from every key and path: link targets, URIs, and ids need no rewriting, primary-key collisions cannot occur, and existing embeddings stay valid (the embedding text never included type). Entries carrying an okf_type attr have that spelling promoted back to type first, so an author's original spelling wins over a slug rename.

0015 writes existing links back into the body before the column becomes a derived value, rendering each as - [<rel>](/<target>.md) — the old rel becoming the anchor text, which is exactly the reading 0024 gives it. Without this step those edges would vanish silently the next time an entry was written. An empty rel falls back to the target's last segment, so nothing renders as an empty [](). Revision snapshots are left alone: history should keep the shape it had, and unlike the ids 0013 rewrote, links are not a key.

ochakai 0.11.0

Choose a tag to compare

@na0fu3y na0fu3y released this 20 Jul 10:37
Immutable release. Only release title and notes can be modified.
0b5a10f

The filename becomes the name (design doc 0022, #95): title drops to optional, the id joins search, and byte-compared keys normalize to NFC. Design doc 0017 made the path the address; this release finishes the thought — the last segment of an address is, in most cases, simply the name. Plus directory index pages in the Web UI (#94).

The filename is the name (design doc 0022)

Since 0019 relaxed the character rules, insights/サンプル has been a legal id — but writing knowledge that way still didn't work. Three reasons, all now addressed.

title is optional. The server no longer requires it. The display name is the title when present and the id's last segment otherwise (domain.DisplayTitle), applied uniformly across the Web UI, CLI, and export. Title becomes what it should have been all along: an override for when the filename won't do — a descriptive heading longer than 42 characters, one containing /, or one a foreign bundle brings with it. This also brings ochakai closer to OKF SPEC, which only ever required type in frontmatter; rejecting title-less documents with a 400 was narrower than the spec.

The id is searchable. k.id joins the lexical haystack and the ILIKE substring floor, so 用語/売上 is findable by 「売上」. The id also prefixes the embedding text — paths carry the domain hierarchy, so this adds context even for entries that do have a title.

Byte-compared keys normalize to NFC. macOS filesystems hand back decomposed (NFD) path names, so unpacking a bundle on a Mac and re-tarring it could silently split one entry into two identical-looking ids. domain.Normalize now applies at every boundary where a byte-compared string enters: all service entry points taking an id, link targets, attachment ids and names, bundle import paths, and search queries. Content columns — body, title, description — stay exactly as written. Normalizing keys, not prose.

Folder + name is a client concern. The server's address stays a single id with no derivation (the 0017/0019 "don't guess" line). The Web UI's new-entry form splits into Folder and File name fields instead, and the + on a tree directory prefills the folder.

Directory index pages (#94)

Clicking a directory in the sidebar now renders the equivalent of the index.md that OKF export generates at each level: subdirectories with counts, and the entries at that level with title and description. The progressive disclosure that previously existed only in exports is now in the Web UI. Breadcrumbs in the detail view became per-segment links up to each ancestor's index, and the browse API projection gained description to make those pages worth more than the tree.

Breaking changes

Mostly this release widens what is accepted, but note:

  • title leaves required in the openapi and MCP schemas. Clients assuming a non-empty title should handle an absent one or fall back to the last segment themselves.
  • Empty titles vanish from the wire. title is omitempty — an empty title is a missing key, not "title": "".
  • NFD spellings no longer round-trip. Ids, attachment names, and link targets are normalized on write; the visual result is identical, but the exact NFD bytes are not preserved.
  • Export drops the title: line for title-less entries. No real diff today, since empty titles could not previously exist.

Migration 0013

Applied automatically at startup. It rewrites stored ids, link targets, revision-snapshot ids, event/usage keys, attachment names and paths, and embedding-table keys to NFC — making the invariant true for data written during the window since 0019 accepted non-ASCII ids without prescribing a Unicode form. On real-world data this is a no-op scan, since ASCII is unchanged by NFC. A normalization collision (two ids becoming one) fails the migration loudly rather than silently merging, leaving it for a human to resolve.

As with 0020, existing entries keep their previously stored vectors until they are written again — the id prefix reaches the embedding only on the next real content update. There is no reindex mechanism, by the same write-time-only posture.

Container image

docker pull ghcr.io/na0fu3y/ochakai:0.11.0
gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.11.0 -R na0fu3y/ochakai

ochakai 0.10.3

Choose a tag to compare

@na0fu3y na0fu3y released this 20 Jul 10:37
Immutable release. Only release title and notes can be modified.
048e2b2

Knowledge gains an address change (design doc 0021, #93): move rewrites an entry's id everywhere it is recorded, in one transaction — the follow-through on design doc 0017, which made the path the address and left renaming it unanswered.

Move (design doc 0021)

Because the id is the address (0017), moving it cannot be an update to one column. POST /api/v1/move rewrites every place the id is recorded, in a single transaction:

  • The entry travels whole. Body, revision history, attachments (metadata and bytes), usage records, and embeddings follow the new id. History reads back under the entry's one address: a move revision is appended, and the old id is gone — a GET on it is a 404.
  • Inbound references are rewritten, each keeping the spelling it was written in: links[].target in both the bare and ochakai:// forms, and attrs.model. Referrers get an update revision, so the rewrite is visible in their history rather than silently applied.
  • The destination must be free. A live or soft-deleted entry at the target id is a 409; a missing source is a 404.
  • ochakai move <from> <to> in the CLI; a Move action and tree drag-and-drop in the Web UI.

Not on the agent surface. move is absent from MCP tools/list by the agent-surface policy in 0021 — reorganizing the knowledge base is a human editorial act, not something an agent should reach for mid-conversation.

Scope note: the rewrite covers links[].target and attrs.model. An ochakai:// reference written inline in body prose is content, not a link, and stays as written.

Web UI

  • Directory rows carry a that opens the new-entry form with the id prefixed to that directory.
  • Sidebar rows compress to title plus a status dot; toggles the sidebar and the choice persists.
  • Search filters become a horizontal chip bar, and search cards drop their meta row.
  • Breadcrumbs read / <id>; Review loses its redundant Refresh; button-style links no longer underline on hover.

Container image

docker pull ghcr.io/na0fu3y/ochakai:0.10.3
gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.10.3 -R na0fu3y/ochakai

ochakai 0.10.2

Choose a tag to compare

@na0fu3y na0fu3y released this 19 Jul 17:29
Immutable release. Only release title and notes can be modified.
4b3085d

Attachments become searchable (design doc 0020, #92): filenames match in every search, and attachment contents join hybrid search — the follow-through on the groundwork design doc 0013 laid when it aligned the attachment allowlist with what Gemini embeds.

Attachment search (design doc 0020)

  • Filenames join the lexical haystack. Searching seeds finds the entry carrying seeds.txt — on every instance, embedder or not, effective immediately for existing attachments.
  • Attachment contents join hybrid search. On attach, the file is embedded into a new attachment_embedding table and fused into results as a third reciprocal-rank-fusion list. A hit is always the owning entry — attachments never stand alone (design doc 0008/0013), and ochakai still never interprets them (embedding is deterministic encoding, not interpretation).
    • text/plain embeds through the text path and works with any embedding model.
    • Images and PDFs embed with gemini-embedding-2 (GA 2026-04-22): set OCHAKAI_VERTEX_MODEL=gemini-embedding-2 and OCHAKAI_VERTEX_LOCATION=global (the model lives in global/us/eu only). On a text-only model they stay findable by name.
  • Replacing or detaching an attachment drops its vector in the same transaction; soft-deleting an entry keeps attachment vectors stored (search never surfaces them — revival brings them back).
  • No backfill, matching entry embeddings: only new attaches embed. Filename search needs none.

gemini-embedding-2 wire dialect

The Vertex driver now speaks two dialects, selected by model name: gemini-embedding-2* uses v1 :embedContent — task instructions folded into the prompt (the model has no task_type), outputDimensionality top-level, file bytes as inline_data parts next to a filename text part — while earlier models keep :predict + task_type. Verified against the live API; details recorded in design doc 0020 §2.3.

Switching an existing knowledge base to gemini-embedding-2 leaves previously stored vectors in the old model's space until entries are written again — there is no reindex mechanism, by the same write-time-only posture as entry embeddings. The default model stays gemini-embedding-001.

Container image

docker pull ghcr.io/na0fu3y/ochakai:0.10.2
gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.10.2 -R na0fu3y/ochakai

ochakai 0.10.1

Choose a tag to compare

@na0fu3y na0fu3y released this 19 Jul 14:49
Immutable release. Only release title and notes can be modified.
d230adf

A web-UI and operations release: the knowledge tree becomes the UI's primary navigation, the base-URL setting is gone, and concurrent server starts no longer race on database migrations (#91).

The tree is the navigation (design doc 0014 §2.2 revision)

With path addressing (0.10.0), an entry's id is its place in the hierarchy — so the folder tree is no longer a tab beside search but a persistent left sidebar, Confluence-style.

  • Opening an entry (deep links included) auto-expands its ancestor directories and highlights it, so the tree always shows where you are.
  • The tree refreshes after create, delete, and status changes, keeping its status badges fresh.
  • Home is a tree-first landing with a search box; full search (filters, the verification-age feed) lives under Search. The legacy #/browse route redirects home.
  • On narrow screens the sidebar collapses to a disclosure, like the search filters.
  • Export OKF moved from the top bar to the home page's quick links — same /api/v1/export, just out of prime real estate.

The page talks to its own origin (design doc 0006 revision)

The base-URL chip (top right, backed by localStorage) is removed. Both serving paths — ochakai ui on loopback and ochakai serve-ui deployed — proxy /api/v1 with the right credentials, so a configurable base URL could only break CORS or authentication, and a mistyped value persisted until cleared. Opened as a plain file (development), the page targets a local ochakai serve.

Concurrent starts no longer race on migrations

Migrate now serializes across processes with a Postgres advisory lock. Previously, several instances starting at once against an unmigrated database (a scaled Cloud Run deployment, parallel CI test binaries) could each see a migration as unapplied and apply it twice — the second failing against the schema the first had already changed, or worse, double-rewriting ids on a database with data. A regression test races four migrators from zero on every run.

Breaking changes

  • ochakai serve-ui requires OCHAKAI_URL. The static-page-only mode (no upstream, user-entered base URL) made no sense once the page stopped accepting a base URL, so serve-ui now fails fast without it. Deployments following the deploy guide already set it.

Container image

docker pull ghcr.io/na0fu3y/ochakai:0.10.1
gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.10.1 -R na0fu3y/ochakai

ochakai 0.10.0

Choose a tag to compare

@na0fu3y na0fu3y released this 19 Jul 14:49
Immutable release. Only release title and notes can be modified.
154795c

A restructuring release: the knowledge hierarchy is freed from the type-first layout, the type vocabulary aligns with the OKF knowledge-catalog reference bundles, and semantic models become ordinary knowledge entries. Breaking changes are listed at the end; database migrations run automatically on upgrade.

The path is the address (design doc 0017)

An entry's id is now its full bundle path — the sole primary key — and the type is metadata, not a location. Place together what should be read together: domain-first (sales/orders), type-first (metrics/revenue), and foreign-bundle-shaped (ga4/tables/orders) layouts are all first-class, and the server forces none of them (#87).

  • MCP address-taking tools (get_knowledge, get_attachment, get_knowledge_usage, delete_knowledge) take a single id argument. report_outcome's target is an id. The resource template is ochakai://{+id}.
  • REST routes are {id...} throughout; the legacy /knowledge/{type}/{id}/usage alias is gone.
  • Bundle import takes the frontmatter type as the only type source — files without one are skipped and reported, never guessed from the path. Archive unwrapping (and --keep-root) is gone: tar czf ga4.tgz ga4/ imports under ga4/, so a wrapper directory is how a bundle keeps its namespace.
  • The web UI's Browse tab walks the id hierarchy from the top-level segments; ochakai browse is its CLI counterpart.
  • Existing ids migrate to <type>/<id> — the spelling every serialized reference (export paths, URIs, link targets) already used, so stored references keep resolving without rewrites.

ID segments now follow OKF's actual contract — a concept ID is a file path, nothing more — so only path safety constrains them: no leading ., no control characters, 128 bytes per segment (design doc 0019). Leading underscores (BigQuery hidden datasets), non-ASCII (用語/売上), and spaces are all valid. Types remain slugs: they are vocabulary, not paths.

Type vocabulary aligns with the knowledge-catalog bundles (design doc 0016)

Recommended type slugs are now plural — metrics, queries, insights, terms, tables — joined by datasets (a container grouping tables) and references (mirrors of external material), matching the OKF knowledge-catalog reference bundles directory-for-directory. Those bundles now import onto the recommended types as-is (#85).

  • resource (the canonical URI of the underlying asset) is promoted from attrs to an envelope field, exported right after type as the reference bundles do.
  • ochakai is BigQuery-only: the compile dialect option is gone from REST, MCP, CLI, and the web UI — output is always BigQuery SQL. Ossie input expressions still resolve BIGQUERY first with ANSI_SQL fallback, so portably-written models keep working.

Semantic models are knowledge entries (design doc 0018)

import-ossie (CLI command, POST /api/v1/import/ossie, the derivation logic) is gone. A semantic model is now a models entry carrying the Ossie model object verbatim in attrs.spec — with everything that entails: revisions, provenance, draft→verified verification, search, and OKF export/import. The model no longer falls out of the bundle round-trip (#88).

  • Broken models are rejected at write time, not when someone asks for SQL. Compilation stays deterministic and LLM-free.
  • compile_sql resolves the model from the models entries themselves: pass model (the entry's id), or omit it and the entry whose spec defines the first metric is used — if several do, the compile fails asking for model (design doc 0019). The result names the models entry and its status, so trust is judged from provenance; there is no status gate.
  • Registering a model and its per-metric entries is the client agent's job now — examples/semantic-model.md registers with a plain ochakai create -f, and asking a connected agent to "register this spec and its metrics" is enough.

Release-review hardening (design doc 0019, #89)

  • ochakai import treats a server 400 (e.g. a models entry whose spec fails validation) as that one document's skip — reported, with its attachments — instead of aborting the bundle halfway.
  • The web UI caught up with the plural type vocabulary (type filters work again, all eight types have icons), the New-entry default is insights, and the compile form seeds the metric name from the id's last segment.
  • Shell completions no longer offer removed flags, and the sync test now pins removed surface by name.

Also in this release

  • The site-wide Compile tab moved into the metric detail view, where the model context lives (#82).
  • Web UI: whole-card click navigation, New entry folded into Explore, attachment thumbnails on result cards (#86).

Breaking changes

  • MCP: address-taking tool schemas went from type + id to id; agent configs (CLAUDE.md, prompts) need updating. compile_sql's model argument is a models entry id; dialect is gone (unknown keys are ignored).
  • REST: routes are /api/v1/{knowledge,usage,revisions,backlinks}/{id...}; the legacy usage alias is removed; type is required in create and update bodies; POST /api/v1/import/ossie is a 404.
  • CLI: import-ossie and import --keep-root are gone; refs are ids (ochakai get metrics/revenue).
  • Export: no id: frontmatter line, all-alphabetical index ordering — a one-time diff against old exports.
  • DB: migrations 0010–0012 rewrite type slugs and ids, move resource to a column, convert semantic_model rows to models/<name> draft entries, and drop the table. They run automatically and abort safely on id collisions (resolve, then re-apply).

Container image

docker pull ghcr.io/na0fu3y/ochakai:0.10.0
gh attestation verify oci://ghcr.io/na0fu3y/ochakai:0.10.0 -R na0fu3y/ochakai