Work 03
Kaname App
自分の業務まるごと(Notion クローン+見積+タスク+カレンダー+会計・M365 連携)を自前 VPS に閉じ込めた個人用モノレポ
2Problem
自分の仕事は三つの島に分かれていた。書き物と管理をまとめる場所、見積から受注までを扱う旧来の表計算の資産、そして予定表である。互いに参照しないため、同じ情報を三度書き写すことになる。統合そのものは既製の道具でも足りるが、見積の中身は取引先の機密であり、外部の事業者の基盤へ平文で預けることはできない。機密を自分の設備の内側へ完全に留めることを最上位の制約として、統合の側を自作する判断をした。
3Requirements & constraints
制約は四つに整理した。第一に、永続する正本は自分で持つ設備の内側にだけ置くこと。第二に、机上の環境と携帯の環境で同じ実装が動くこと。第三に、回線が切れている間も編集でき、復帰したときに片方の変更が黙って消えないこと。第四に、旧来の表計算が持っていた計算の振る舞いを、見た目ではなく仕様として引き継ぐこと。とくに三番目は、既製の同期基盤を選べるかどうかを決める分かれ目になった。
4Design
構成は、単一の記述を二つの面で走らせ、自前の同期役を唯一の永続する正本に据える三層とした。同期は性質の違いで二つの経路へ分けている。文章のように同時編集が起きる対象は、頁の単位で合流できる型を用い、自前で立てた中継を通す。属性のように欄ごとに更新される対象は、欄の単位で後勝ちの規則を用い、時刻と論理順序を混ぜた鍵で順序を決め、送信は取り消しのできる待ち行列へ載せて後から突き合わせる。見積は独立した関係型の設計とし、版ごとに書き換えない写しを残す。
5Why this stack
既製の同期基盤を採らなかった理由は明確だった。行の単位で後勝ちを解決する方式では、二つの端末が同じ行の別々の欄を直したときに、片方の変更が警告もなく消える。これを欄の単位の後勝ちとして自前で組み直し、両方が生き残ることを機械で確かめている。携帯と机上を一つの枠組みで賄う案を採らなかったのは、最も重い再利用資産である文書編集の実装(stack に出している部品)が web の技術で書かれており、載せ替えれば書き直しになるためである。予定表の書き出しに再生成型の実装を避けたのも同じ性質の判断で、その種の実装は未知の拡張欄を黙って落とし、他の道具が作った予定を壊す。
6Implementation
実装は複数の package に分かれる。規模は本節末の計測に示す。中核には自作の数式処理があり、式を構文木へ落とし、循環を検出し、依存の順に再計算する。欄どうしの参照と、その集約も自前で持つ。予定表との双方向は、変更の目印を先に確かめてから差分を引き、一日に一度は全件を突き合わせる。削除は自分の管理下にある暦の住所に限定し、影響の及ぶ範囲を構造として閉じた。帳票の書き出しは外部への送信を遮断した環境で行い、会計と社内基盤との連携、および送信の基盤も同じ木の中にある。
コード規模 — 317,562 行 / 893 ファイル1
7Performance
性能については、施策までしか書けない。前後を比較した計測が資料に残っていないためである。実際に入れたのは、見積の編集における初期化の遅延と合計値の記憶化、価格表の実体を一つに畳むこと、予定表の取得において変更の目印を先に問い合わせる二段構えと、間隔を広げながら無作為の揺らぎを加える再試行、そして派生する値は同期せず各端末で計算し直して送る量を減らすことである。効果の裏付けは取っていないので、改善したとは書かない。
8Outcome
自分の設備の上で本番として動いており、外部へ開いた口は持たない。Tailscale の内側からのみ到達できるため外形からの確認はできないが、日々の業務で実際に使っている。試験と関門の通過状況、鍵をかけた保管の実機確認、送信の到達性の評価は本節末の計測に示す。出荷前のレビューでは、見積の帳票と編集画面とで小計の値が食い違うという重大な欠陥が見つかり、数える対象を判定する述語を一つに統一することで根から断った。
テスト — 23,020 pass / 0 fail(ci-gate 10 ゲート green)2
メール配信性 — mail-tester 10/103
R2 暗号化 — 実機スモーク全項目合格(暗号文が平文を部分列として含まないことを実証)4
9Caveats found during review
作業ツリーの主枝は古い時点で止まっており、現行の線は別の枝にある。枝を取り違えると、存在しない状態を見ることになる。
机上の外殻と表計算相当の部品は、設計の決定としては書かれているが、依存としては入っておらず実装もされていない。決定は成果物ではない。
同時編集のための中継は既定で無効であり、本番では動いていない。稼働しているのは欄の単位の経路だけである。
関係型の別実装への書き出しは削除済みで、現在は単一ファイルの実装への書き出しだけが残っている。
製品の名称は途中で改めており、以前に撮った画面はすべて旧称のままである。
性能の施策には前後の計測がない。数字を出せないという意味であって、効果が確かめられているという意味ではない。
10AI assistance
実装そのものは言語モデルのエージェントが受け持ち、設計の決定と受け入れの判断は本人が持つ分業で進めており、出荷前に見つかった小計の食い違いのような重大な欠陥も、この分業と検収の往復の中で表に出ている。