COMMENT 規約
Kozou は、テーブル・カラム・ビュー・外部キーに付与した COMMENT を読み取り、3 つのサーフェスへと変換します。すなわち Admin UI、REST API、そして AI エージェント向けの MCP コンテキストです。COMMENT のほとんどは人間向けに書かれた素のプロース(散文)であり、Kozou はそのプロースをそのまま変更せずに引き継ぎます。しかし、わずかなオプトインの @ 接頭辞付きタグを使うと、SQL の外に出ることなく構造 — ウィジェットヒント、AI ガイダンス、業務ポリシー、サンプルクエリ — を追加できます。
このページでは、@kozou/core がパースする通りに、そのタグの語彙を正確に解説します。パース結果が各サーフェスにどう反映されるかについては、出力されるサーフェス を参照してください。なぜデータベースがこれらすべての唯一の源になるのかについては、信頼できる唯一の情報源としての Postgres を参照してください。
モデル: プロースが先、タグはオプトインの構造
Section titled “モデル: プロースが先、タグはオプトインの構造”COMMENT は素のテキストです。人間の読み手に向けて書き、最初の 1 行は短くするべきです — Kozou はそれをフォールバックのラベルとして使います。そのプロースの下に、タグ行を追加できます。タグ行は、(任意の先頭の空白の後に)@、タグ名、コロンで始まる場合に認識されます。
@<name>: <value>v0.1.1 で認識されるタグ名は 4 つです。@ai、@widget、@policy、@example。それぞれパースのされ方が異なり、以下の選択は意図的なものです — あるタグは表示される本文に残り、あるタグは取り除かれ、1 つは完全に抽出されます。続くセクションでは、各タグと、Kozou が認識しないタグに何が起こるかを扱います。
パーサは COMMENT ごとに 1 つの構造化された結果を返します。
type ParsedComment = { body: string; // human-facing text, with some tags removed ai: string[]; // every @ai value, in order widget: WidgetType | null; // the last valid @widget value policy: string[]; // every @policy value, in order examples: ExampleQuery[]; // each @example block, lifted out of body};@ai — AI エージェント向けの自由記述ガイダンス
Section titled “@ai — AI エージェント向けの自由記述ガイダンス”@ai は、UI ではなく AI エージェントに向けた指示やコンテキストを伝えます。@ai 行は複数書くことができ、各値は順序を保ったまま ai[] に収集されます。
COMMENT ON TABLE orders IS 'Customer orders. One row per placed order.
@ai: For revenue figures, prefer the view vw_orders_paid. @ai: Rows where deleted_at is not null are soft-deleted; exclude them.';@ai は、表示される本文に残されると同時に抽出もされる唯一のタグです。その理由は、@ai の注記は通常、人間にとっても意味の通る文として読めるため、これを取り除くと生の説明を読む人がコンテキストを失ってしまうからです。したがって、同じテキストが body と ai[] の両方に現れます。
@widget — カラム専用の UI ウィジェットヒント
Section titled “@widget — カラム専用の UI ウィジェットヒント”@widget は、Admin UI がカラムに対してどの入力コントロールをレンダリングするかを指示します。これはカラムの COMMENT 上でのみ意味を持ちます。テーブルやビューの COMMENT では、バインドする対象のカラムがありません。
COMMENT ON COLUMN products.description IS 'Long-form product copy shown on the storefront. @widget: textarea';@widget に固有の挙動が 3 つあります。
- 表示される本文から取り除かれます。
@aiと異なり、@widget行は人間の読み手にとって構造的なノイズであるため、bodyには現れません。 - 最後のものが優先されます。 COMMENT に複数の
@widget行が含まれる場合、最後の有効な値が効果を持ちます。 - 値は既知のウィジェットタイプでなければなりません。 値が以下のタイプのいずれでもない場合、Kozou は警告をログに出力し、そのカラムにはウィジェットを記録しません(そのため、ヒューリスティックなデフォルトにフォールバックします)。
@kozou/core で定義されている通りの、ウィジェットタイプの全集合は次の 12 個です。
texttextareanumberbooleandatedatetimeenum-selectrelation-selectjsonimage-urluuidcurrency@widget はヒントであり、唯一の入力ではありません。これを省略すると、Kozou はカラムの型と制約からウィジェットを推論します(たとえば、許可された値の CHECK リストを持つカラムは enum-select を推論し、外部キーカラムは relation-select を推論します)。YAML の UI Hints ファイルが存在する場合、それは @widget タグとヒューリスティックの両方より優先されます。image-url は v0.1.1 では表示用に画像の URL をレンダリングします。これはアップロードコントロールではありません。
@policy — 業務ポリシーのテキスト(v0.1 では強制されません)
Section titled “@policy — 業務ポリシーのテキスト(v0.1 では強制されません)”@policy は、業務ルールをプロースで記録します。すべての @policy 行は policy[] に収集され、そして — @ai と同様に — その行は表示される本文に残されます。
COMMENT ON COLUMN orders.status IS 'Order lifecycle state. @policy: An order may only move to ''shipped'' after payment is captured. @widget: enum-select';v0.1.1 では、@policy はパースされますが強制されません。Kozou はテキストを抽出し、コンテキストとして利用できるようにします。そこから制約、トリガー、API レイヤーのチェックを生成することはありません。これは、ランタイムが保証するものではなく、スキーマとともに移動して AI エージェントに届くドキュメントとして扱ってください。
@example — ビューと概念のためのサンプルクエリ
Section titled “@example — ビューと概念のためのサンプルクエリ”@example は、実行可能なサンプルクエリをビューに添付します(MCP では「concept」として提示されます)。これは v0.1.1 で唯一の複数行タグであり、最も特徴的なパースを持ちます。
@example:行自体にあるテキストが説明です(空でもかまいません)。- その下のインデントされた継続行が SQL です。
- ブロックは、最初のインデントされていない行、次の
@タグ、または COMMENT の終端で終わります。 - 共通の先頭インデントは取り除かれるため、保存される SQL は COMMENT ブロックによってインデントされた形ではなく、書かれた通りに読めます。ブロック内の空行は保持されるため、複数ステートメントのサンプルはその区切りを保ちます。
COMMENT ON VIEW vw_orders_paid IS 'Orders that have been paid for.
@example: Total revenue in the last 30 days select sum(total_amount) from vw_orders_paid where paid_at >= now() - interval ''30 days'';';他のすべてのタグと異なり、@example ブロックは表示される本文から完全に抽出されます。SQL は別途 — { description, sql } エントリのリストとして — 提示されます。これはプロースとしてではなく、サンプルクエリとして提示されるためです。上記の COMMENT から、本文には Orders that have been paid for. だけが残り、サンプルは 1 つのエントリとなります。その description は Total revenue in the last 30 days で、sql はインデントを取り除いた 2 行のクエリです。
未知のタグ — 本文に残され、警告としてログに出力される
Section titled “未知のタグ — 本文に残され、警告としてログに出力される”COMMENT に Kozou が認識しないタグ — たとえば将来の @foo: — が含まれている場合、パーサは失敗しません。その行を表示される本文に残し、警告をログに出力します。これは意図的な前方互換性です。新しい Kozou 向けに書かれた COMMENT も v0.1.1 で問題なくレンダリングされ、未知のテキストが暗黙のうちに破棄されることは決してありません。
COMMENT ON COLUMN products.sku IS 'Stock-keeping unit. @foo: reserved for a future convention';@foo: 行は body に残り、未知のタグが本文に残されたことを伝える警告が @kozou/core から出力されます。
これらのルールを 1 つの一般的なカラムにまとめて適用してみましょう。status カラムが draft、published、archived のいずれかに制約された products テーブルがあるとします。
COMMENT ON COLUMN products.status IS 'Publication state of the product. draft: not yet visible published: live on the storefront archived: hidden but retained
@ai: Only ''published'' rows should appear in public listings. @widget: enum-select';Kozou はその 1 つの COMMENT を次の各部分にパースします。
| COMMENT の部分 | 行き先 |
|---|---|
Publication state of the product. と 3 つの draft/published/archived 行 | body — 表示される説明 |
@ai: Only 'published' rows should appear in public listings. | body に残され、かつ ai[] にも追加される |
@widget: enum-select | body から取り除かれ、widget を enum-select に設定する |
その結果、表示される本文は素のプロースとして読め(型の説明に加えて @ai の文)、カラムは Admin UI で enum select コントロールとしてレンダリングされ、@ai ガイダンスは MCP を通じて AI エージェントが利用できます。1 つの COMMENT、3 つのサーフェスです。
もし代わりに @widget: dropdown と書いていた場合、dropdown は既知の 12 個のウィジェットタイプのいずれでもないため、Kozou は警告をログに出力し、そのカラムの widget を未設定のままにし、推論されたデフォルト(ここでは、カラムが CHECK リストを持つため enum-select)にフォールバックします。
タグが各サーフェスへどう流れるか
Section titled “タグが各サーフェスへどう流れるか”同じパース結果が、Kozou の 3 つの出力すべてに供給されます。
- Admin UI (
@kozou/svelte-ui) —@widgetがカラムの入力コントロールを選びます。bodyテキストがフィールドの説明になります。 - REST API — v0.1.1 では、REST レイヤーは Kozou と並んで動作する PostgREST によって提供されます。COMMENT のプロースが、テーブルとカラムを説明するものになります。v0.2 系では実験的な自前の REST レイヤー
@kozou/apiがkozou dev --adapter apiの背後に追加されます。これは実験的なものとして扱ってください。 - MCP コンテキスト (
@kozou/mcp) —@aiの注記、@policyのテキスト、@exampleのクエリが、AI エージェントが読める構造化されたコンテキストになります。そのため、エージェントはテーブルの形だけでなく、あなたがそれらとともに書いたガイダンスやサンプルクエリのパスも学びます。
各出力が正確に何を含むかをサーフェスごとに詳しく見るには、出力されるサーフェス へ進んでください。