Color mode

設計思想

Riebeckite は、Markdown と Obsidian のノートを、HonoX と Vite で構築した静的サイトに変換するフレームワークです。コンテンツを独自形式に取り込まず、生成したサイトを通常の HonoX アプリケーションとして利用者に返します。ホスティングサービスでも CMS でも新しい Markdown 方言でもありません。

出発点は、個人の知識ベースを公開する作業が、書く作業より重くなることでした。Quartz 4 では、コンテンツは残っても、その周りのサイトはフレームワークの更新に追随できませんでした。Riebeckite は境界を動かします。Markdown を入力にし、サイトを通常のコードとして残し、拡張を npm パッケージにします。

コンテンツは公開に使ったツールより長く残るべきです。ノートはテキストエディター、Git リポジトリ、別の静的サイトジェネレーターのどれでも読める必要があります。生成されたサイトも、Riebeckite のアカウントなしで確認、編集、デプロイできなければなりません。対話性は、機能がそれを必要とするときにだけ加えます。

このページは機能一覧ではありません。Riebeckite 本体の開発における判断基準であり、利用者が遭遇するトレードオフを理解するための指針です。実装が原則に届いていない箇所は、原則を書き換える理由ではなく、修正すべき不具合か、判断が必要な論点です。実装の詳細はアーキテクチャを、背景と根拠は設計思想の詳細を参照してください。

原則の一覧

原則 要約
コンテンツ第一 Markdown と frontmatter が唯一の情報源。フレームワークなしでも読めて移せる。
自分の Web を所有する 生成物は利用者のもの。通常の HonoX アプリとして編集、デプロイできる。
標準を優先し、独自仕様を最小化する Markdown、HTML、CSS、HonoX、Vite を土台にし、独自 API は不変条件を表す場合だけ追加する。
静的生成を基本とし、必要なときだけ対話性を加える 読むための体験は HTML。ブラウザー側のコードは必要な機能だけに足す。
明示性を優先する 公開、依存関係、キャッシュの判断を確認できる形にする。

コア原則

原則の数は少なく保っています。候補の一部は別の原則に統合しました。拡張性は「Core を小さく保ち、契約を明示する」の結果であり、可観測性は「明示性を優先する」の一部です。ローカルファーストのコンテンツ管理は「コンテンツ第一」と「自分の Web を所有する」に含まれます。

コンテンツ第一

Markdown と frontmatter が唯一の情報源です。ビルド時に変換しますが、コンテンツはフレームワークなしで読めて移せる通常の Markdown のままにします。

  • content.directory は、サイト内のフォルダー、隣接するフォルダー、外部リポジトリ、Obsidian Vault のいずれも指定できます。コンテンツは app/ の中やサイトリポジトリの中にある必要はありません。
  • 公開先はファイルシステムのパスと独立して解決できます。コンテンツリポジトリを移しても、公開 URL を変えずに済みます。
  • テーマはコンテンツ、ルート、マニフェスト、グラフ、プラグインやクライアントの動作を変更できません。見た目だけを担います。
  • 公開はコンテンツ側の判断です。既定では publish: true があるノートだけを公開し、draft、private、visibility、publishAt で他の状態を表します。

ただし、Riebeckite は Markdown を変換し、サイト固有の frontmatter や構文を拡張として持ちます。Obsidian のすべての機能に対応しているわけではなく、Obsidian ガイドにあるのは確認済みの動作です。

自分の Web を所有する

生成されたサイトは、それを作った人のものです。Riebeckite が提供するのはパッケージとビルドであり、成果物を所有するプラットフォームではありません。

  • create-riebeckite は、app/、riebeckite.config.ts、package.json を持つ通常の HonoX アプリケーションを生成します。ルート、コンポーネント、スタイル、アイランドは、標準の TypeScript、JSX、HTML、CSS で編集できます。
  • Riebeckite のパッケージは依存関係です。更新はパッケージマネージャーで行い、ホストされたエディターを待ったり、サービスからサイトをエクスポートしたりする必要はありません。
  • ビルドは dist/ に静的ファイルを書き出します。Cloudflare Workers、GitHub Pages、Netlify、Vercel、その他の静的ホストへデプロイできます。デプロイ先はサイト側の判断であり、Riebeckite による囲い込みではありません。

