Skip to content

なぜShojikuを作ったか

作者はThinreportsの帳票テンプレートを何年も保守してきました。その間、同じ三つの事故が形を変えて繰り返し起きました。どれもバグではありません。フォーマットの構造が招いた必然です。Shojikuは、この三つを構造的に不可能にする試みです。

帳票レイアウトの保守をしたことがない人には、このページは妙に具体的に見えるはずです。それが狙いです。

事故1:誰にも見つけられないバインディングキー

旧システムでは、キャンバス上のフィールドがIDを持ち、値を流し込むコードがそのIDを文字列で参照していました。両者をつなぐものは慣習だけです。デザイナでフィールド名を変えると、帳票は何事もなくレンダリングされます。顧客の住所があった場所が、空白になったまま。エラーも警告も出ません。品質保証は「誰かがPDFを目で見る」でした。

いちばん痛いのは静かな壊れ方です。一度も値が入らなかったフィールドと、今回たまたま値が空だったフィールドは、紙の上では見分けがつきません。

Shojikuでは、フィールドの台帳がファイルです。 definitions.ymlがテンプレートの参照してよいデータ項目を宣言し、テンプレートはその宣言を参照します。未宣言のキーへの参照は、レンダリングの前に診断コードつきのエラーになります。同じチェックが作成時・CI・CLI・MCPサーバ・Designerで走ります。下にあるのは一つのエンジンだからです。

リネーム事故はバグの類型であることをやめて、ただのdiffになります。

事故2:フォーマットの数だけ増えるキー

二つ目の痛みは静かに複利で効きました。金額に桁区切りが要るので、フィールドにフォーマットを付けます。別の帳票では同じ金額を通貨記号なしで出したい。次は丸めたい。次は別ロケールで。

フォーマットが値ではなくフィールドに付いていたので、変種のたびにキーが増えました。数年後には、違いを誰も思い出せないよく似たキーが台帳に数十個並び、選び間違えても出力はもっともらしく見えました。

Shojikuは表示の瞬間にフォーマットし、CSSのように継承します。 コンテナに通貨スタイルを一度書けば、その下の金額はすべて従い、上書きしたければその場で上書きします。値は数値のままです。ロケール情報はpacks/locale/にデータとして置かれ、エンジン内の分岐にはなりません。だから同じ領収書テンプレートが、通貨・日付・税表記・フォントフォールバックだけ差し替わって、日本語・繁体字・簡体字・英語でレンダリングされます。ジオメトリは動きません。ギャラリーで四つを並べて見られます。

事故3:人間に編集できないレイアウトファイル

旧フォーマットは機械が書き出すXMLで、人間には事実上読み取り専用でした。レイアウト変更をプルリクエストでレビューできない。マージコンフリクトを解決できない。二つのバージョンの間で何が変わったのか、同僚に聞いても答えようがない。ファイルはGUIの産物で、GUIだけが入口でした。

デザイナが隣に座っている間は、それでも回ります。AIエージェントにテンプレートを書かせたくなった瞬間に、これは中心的な問題になりました。エージェントはテキストを読んで書くことで仕事をします。あのファイルには、読むべきものがありませんでした。

Shojikuの文書は、レビューに出して恥ずかしくない二枚のYAMLです。 テンプレートとフィールド台帳、それにデータのJSON。きれいにdiffが出ます。マージできます。エージェントは一枚を読み、6行を直し、プレビューをレンダリングし、レイアウトツリーを読み返し、診断がきれいになるまで反復します。MCPサーバはこのループのためにあります。Designerは同じファイルを往復するだけで、所有はしません。GUIは入口の一つで、唯一の入口ではありません。

この構造が買ってくれるもの

どこでも同じバイト列。 レンダラはレイアウトツリーから描くだけで、測り直しも整形もしません。レイアウトは描画しません。この分離はクレート境界で強制されていて、だからCLI・Dockerイメージ・SDK・ブラウザWASMのPDFは同じ入力に対してバイト単位で一致します。帳票エンジンの回帰テストは、これが成り立って初めて現実的になります。

マシンの外に何も出ない。 レンダリング・署名・検証は設定ではなく設計としてネットワークを使いません。顧客向けの見積を作るPMも、プリントを刷る教師も、手元でレンダリングします。このサイトがブラウザでPDFを描くとき、動いているのはあなたのタブの中のエンジンです。Designerと同じWASMモジュールです。

「検証しなかったこと」を言う検証。 署名が実際に覆うバイト範囲を報告します。不完全な範囲の上の正しい署名は偽造であり、黙って通す検証器は検証器がないより悪いからです。電子帳簿保存法に向き合う人には、ここが要点です。

一つのテンプレート、複数のデータ。 申込書の例は、一つのテンプレートから記入済とブランクの両方を出します。1ptも動きません。請求書の例は22明細を表ヘッダの繰り返しつきで改ページし、同じファイルが別のデータで3明細の1ページにもなります。

Shojikuではないもの

.tlfのインポータはありませんし、作りません。Thinreportsからの移行は、旧帳票をレンダリングし、その画像をAIエージェントに渡し、定義からテンプレートを再作成させる手順です。移行ウォークスルーが最初から最後まで実施済みです。これらの問題を生んだフォーマットとの互換を謳うことは、問題ごと輸入することでした。

サービスでもありません。アカウントも、アップロードも、依存すべきホスト型レンダリングもありません。