サイトを所有するということは、アップグレードと独自コードも自分で管理するということです。1.0 前のマイナーリリースには破壊的変更が含まれることがあり、独自のルートやコンポーネントが自動で移行される保証はありません。メジャーまたはマイナーアップグレードの前にアップグレードガイドを確認してください。

標準を優先し、独自仕様を最小化する

既存の形式とツールを使い、独自仕様は本当に必要な場合だけ追加します。

  • コンテンツには Markdown、GFM、frontmatter、確認済みの Obsidian 構文を使います。サイトには TypeScript、JSX、HonoX、Vite、HTML、CSS、npm を使います。
  • 独自構文は任意です。Shortcode は remark-directive を使ったプラグインであり、Markdown を置き換えるものでも、Riebeckite の利用に必須のものでもありません。
  • 独自 API は、標準が定義していない不変条件を表す場合に正当化されます。公開先の解決、公開状態、プラグインのライフサイクル、Interactive Runtime のライフサイクルなどが例です。
  • 独自 API は文書化し、プラグインやテーマ向けであれば公開し、別の標準を作らない程度に狭く保ちます。

「標準を優先する」は「決して作らない」という意味ではありません。サイドバーのメタデータのような Riebeckite 独自の frontmatter は、公開サイトに Markdown では表せない振る舞いが必要だから存在します。判断基準は、新しい仕様が目新しいかどうかではなく、実際の不変条件を担っているかどうかです。

静的生成を基本とし、必要なときだけ対話性を加える

既定の出力は静的 HTML です。対話性は明示的に追加するものであり、土台ではありません。

  • ページはビルド時に生成され、読むだけなら JavaScript なしで表示されます。ナビゲーション、記事本文、メタデータは HTML に含まれます。
  • ブラウザー側のコードは、必要な機能にだけクライアントエントリやアイランドとして追加します。クライアントエントリは、そのページが使う場合にだけ読み込まれます。
  • SPA ナビゲーションは任意です。Interactive Runtimeは、プラグインのマーカーがあるページでだけ読み込まれ、静的なフォールバックを用意することが前提です。
  • ビルド時に計算できる結果は、ビルド時に計算します。

JavaScript が必要な機能はあります。検索 UI、テーマ切り替え、SPA ナビゲーション、対話的なウィジェットなどです。すべてのプラグインが JavaScript なしで動くことや、リクエスト時のエンドポイントを一切使わないことは保証しません。「静的生成を基本とする」は優先順位であり、禁止ではありません。

明示性を優先する

公開結果に影響する判断は、見える形にするか、記録するか、確認できる状態にします。なぜページが公開されたのか、どこに公開されたのか、なぜビルドが再利用されたのかを推測しなければならない状態は避けます。

  • 公開は既定で明示的です。publish: true があるノートだけを公開し、公開 URL は公開先を通じて解決します。リクエスト時にファイルパスや slug から推測しません。
  • プラグインの順序と依存関係は宣言し、プラグインは必要最小限の拡張点を使います。
  • キャッシュは依存関係が判明している結果だけを保存します。不明な依存関係は保存せず、再利用が不確かなら再計算します。
  • Diagnostics、Doctor、Inspector は読み取り専用です。問題や解決済みの状態を報告しますが、コンテンツや設定を黙って書き換えません。
  • データ来歴はビルドの入力と出力を記録しますが、生成物は変更しません。これは証拠であり、デプロイのゲートではありません。

既定値や規約も、文書化されていて確認できればこの原則に反しません。すべての振る舞いを設定ファイルに書かなければならないという意味ではありません。依存関係を証明できないフックの効果は、不透明なものとして記録されます。

実装原則

コア原則を実装でどう保つかを示します。詳細はアーキテクチャと境界を参照してください。

ビルドを唯一の情報源にする。 コンテンツの解釈はビルド時に一度だけ行い、実行時のコードは用意された結果を配信します。実行時に Markdown を再パースしたり、公開戦略を再解決したりしません。.riebeckite/ はビルド時の状態であり、実行時に読み書きしてはいけません。ビルドに失敗しても、直前の有効な出力は置き換えません。リクエスト時のエンドポイントや SPA ランタイムは存在しますが、コンテンツを再解釈してはいけません。

Core を小さく保ち、契約を明示する。 Core は、共有されるフレームワーク非依存の契約とオーケストレーションを担います。プラグインはコンテンツの振る舞い、テーマは見た目、インテグレーションは HonoX や Vite との接続、アプリケーションはルートやコンポーネントを担います。依存関係は内側へ向け、複数の外側の層が必要とする契約だけを Core に置きます。公式のプラグインとテーマも、外部パッケージと同じ公開契約を使います。

最適化より正しさを優先する。 正しいフルビルドを基準にします。キャッシュ、増分ビルド、出力の再利用は、同じサイトを公開できる範囲での最適化です。状態がない、互換性がない、使えなくなっている、または不確かな場合は、安全にフルビルドへ戻します。ビルド状態は成功後にだけ書き込み、再利用が正しいか判断できない場合は再ビルドします。

信頼境界で安全性を確保する。 サイト所有者、プラグイン、テーマ、ローカルコンテンツは信頼します。外部入力、第三者のコンテンツ、ブラウザーから来るデータは信頼しません。Markdown に書かれた HTML は、プラグインが HTML を変換する前に、Core の許可リスト方式サニタイザーで除去します。プラグインが生成した HTML は信頼されたアプリケーションコードであり、Core はサンドボックス化しません。公開境界はビルド時に解決し、非掲載コンテンツはルーティングできても発見できてはいけません。秘密情報やローカルの絶対パスを、公開出力、クライアントエントリ、ログ、データ来歴に含めてはいけません。

トレードオフ

原則は絶対的な順位ではありません。対立したときの既定と、優先順位を逆転させる条件を示します。セキュリティと公開境界は重み付けの対象ではなく制約であり、利便性で上書きできません。逆転には、測定、テスト、移行手順などの根拠を要求します。各対立の根拠と例は設計思想の詳細にあります。

対立 既定 逆転する条件
Obsidian 互換性 / Riebeckite の拡張 Markdown と Obsidian 構文の意味を保ち、拡張は任意で文書化されたプラグインとして追加する。既存の構文を黙って再解釈しない。 標準に対応する手段がないサイト固有の要求がある。互換性テスト、拡張の文書化、フォールバックを用意する。
設定の単純さ / カスタマイズ性 型付き設定を小さく保ち、プリセットと規約を使う。カスタマイズはプラグイン、テーマ、アプリケーションコードに置く。 多くのサイトが同じ振る舞いを必要とする。検証、文書化された既定値、移行方法を用意する。
静的生成 / 実行時の対話性 ビルド時に計算する。ブラウザー側のコードは、必要なページだけに足す。 検索クエリ、エンドポイント、対話的なウィジェットなど、リクエスト時の計算や入力が本質的に必要である。
性能 / 正しさ・再現性 正しさと再現性を優先する。キャッシュは任意で、依存関係を追跡し、削除しても安全にする。 依存関係の追跡と無効化のテストがあり、条件を明示した測定済みの効果がある。
拡張性 / Core の単純さ まずプラグイン、テーマ、インテグレーション、アプリケーションで解決する。 複数の外側の層が同じフレームワーク非依存の不変条件を必要とする。
自動化 / 明示性 破壊的または影響の大きい操作は段階的かつ明示的にする。安全で可逆な作業は自動化する。 手作業が規模に耐えず、ドライラン、ジャーナル、ロールバック、検証がある。
利用者の自由 / 安全性 コンテンツ構造、ルート、見た目、デプロイの自由を保つ。信頼境界では安全を確保する。 利用者が信頼済みの拡張点へ明示的にオプトインし、結果が文書化されている。
既存 API の維持 / アーキテクチャの改善 公開 API を維持し、移行手段を用意する。1.0 前のマイナーリリースでは破壊的変更があり得るが、1.0 以降はセマンティックバージョニングに従う。 境界が誤っている、または安全でない。移行手順とテストを用意して変更する。

非目標

Riebeckite が担うつもりのないものです。実現できない、あるいは重要でないという主張ではありません。ここに挙げていない未対応事項は、必要性と設計次第で変わります。個別の制限は各プラグインとガイドに記載します。未確定の制限と提案段階の項目は設計思想の詳細に記録しています。

意図的な非目標

  • Obsidian の再実装。 Riebeckite は Obsidian 形式の Markdown と一部の構文を読みますが、Obsidian のプラグインを実行したり、Vault アプリケーションを再現したりはしません。確認済みの動作はObsidian ガイドにあります。
  • Markdown を Riebeckite 独自言語に置き換えること。 Core は Markdown と GFM を使います。任意の構文は標準パーサーの上に構築し、プラグインとして提供します。
  • HonoX、Vite、Web プラットフォームの置き換え。 生成されるサイトは通常の HonoX アプリケーションです。インテグレーションが Riebeckite と HonoX / Vite を接続し、Core はそれらを再実装しません。
  • ホスティングサービスの運営。 ビルドは dist/ に静的ファイルを書き出します。デプロイガイドは外部プロバイダーを対象にし、publish はプロバイダーへの公開を自動化するもので、サイトをホストするものではありません。
  • すべての機能を Core に置くこと。 再利用可能な機能はプラグイン、見た目はテーマ、フレームワークとの接続はインテグレーション、サイトの振る舞いはアプリケーションに置きます。
  • クライアント JavaScript だけのサイト。 読むための体験は静的 HTML です。ブラウザー側のコードは任意の拡張です。

アーキテクチャ上の制約

  • 実行時のコードは .riebeckite/、プラグインキャッシュ、ローカルのビルドファイルに依存できません。
  • テーマはルート、JSX、クライアントスクリプト、プラグインを追加できません。
  • Core は HonoX、Vite、特定のプラグイン、テーマ、サイトアプリケーションに依存できません。
  • インストール済みプラグインのコードは信頼され、Core によるサンドボックス化は行われません。
  • 非掲載コンテンツは公開の発見面に出してはいけません。
  • 最終的な公開状態はビルド時に決まり、実行時のリクエストでは決まりません。

設計判断のガイドライン

機能、設定項目、構文拡張、公開 API を追加する前に、次の問いを確認してください。順番は優先順位ではありません。衝突する場合は、上のトレードオフで決めます。

  1. これは Riebeckite が解くべき問題か。それとも 1 つのサイトやアプリケーションの関心事か。
  2. Markdown、Obsidian 構文、HTML、CSS、HonoX、Vite、その他の既存標準で解決できないか。
  3. 新しい Riebeckite の API、構文、抽象化は本当に必要か。どの不変条件を表すのか。
  4. どの層が担うのか。Core の契約、プラグイン、テーマ、インテグレーション、アプリケーション、CLI のどれか。
  5. Core ではなくプラグインにできないか。任意化または無効化できるか。
  6. ブラウザーではなくビルド時にできないか。
  7. 実行時の振る舞いが必要な場合、静的なフォールバックと明確な信頼境界があるか。
  8. Diagnostics、inspect、データ来歴、ログで振る舞いを確認できるか。
  9. 公開境界、サニタイズ、秘密情報の扱い、アクセシビリティ、データの所有権を保てるか。
  10. 将来のアップグレードや移行を不必要に難しくしないか。ロールバックまたは移行の経路があるか。
  11. 公開 API は外部のプラグインやテーマに必要か。公式コードだけが使う特権 API になっていないか。
  12. 原則から逸脱する場合、その文脈と結果を記録しているか。

原則から逸脱する重要な判断は、docs/agents/adr/に Architecture Decision Record として記録します。公開契約の変更、アーキテクチャ境界の変更、原則からの意図的な逸脱、セキュリティまたは公開に関する例外、リリース方針の変更では作成してください。それ以外のほとんどの変更では、pull request または issue に、問題、判断、代替案、結果を書けば十分です。逸脱は失敗ではありません。記録されていない逸脱が失敗です。

利用者に影響する変更は、別に changes/unreleased/ の変更エントリとして記録します。エントリはリリース前に検証され、変更履歴、リリースノート、GitHub Releases を一つの情報源から生成します。手順はリリース作業を参照してください。

設計思想の詳細

背景と根拠を表示

動機

Riebeckite は、個人の知識ベースを公開する作業が、書く作業より重くなるという問題から始まりました。Quartz 4 は有用な出発点でしたが、クライアント側の UI がコンポーネントモデルではなく Hooks と DOM の変更を中心に組み立てられていました。Vault とサイトを分離して保つことも煩雑で、Quartz 4 から 5 への移行ではサイトの多くを作り直す必要がありました。コンテンツは残るのに、その周りのサイトは残らない。そこに問題がありました。

足りなかったのは機能ではありません。コンテンツ、サイト、フレームワークの間の境界が、この用途に合っていなかったのです。Riebeckite はその境界を動かします。

  • Markdown は入力であり、アーキテクチャではありません。コンテンツモデルは描画フレームワークに依存しません。
  • 生成されるサイトは通常の HonoX アプリケーションです。ルート、コンポーネント、アイランド、CSS、設定は利用者が所有します。
  • 拡張は npm パッケージです。プラグインやテーマは、プラットフォームへの特権的な統合ではなく、依存関係として追加します。

固定テーマを中心にしたジェネレーターと比べると、Riebeckite は生成後のアプリケーションを閉じずに利用者へ渡します。汎用の Web フレームワークと比べると、Riebeckite は Markdown と公開の意味論から始まります。どちらよりも約束は狭く、Riebeckite はコンテンツの解釈とビルドを担い、サイトは通常のコードとして残ります。

ビジョン

コンテンツは、公開に使ったツールより長く残るべきです。ノートはテキストエディター、Git リポジトリ、別の静的サイトジェネレーターのどれでも読めなければなりません。Riebeckite はビルド時にコンテンツを変換しますが、ソースが Riebeckite なしでは読めなくなる状態は作りません。

サイトは、フレームワークのバージョンより長く残るべきです。生成されたサイトは、Riebeckite のアカウントなしで確認、編集、デプロイできる必要があります。Riebeckite の更新は、原則として書き直しではなく依存関係の更新です。ただし、メジャーバージョンや 1.0 前のマイナーリリースでは変更が必要になることがあります。

対話性は、必要とされたときにだけ加えます。サイトはまず静的 HTML として動作し、ブラウザー側のコードは機能がそれを必要とする場合にだけ追加します。フレームワークは境界で取り外せる形にします。コンテンツは Markdown、サイトは HonoX のコード、拡張はパッケージです。

アーキテクチャ原則の詳細

コア原則は Riebeckite が何を重視するかを示します。アーキテクチャ原則は、実装がその価値をどう保つかを示します。具体的なパッケージと処理の流れは、アーキテクチャと境界を参照してください。

ビルドを唯一の情報源にする

コンテンツの解釈は、ビルド時に一度だけ行います。ビルドは、コンテンツの同一性、公開状態、公開先、マニフェスト、グラフ、派生データ、最終的なルートを解決します。実行時のコードは、用意された結果を配信します。

具体的には、次のように扱います。

  • 実行時のコードは、生成されたアプリケーションの出力と、安定したコンテンツデータを読みます。Markdown の再パース、多言語化の再検出、公開戦略の再解決は行いません。
  • .riebeckite/ はビルド時の状態です。実行時の依存物ではなく、Worker のリクエストが読み書きしてはいけません。
  • ビルドに失敗しても、直前の有効な出力を置き換えません。増分ビルドの状態は、ビルドが成功した後にだけ更新します。

境界は次のとおりです。リクエスト時のエンドポイントと SPA ランタイムは存在します。リクエスト固有の応答を計算してもかまいませんが、コンテンツを再解釈したり、実行環境に存在しないローカルファイルに依存したりしてはいけません。「ビルドが唯一の情報源」は「サーバーがない」という意味ではありません。

Core を小さく保ち、契約を明示する

Core は、共有されるフレームワーク非依存の契約とオーケストレーションを担います。プラグインは再利用可能なコンテンツの振る舞い、テーマは見た目、インテグレーションは Web フレームワークとバンドラーへの接続、アプリケーションはルート、コンポーネント、アイランドを担います。

実装上の扱いは次のとおりです。

  • 依存関係は内側へ向けます。Core は HonoX、Vite、特定のプラグイン、テーマ、サイトアプリケーションに依存しません。
  • 複数の外側の層が同じ契約を必要とし、その契約が特定のフレームワークを名指ししない場合に、Core へ置きます。1 つのプラグインだけが必要とする機能は、そのプラグインに置きます。
  • 問題を解決する最小の拡張点を使います。ファイルシステムの再走査よりもマニフェストやグラフへの問い合わせを、独自ルートよりも Page Type を、クライアント JavaScript よりもビルド時の描画を優先します。
  • 公式のプラグインとテーマも、外部パッケージと同じ公開契約を使うことを期待します。特権的な別レイヤーにはしません。

この原則の及ぶ範囲は次のとおりです。「小さい」は行数ではなく責務を指します。Core には、公開、移行、データ来歴のようにパッケージ境界をまたぐビルド時の契約が含まれます。Core はフレームワーク非依存ですが、現在は実行環境非依存ではありません。ビルド時のモジュールは Node の API を使い、実行時のコードはそれらに依存してはいけません。

最適化より正しさを優先する

正しいフルビルドを基準にします。キャッシュ、増分ビルド、出力の再利用は、同じサイトを公開できる範囲での最適化です。

判断と処理は次のようにします。

  • 状態がない、互換性がない、使えなくなっている、または不確かな場合は、安全にフルビルドへ戻します。--full は常に利用できます。
  • ビルド状態は、ビルドが成功した後にだけ書き込みます。失敗したビルドは、直前の有効な状態を残します。
  • キャッシュキーには、結果に影響する入力、バージョン、契約を含めます。依存関係が不明または安全でないプラグインは再利用を迂回します。
  • 再利用が正しいか判断できない場合は、再ビルドします。速度を理由に、誤ったページを公開したり、非公開コンテンツを漏らしたりしません。

性能は測定された性質であり、次の点は約束しません。すべてのサイトで固定の高速化を保証するものではなく、現時点では、すべての増分ビルドとクリーンビルドの出力がバイト単位で同一になることも約束していません。これは検証目標であり、再利用が不確かな場合はフルビルドへ戻す必要があります。

信頼境界で安全性を確保する

Riebeckite は、サイト所有者、プラグイン、テーマ、ローカルコンテンツを信頼します。外部入力、第三者のコンテンツ、ブラウザーから来るデータは信頼しません。

実装では、次の点を守ります。

  • Markdown に書かれた HTML は、プラグインの HTML 変換より前に、Core の許可リスト方式サニタイザーで除去します。スクリプト、イベントハンドラー、危険な URL は取り除かれます。
  • プラグインが生成した HTML は、信頼されたアプリケーションコードです。プラグインは外部由来のテキストをエスケープし、URL を検証する必要があります。Core はインストール済みプラグインのコードをサンドボックス化しません。
  • 公開境界はビルド時に解決します。下書き、予約公開、公開、非掲載の状態を明示します。非掲載コンテンツはルーティングできても発見できてはいけません。検索やグラフなどの発見面では、マニフェスト全体ではなく discoverableEntries を使います。
  • 秘密情報やローカルの絶対パスを、公開出力、クライアントエントリ、ログ、データ来歴に含めてはいけません。

サニタイザーと信頼境界の限界は次のとおりです。サニタイザーは Markdown 内の偶発的または悪意のある HTML を減らしますが、コンテンツレビューの代わりではありません。第三者のプラグイン、テーマ、コンテンツには引き続き判断が必要です。エンドポイントは入力を検証し、失敗時は安全側に倒します。セキュリティと公開境界の制約を、利便性やビルド速度と引き換えにすることはありません。

トレードオフの詳細

原則は絶対的な順位ではありません。ここでは、既定でどちらを優先するか、どのような根拠があれば優先順位を逆転するかを示します。セキュリティと公開境界は重み付けの対象ではなく制約です。利便性のための機能が、これらを上書きすることはありません。

Obsidian 互換性と Riebeckite の拡張

対立する要求。 ノートは Obsidian で見たままに近く表示されるべきですが、公開サイトには Obsidian の構文では表せない振る舞いが必要です。

既定。 Markdown と Obsidian 構文の意味を保ちます。Riebeckite の拡張は、明示的で任意の、文書化された振る舞いとして追加し、通常はプラグインに置きます。既存の構文を黙って再解釈しません。

逆転する条件。 安定したセクションナビゲーションや独自のページ形状など、標準に対応する手段がないサイト固有の要求がある場合です。文書化された拡張を追加し、Obsidian でもコンテンツが読める状態を保ち、互換性の限界を明記します。

必要な根拠。 互換性テストまたは確認済みの対応表、拡張の文書化、可能であればオプトインの切り替え、拡張を使わないコンテンツのフォールバックです。

例。 サイドバーの frontmatter は、サイトナビゲーションのための Riebeckite 拡張です。Shortcode は remark-directive を使ったオプトインの構文プラグインです。どちらも Markdown を置き換えるものではありません。

設定の単純さとカスタマイズ性

対立する要求。 設定は小さいほど理解しやすい一方で、サイトの形はそれぞれ異なります。

既定。 型付きの設定を小さく保ち、プリセットと規約を使います。カスタマイズは Core のフィールドを増やすのではなく、プラグイン、テーマ、アプリケーションコードに置きます。

逆転する条件。 多くのサイトが同じ振る舞いを必要とする場合、または契約上、共有の設定が必要な場合です。型付きのオプションを、検証、文書化された既定値、移行方法とともに追加します。複雑さを別の場所へ移すだけの汎用 escape hatch は追加しません。

必要な根拠。 複数の実用例、既存の振る舞いを保つ既定値、不正な値のテスト、いつ使うかの文書化です。

例。 テーマの設定はテーマパッケージに属し、Core の ThemeOptions を増やしません。プラグインのオプションは、それを使うプラグインに属します。

静的生成と実行時の対話性

対立する要求。 静的出力は速く、移植性が高く、確認しやすい一方で、ビルド時には分からない入力や計算を必要とする機能があります。

既定。 ビルド時に計算します。対話やリクエスト時の入力が本質的に必要な場合にだけブラウザー側のコードを追加し、必要なページに限定します。JavaScript なしでも意味のある内容がある機能には、静的なフォールバックを用意します。

逆転する条件。 検索クエリ、エンドポイント、対話的なウィジェットなど、リクエスト時の計算やユーザー入力なしでは機能が成立しない場合です。クライアントエントリ、エンドポイント、または Interactive Runtime を、明示的な信頼境界とともに使います。

必要な根拠。 JavaScript なしのフォールバック、またはそれが不可能であることの明示、ページ単位の読み込み、実行時の制限、失敗と破棄のテストです。

例。 検索はクライアントエントリを使います。SPA ナビゲーションは任意です。Interactive Runtime はプラグインのマーカーがあるページでだけ読み込まれ、実行に失敗してもサーバー側で描画したフォールバックが残ります。

性能と正しさ・再現性

対立する要求。 ビルドが速いと大規模なサイトを編集しやすい一方で、再利用は古い出力や誤った出力を公開する可能性があります。

既定。 正しさと再現性を優先します。キャッシュは任意で、依存関係を追跡し、削除しても安全でなければなりません。再利用が正当化できない場合は、もう一度処理します。

逆転する条件。 明示的な依存関係の追跡、無効化のテスト、条件を明示した測定済みの効果がある場合です。その場合でも、公開境界やセキュリティ境界を弱めてはいけません。

必要な根拠。 コールドビルドとの比較、状態の欠落や破損のテスト、キャッシュキーの入力、ベンチマークの条件です。「速く感じる」は根拠になりません。

例。 コンテンツキャッシュは、依存関係が安全でないプラグインを迂回します。増分ビルドの状態は成功後にだけ更新されます。出力レベルの SSG キャッシュは、依存関係が判明しているルートだけを再利用します。

拡張性と Core の単純さ

対立する要求。 拡張点が増えるほど柔軟になりますが、Core の契約が増えるほど保守と結合の負担も増えます。

既定。 まずプラグイン、テーマ、インテグレーション、アプリケーションで解決します。複数の外側の層が同じフレームワーク非依存の不変条件を必要とする場合にだけ、Core へ契約を追加します。最小の拡張点を使います。

逆転する条件。 公式機能が共有契約の欠落を明らかにした場合、またはパッケージ間の重複が一貫性のない振る舞いを生む場合です。契約を追加し、公式コードを移行し、外部パッケージが monorepo なしで使えることを確認します。

必要な根拠。 2 つ以上の実際の利用者、フレームワークを名指ししない公開 API の形、逆依存がないこと、外部利用のテストまたは文書化です。

例。 独自ルートより Page Type を優先します。Derived View は、Markdown のソースにもグラフのノードにもならず、ビルド時の計算値を共有します。テーマトークンは、振る舞いを変えずに見た目を変えます。

自動化と明示性

対立する要求。 自動化は繰り返し作業を減らしますが、破壊的または影響の大きい操作には明確な判断点が必要です。

既定。 公開、移行、コンテンツ変更、削除など、破壊的または影響の大きい操作は段階的かつ明示的にします。キャッシュ、ビルド、診断など、安全で可逆的で観測可能な作業は自動化します。

逆転する条件。 手作業が規模に耐えず、自動化にドライラン、ジャーナルまたは監査記録、ロールバック、検証がある場合です。実行前後に内容を確認できる必要があります。

必要な根拠。 計画またはドライランの出力、冪等性と復旧のテスト、変更内容の記録、不可逆な処理の前に止める手段です。

例。 コンテンツ変更は書き込み前に計画し、ジャーナルを残します。コンテンツ移行はルールを明示します。公開の承認はオプトインです。増分キャッシュは破棄しても安全なので自動化します。

利用者の自由と安全性

対立する要求。 フレームワークは作りたいものを作れるべきですが、非公開コンテンツの公開や攻撃への露出につながる選択もあります。

既定。 コンテンツ構造、ルート、見た目、デプロイの自由は保ちます。サニタイズ、公開状態、エンドポイントの検証、秘密情報の扱いという信頼境界では安全を確保します。

逆転する条件。 プラグインが生成する HTML や外部埋め込みプロバイダーなど、信頼済みの拡張点へ利用者が明示的にオプトインし、結果が文書化されている場合です。オプトインは見える形にし、全員の信頼境界を黙って広げてはいけません。

必要な根拠。 脅威モデル、サニタイザーと公開境界のテスト、何を信頼するかの文書化です。

例。 Markdown の生 HTML はサニタイズします。プラグインが生成する HTML は、プラグインが信頼されたコードなので信頼します。非掲載コンテンツは発見面に出しません。公開境界と秘密情報の扱いを、利便性と引き換えにすることはありません。

既存 API の維持とアーキテクチャの改善

対立する要求。 利用者には安定した API が必要ですが、誤った境界は維持するほど修正コストが大きくなります。

既定。 公開 API を維持し、移行手段を用意します。1.0 前のマイナーリリースには破壊的変更が含まれることがあり、1.0 以降はセマンティックバージョニングに従います。変更はリリースノートと移行ガイドで伝えます。

逆転する条件。 境界が誤っている、または安全でなく、維持すると欠陥が残る場合です。移行方法、新しい境界の説明、移行経路のテストを用意して変更します。

必要な根拠。 影響を受ける公開範囲、移行手順、リリースノート、古い振る舞いを維持するか明確に拒否するかのテストです。

例。 パッケージ境界と公開エクスポートは契約の一部であり、@riebeckite/core/src/** は内部です。現在の Riebeckite は、実行時の非推奨警告や互換シムを既定では提供していないため、アップグレードでコード変更が必要になることがあります。

非目標の詳細

本体ページには確定した非目標とアーキテクチャ上の制約をまとめています。ここには、まだ方針として確定していない制限と候補を記録します。

現時点で未対応であり、非目標と確定していないもの

以下は現在の実装の限界です。必要性と設計が十分に強ければ、変わる可能性があります。

  • DataviewJS。Dataview プラグインは DQL を扱いますが、JavaScript は実行しません。
  • Obsidian のコミュニティプラグイン。Riebeckite はノートを読みますが、Obsidian のプラグイン実行環境は動かしません。
  • Liquid、Nunjucks、EJS などの任意のテンプレートエンジン。サイトは TypeScript、JSX、HonoX を使い、別のテンプレート言語を持ちません。
  • コンテンツ移行における任意の Markdown 本文の書き換え。移行ルールは解析済みの frontmatter と論理パスを対象にし、本文全体の正規表現置換は行いません。

将来の候補(約束ではない)

ランタイムアダプターの追加、デプロイガイドの追加、破壊的変更前の非推奨期間は候補です。ただし約束ではなく、このページで確定した方針でもありません。

提案段階のもの

「CMS ではない」「ノーコードのサイトビルダーではない」「コミュニティやコメントのプラットフォームではない」といった主張は、非目標として提案されることがありますが、まだ確定していません。根拠を伴うメンテナーの判断が必要です。ここでは公式方針ではなく、未解決の論点として記録します。

関連ドキュメント

Local Graph

Nearby Notes