From f3326e97f770bb5cab1b0673489989d30f3eac97 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Wed, 15 Apr 2026 16:47:57 +0900 Subject: [PATCH 1/2] README: restructure as a pattern index with mermaid shapes Shift the entry point from philosophy-first to problem-first: - Replace the top-of-file "Philosophy" section with a "Choose a pattern" use-case index. Readers match their problem to a pattern without having to learn the ontology first. - Add an abstract mermaid flowchart to each pattern card so the shape is scannable at a glance. Concrete class-name flows are kept below as reference. - Drop the Beginner/Intermediate/Advanced level labels; complexity is already implied by ordering and the diagrams. - Drop the numeric "At a glance" counts table; the shapes convey the same information visually. - Move the six-layer vocabulary table into a "Background" section at the end with links to CLAUDE.md, GLOSSARY.md and PHILOSOPHY.md. - Rename the title from "BE Framework Demos" to "Be Framework Patterns" to match the repository rebrand. - Fix the stale `composer test` instruction (no root composer exists; each demo installs independently). Japanese README mirrors all of the above. --- README.ja.md | 252 +++++++++++++++++++++++++++++++------------------- README.md | 256 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 314 insertions(+), 194 deletions(-) diff --git a/README.ja.md b/README.ja.md index 44356ce..119c264 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1,160 +1,220 @@ -# BE Framework デモ集 +# Be Framework パターン集 -BE Frameworkの存在論的プログラミングアプローチを示すデモプロジェクト集です。 +[Be Framework](https://github.com/be-framework/be) のための**変容(メタモルフォーシス)パターンカタログ**です。8つの実行可能なPHPデモを収録し、それぞれが1つのフロー形状を独立して示しているため、自分のアプリケーションの出発点としてそのままコピーできます。 -## 哲学 +> **「Be, Don't Do(するな、あれ)」** — すべてのパターンは、ワークフローを「データに対して動作するメソッド」ではなく、「次の状態へと *becoming* する型付き・不変な状態の連鎖」としてモデル化します。 -BE Frameworkは「Be, Don't Do(するな、あれ)」の原則を体現しています。ソフトウェアを動作の連続ではなく、存在の変容(メタモルフォーシス)としてモデル化します。各デモは6つの哲学的レイヤーを通じて異なる変容パターンを示します: +--- -| レイヤー | 語源 | 役割 | -|---------|------|------| -| **Input** | δύναμις(デュナミス) | システムに入る生の可能態 | -| **Being** | Dasein(現存在) | 計算されたプロパティを持つ存在状態 | -| **Moment** | 契機 | 遅延Potentialを持つ過渡的段階 | -| **Final** | ἐνέργεια(エネルゲイア) | 完全に現実化された結果 | -| **Semantic** | Sinn(意味) | ドメイン検証ルール | -| **Reason** | 充足理由律 | ビジネスロジックと外部連携 | +## パターンを選ぶ -## デモカタログ +あなたの問題に最も近い行を選んでください。各リンクから完全な実装(テスト付き)に飛べます。 -### 初級 +| こんな問題には… | パターン | デモ | +|---|---|---| +| 入力1、出力1、中間状態なし | **最小変換** | [hello-world](./demos/hello-world/) | +| 単一フォームの検証と正規化 | **線形** | [contact-form](./demos/contact-form/) | +| 順序のある複数の変換 | **連鎖チェーン** | [user-registration](./demos/user-registration/) | +| 独立した関心事を並列処理して収束 | **ダイヤモンド** | [order-processing](./demos/order-processing/) | +| 段階的な中間コミットを伴う連鎖 | **連鎖 + Moment** | [blog-publishing](./demos/blog-publishing/) | +| 1入力から判定で複数結果に分岐 | **分岐** | [medical-triage](./demos/medical-triage/) | +| 直列2段、各段に独自の並列性 | **カスケードダイヤモンド** | [loan-application](./demos/loan-application/) | +| 複数入力が収束→並列→分岐 | **複合収束** | [insurance-claim](./demos/insurance-claim/) | -#### [hello-world](./demos/hello-world/) -**パターン:** 最小変換 -**フロー:** `Input → Final` +> このカタログの機械可読版は [`docs/patterns.json`](./docs/patterns.json) にあります。 + +--- + +## パターンカタログ -最もシンプルなBE Frameworkデモ。BeingやMomentレイヤーを持たない挨拶変換です。 +### 最小変換 — [hello-world](./demos/hello-world/) -```text -HelloInput → Hello +**フロー:** `Input → Final` + +```mermaid +flowchart LR + I([Input]) --> F([Final]) ``` -#### [contact-form](./demos/contact-form/) -**パターン:** 線形変換 -**フロー:** `Input → Being → Final` +最もシンプルなBe Frameworkデモ。BeingやMomentレイヤーを持たない挨拶変換です。 -最もシンプルなBE Frameworkパターン。基本的な入力検証、メール正規化、受領証生成を示すお問い合わせフォームです。 +> 具体: `HelloInput → Hello` -```text -ContactInput → EmailNormalized → ContactReceived +### 線形 — [contact-form](./demos/contact-form/) + +**フロー:** `Input → Being → Final` + +```mermaid +flowchart LR + I([Input]) --> B([Being]) --> F([Final]) ``` -#### [user-registration](./demos/user-registration/) -**パターン:** 連鎖チェーン +基本的な入力検証、メール正規化、受領証生成を示すお問い合わせフォームです。 + +> 具体: `ContactInput → EmailNormalized → ContactReceived` + +### 連鎖チェーン — [user-registration](./demos/user-registration/) + **フロー:** `Input → Being(A) → Being(B) → Being(C) → Final` +```mermaid +flowchart LR + I([Input]) --> B1([Being]) --> B2([Being]) --> B3([Being]) --> F([Final]) +``` + Being変換を連鎖させたユーザー登録:メール検証、パスワードハッシュ化、プロフィール拡充。 -```text -RegistrationInput → EmailVerified → PasswordHashed → ProfileEnriched → UserRegistered -``` +> 具体: `RegistrationInput → EmailVerified → PasswordHashed → ProfileEnriched → UserRegistered` -### 中級 +### ダイヤモンド — [order-processing](./demos/order-processing/) -#### [order-processing](./demos/order-processing/) -**パターン:** ダイヤモンドメタモルフォーシス **フロー:** `Input → [並列Beings] → [並列Moments] → Final` +```mermaid +flowchart LR + I([Input]) --> B1([Being]) + I --> B2([Being]) + I --> B3([Being]) + B1 --> M1([Moment]) --> F([Final]) + B2 --> M2([Moment]) --> F + B3 --> M3([Moment]) --> F +``` + 並列Beingチェーン(在庫、決済、配送)がMomentを生成し、Final状態で収束するECオーダー処理。 -```text -OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed - ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ - └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ -``` +> 具体: +> ```text +> OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed +> ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ +> └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ +> ``` -#### [blog-publishing](./demos/blog-publishing/) -**パターン:** 連鎖変換(3 Being、2 Moment) -**フロー:** `Input → Moment → Being → Being → Moment → Being → Final` +### 連鎖 + Moment — [blog-publishing](./demos/blog-publishing/) -マークダウンレンダリング、スラグ生成、抜粋抽出、著者解決を段階的に処理する記事公開デモ。BeingクラスはArticlePrepared、MarkdownRendered、SlugGenerated。MomentクラスはContentPreparedとMetadataResolved。 +**フロー:** `Input → Moment → Being → Being → Moment → Being → Final` -```text -ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished +```mermaid +flowchart LR + I([Input]) --> M1([Moment]) --> B1([Being]) --> B2([Being]) --> M2([Moment]) --> B3([Being]) --> F([Final]) ``` -### 上級 +3つのBeingクラス(`ArticlePrepared`、`MarkdownRendered`、`SlugGenerated`)と2つのMomentクラス(`ContentPrepared`、`MetadataResolved`)を通じて、マークダウンレンダリング、スラグ生成、抜粋抽出、著者解決を段階的に処理する記事公開デモ。 + +> 具体: `ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished` + +### 分岐 — [medical-triage](./demos/medical-triage/) -#### [medical-triage](./demos/medical-triage/) -**パターン:** 分岐メタモルフォーシス **フロー:** `Input → Being → [分岐] → Final(A) | Final(B) | Final(C)` +```mermaid +flowchart LR + I([Input]) --> B([Being]) + B --> F1([Final A]) + B --> F2([Final B]) + B --> F3([Final C]) +``` + JTASプロトコルを実装した救急トリアージ。1つの入力が型付き`$being`識別子を通じて3つの異なるFinalに分岐し、各分岐の振る舞いはReason戦略クラスが保持します。 -```text -PatientInput → TriageLevelDetermined - │ - ┌──────────────┼──────────────┐ - ↓ ↓ ↓ - [ImmediateCase] [UrgentCase] [NonUrgentCase] - ↓ ↓ ↓ -EmergencyAdmitted UrgentQueued OutpatientReferred -``` +> 具体: +> ```text +> PatientInput → TriageLevelDetermined +> │ +> ┌──────────────┼──────────────┐ +> ↓ ↓ ↓ +> [ImmediateCase] [UrgentCase] [NonUrgentCase] +> ↓ ↓ ↓ +> EmergencyAdmitted UrgentQueued OutpatientReferred +> ``` + +### カスケードダイヤモンド — [loan-application](./demos/loan-application/) -#### [loan-application](./demos/loan-application/) -**パターン:** カスケードダイヤモンド(2段階) **フロー:** `Input → Stage1(並列 → 収束) → Stage2(並列 → Final)` +```mermaid +flowchart LR + I([Input]) --> S([Being]) + S --> A1([Being]) --> AM1([Moment]) --> C([Being]) + S --> A2([Being]) --> AM2([Moment]) --> C + C --> D1([Being]) --> DM1([Moment]) --> F([Final]) + C --> D2([Being]) --> DM2([Moment]) --> F +``` + 段階的Moment実現を伴う住宅ローン申請。Stage 1のMomentは適格性確認時に実現、Stage 2のMomentは最終承認時に実現。 -```text -LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed - └→ IncomeAssessed → IncomeApproved ─┘ - ↓ - ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved - └→ InsuranceQuoted → InsurancePrepared ─┘ -``` +> 具体: +> ```text +> LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed +> └→ IncomeAssessed → IncomeApproved ─┘ +> ↓ +> ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved +> └→ InsuranceQuoted → InsurancePrepared ─┘ +> ``` -#### [insurance-claim](./demos/insurance-claim/) -**パターン:** 複合収束 -**フロー:** `Input(A) + Input(B) → 収束 → 並列(3) → 分岐 → Final(A) | Final(B)` +### 複合収束 — [insurance-claim](./demos/insurance-claim/) -複数入力の収束、3方向並列評価、分岐Finalを持つ保険請求処理。 +**フロー:** `Input(A) + Input(B) → 収束 → 並列(3) → 分岐 → Final(A) | Final(B)` -```text -ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [閾値判定] → ClaimSettled -PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ または - └→ FraudScreened ─┘ ClaimEscalated +```mermaid +flowchart LR + I1([Input A]) --> C([Being]) + I2([Input B]) --> C + C --> P1([Being]) + C --> P2([Being]) + C --> P3([Being]) + P1 --> D{分岐} + P2 --> D + P3 --> D + D --> F1([Final A]) + D --> F2([Final B]) ``` -## パターン一覧 +複数入力の収束、3方向並列評価、分岐Finalを持つ保険請求処理。 -| パターン | デモ | 入力数 | Being数 | Moment数 | Final数 | -|---------|------|--------|---------|----------|---------| -| 最小 | hello-world | 1 | 0 | 0 | 1 | -| 線形 | contact-form | 1 | 1 | 0 | 1 | -| 連鎖 | user-registration | 1 | 3 | 0 | 1 | -| ダイヤモンド | order-processing | 1 | 6 | 6 | 1 | -| 連鎖 | blog-publishing | 1 | 3 | 2 | 1 | -| 分岐 | medical-triage | 1 | 1 | 0 | 3 | -| カスケード | loan-application | 1 | 5 | 4 | 1 | -| 複合 | insurance-claim | 2 | 5 | 3 | 2 | +> 具体: +> ```text +> ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [閾値判定] → ClaimSettled +> PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ または +> └→ FraudScreened ─┘ ClaimEscalated +> ``` -## テスト実行 +--- -各デモには以下をカバーする包括的なテストが含まれます: -- 正常系統合テスト -- Semantic検証単体テスト -- Reasonレイヤーロジックテスト -- Potential冪等性テスト(該当する場合) +## テスト実行 ```bash -# 全テスト実行 -composer test - # 特定デモのテスト実行 -./demos/vendor/bin/phpunit demos/medical-triage/tests/ +cd demos/hello-world && composer install && vendor/bin/phpunit ``` +各デモには正常系統合テスト、Semantic検証単体テスト、Reasonレイヤーロジックテスト、そして該当する場合はPotential冪等性テストが含まれます。 + ## 要件 - PHP 8.2+ - [Ray.Di](https://ray-di.github.io/)(依存性注入) +## 背景 + +上記のすべてのパターンは、同じ6つのレイヤーからなる語彙で構築されています。パターンをコピーして使うだけならこの語彙を理解する必要は**ありません**。さらに深く学びたい場合は以下から: + +- [`CLAUDE.md`](./CLAUDE.md) — 不変条件と読み順(AIアシスタント向けの契約でもあります) +- [`docs/GLOSSARY.md`](./docs/GLOSSARY.md) — 用語→ファイル逆引きインデックス +- [`demos/order-processing/docs/PHILOSOPHY.md`](./demos/order-processing/docs/PHILOSOPHY.md) — 概念的な理論的背景 + +| レイヤー | 語源 | 役割 | +|---|---|---| +| **Input** | δύναμις(デュナミス) | システムに入る生の可能態 | +| **Being** | Dasein(現存在) | 計算されたプロパティを持つ存在状態 | +| **Moment** | 契機 | 遅延Potentialを持つ過渡的段階 | +| **Final** | ἐνέργεια(エネルゲイア) | 完全に現実化された結果 | +| **Semantic** | Sinn(意味) | ドメイン検証ルール | +| **Reason** | 充足理由律 | ビジネスロジックと外部連携 | + ## ライセンス MIT --- -[English version](./README.md) \ No newline at end of file +[English version](./README.md) diff --git a/README.md b/README.md index 80d5cbb..da6f0a4 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,220 @@ -# BE Framework Demos +# Be Framework Patterns -A collection of demonstration projects showcasing the BE Framework's ontological programming approach. +A catalog of **metamorphosis patterns** for the [Be Framework](https://github.com/be-framework/be) — eight runnable PHP demos, each isolating one flow shape so you can copy it as a starting point for your own application. -## Philosophy +> **"Be, Don't Do."** Every pattern models a workflow as a chain of typed, immutable *states that become the next state*, rather than methods that act on data. -The BE Framework embodies the principle "Be, Don't Do" - modeling software as transformations of being rather than sequences of actions. Each demo illustrates different metamorphosis patterns through six philosophical layers: +--- -| Layer | Greek/German | Role | -|-------|--------------|------| -| **Input** | δύναμις (Dynamis) | Raw potential entering the system | -| **Being** | Dasein | Existential state with computed properties | -| **Moment** | 契機 (Keiki) | Transitional phase with deferred Potentials | -| **Final** | ἐνέργεια (Energeia) | Fully actualized result | -| **Semantic** | Sinn | Domain validation rules | -| **Reason** | Sufficient Reason | Business logic and external integrations | +## Choose a pattern -## Demo Catalog +Pick the row that best describes your problem. Each link goes to a complete, tested implementation. -### Beginner Level +| If your problem looks like… | Pattern | Demo | +|---|---|---| +| One input, one output — no intermediate state | **Minimal** | [hello-world](./demos/hello-world/) | +| Validate and normalize a single form | **Linear** | [contact-form](./demos/contact-form/) | +| Several transformations that must run in order | **Sequential Chain** | [user-registration](./demos/user-registration/) | +| Independent concerns that run in parallel and merge | **Diamond** | [order-processing](./demos/order-processing/) | +| A sequential chain with staged intermediate commits | **Sequential + Moments** | [blog-publishing](./demos/blog-publishing/) | +| One input, several outcomes chosen by a decision | **Branching** | [medical-triage](./demos/medical-triage/) | +| Two pipelines in series, each with its own parallelism | **Cascade Diamond** | [loan-application](./demos/loan-application/) | +| Multiple inputs converge, fan out, then branch | **Complex Convergence** | [insurance-claim](./demos/insurance-claim/) | -#### [hello-world](./demos/hello-world/) -**Pattern:** Minimal Transformation -**Flow:** `Input → Final` +> A machine-readable version of this catalog lives in [`docs/patterns.json`](./docs/patterns.json). + +--- + +## Pattern catalog -The simplest possible BE Framework demo. A greeting transformation with no Being or Moment layers. +### Minimal — [hello-world](./demos/hello-world/) -```text -HelloInput → Hello +**Flow:** `Input → Final` + +```mermaid +flowchart LR + I([Input]) --> F([Final]) ``` -#### [contact-form](./demos/contact-form/) -**Pattern:** Linear Transformation -**Flow:** `Input → Being → Final` +The simplest possible Be Framework demo. A greeting transformation with no Being or Moment layers. -The simplest BE Framework pattern. An email contact form demonstrating basic input validation, email normalization, and receipt generation. +> Concrete: `HelloInput → Hello` -```text -ContactInput → EmailNormalized → ContactReceived +### Linear — [contact-form](./demos/contact-form/) + +**Flow:** `Input → Being → Final` + +```mermaid +flowchart LR + I([Input]) --> B([Being]) --> F([Final]) ``` -#### [user-registration](./demos/user-registration/) -**Pattern:** Sequential Chain +A contact form demonstrating basic input validation, email normalization, and receipt generation. + +> Concrete: `ContactInput → EmailNormalized → ContactReceived` + +### Sequential Chain — [user-registration](./demos/user-registration/) + **Flow:** `Input → Being(A) → Being(B) → Being(C) → Final` +```mermaid +flowchart LR + I([Input]) --> B1([Being]) --> B2([Being]) --> B3([Being]) --> F([Final]) +``` + User registration with chained Being transformations: email verification, password hashing, and profile enrichment. -```text -RegistrationInput → EmailVerified → PasswordHashed → ProfileEnriched → UserRegistered -``` +> Concrete: `RegistrationInput → EmailVerified → PasswordHashed → ProfileEnriched → UserRegistered` -### Intermediate Level +### Diamond — [order-processing](./demos/order-processing/) -#### [order-processing](./demos/order-processing/) -**Pattern:** Diamond Metamorphosis **Flow:** `Input → [parallel Beings] → [parallel Moments] → Final` +```mermaid +flowchart LR + I([Input]) --> B1([Being]) + I --> B2([Being]) + I --> B3([Being]) + B1 --> M1([Moment]) --> F([Final]) + B2 --> M2([Moment]) --> F + B3 --> M3([Moment]) --> F +``` + E-commerce order processing with parallel Being chains (Inventory, Payment, Shipping) that produce Moments converging in the Final state. -```text -OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed - ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ - └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ -``` +> Concrete: +> ```text +> OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed +> ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ +> └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ +> ``` -#### [blog-publishing](./demos/blog-publishing/) -**Pattern:** Sequential Chain (3 Beings, 2 Moments) -**Flow:** `Input → Moment → Being → Being → Moment → Being → Final` +### Sequential + Moments — [blog-publishing](./demos/blog-publishing/) -Article publishing with staged processing through three Being classes (ArticlePrepared, MarkdownRendered, SlugGenerated) and two Moment classes (ContentPrepared, MetadataResolved), handling markdown rendering, slug generation, excerpt extraction, and author resolution. +**Flow:** `Input → Moment → Being → Being → Moment → Being → Final` -```text -ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished +```mermaid +flowchart LR + I([Input]) --> M1([Moment]) --> B1([Being]) --> B2([Being]) --> M2([Moment]) --> B3([Being]) --> F([Final]) ``` -### Advanced Level +Article publishing staged through three Being classes (`ArticlePrepared`, `MarkdownRendered`, `SlugGenerated`) and two Moment classes (`ContentPrepared`, `MetadataResolved`), handling markdown rendering, slug generation, excerpt extraction, and author resolution. -#### [medical-triage](./demos/medical-triage/) -**Pattern:** Branching Metamorphosis -**Flow:** `Input → Being → [Branch] → Final(A) | Final(B) | Final(C)` +> Concrete: `ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished` -Emergency room triage implementing JTAS protocol. One input branches to three possible Finals via a typed `$being` discriminator, with each branch's behavior carried by a Reason strategy class. +### Branching — [medical-triage](./demos/medical-triage/) + +**Flow:** `Input → Being → [Branch] → Final(A) | Final(B) | Final(C)` -```text -PatientInput → TriageLevelDetermined - │ - ┌──────────────┼──────────────┐ - ↓ ↓ ↓ - [ImmediateCase] [UrgentCase] [NonUrgentCase] - ↓ ↓ ↓ -EmergencyAdmitted UrgentQueued OutpatientReferred +```mermaid +flowchart LR + I([Input]) --> B([Being]) + B --> F1([Final A]) + B --> F2([Final B]) + B --> F3([Final C]) ``` -#### [loan-application](./demos/loan-application/) -**Pattern:** Cascade Diamond (2-Stage) +Emergency room triage implementing the JTAS protocol. One input branches to three possible Finals via a typed `$being` discriminator, with each branch's behavior carried by a Reason strategy class. + +> Concrete: +> ```text +> PatientInput → TriageLevelDetermined +> │ +> ┌──────────────┼──────────────┐ +> ↓ ↓ ↓ +> [ImmediateCase] [UrgentCase] [NonUrgentCase] +> ↓ ↓ ↓ +> EmergencyAdmitted UrgentQueued OutpatientReferred +> ``` + +### Cascade Diamond — [loan-application](./demos/loan-application/) + **Flow:** `Input → Stage1(parallel → converge) → Stage2(parallel → Final)` +```mermaid +flowchart LR + I([Input]) --> S([Being]) + S --> A1([Being]) --> AM1([Moment]) --> C([Being]) + S --> A2([Being]) --> AM2([Moment]) --> C + C --> D1([Being]) --> DM1([Moment]) --> F([Final]) + C --> D2([Being]) --> DM2([Moment]) --> F +``` + Mortgage application with staged Moment realization. Stage 1 Moments realize at eligibility confirmation; Stage 2 Moments realize at final approval. -```text -LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed - └→ IncomeAssessed → IncomeApproved ─┘ - ↓ - ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved - └→ InsuranceQuoted → InsurancePrepared ─┘ -``` +> Concrete: +> ```text +> LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed +> └→ IncomeAssessed → IncomeApproved ─┘ +> ↓ +> ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved +> └→ InsuranceQuoted → InsurancePrepared ─┘ +> ``` -#### [insurance-claim](./demos/insurance-claim/) -**Pattern:** Complex Convergence -**Flow:** `Input(A) + Input(B) → converge → parallel(3) → Branch → Final(A) | Final(B)` +### Complex Convergence — [insurance-claim](./demos/insurance-claim/) -Insurance claim processing with multiple input convergence, three-way parallel assessment, and branching finals. +**Flow:** `Input(A) + Input(B) → converge → parallel(3) → Branch → Final(A) | Final(B)` -```text -ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [threshold] → ClaimSettled -PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ or - └→ FraudScreened ─┘ ClaimEscalated +```mermaid +flowchart LR + I1([Input A]) --> C([Being]) + I2([Input B]) --> C + C --> P1([Being]) + C --> P2([Being]) + C --> P3([Being]) + P1 --> D{Branch} + P2 --> D + P3 --> D + D --> F1([Final A]) + D --> F2([Final B]) ``` -## Pattern Summary +Insurance claim processing with multiple input convergence, three-way parallel assessment, and branching finals. -| Pattern | Demo | Inputs | Beings | Moments | Finals | -|---------|------|--------|--------|---------|--------| -| Minimal | hello-world | 1 | 0 | 0 | 1 | -| Linear | contact-form | 1 | 1 | 0 | 1 | -| Sequential | user-registration | 1 | 3 | 0 | 1 | -| Diamond | order-processing | 1 | 6 | 6 | 1 | -| Sequential | blog-publishing | 1 | 3 | 2 | 1 | -| Branching | medical-triage | 1 | 1 | 0 | 3 | -| Cascade | loan-application | 1 | 5 | 4 | 1 | -| Complex | insurance-claim | 2 | 5 | 3 | 2 | +> Concrete: +> ```text +> ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [threshold] → ClaimSettled +> PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ or +> └→ FraudScreened ─┘ ClaimEscalated +> ``` -## Running Tests +--- -Each demo includes comprehensive tests covering: -- Happy path integration tests -- Semantic validation unit tests -- Reason layer logic tests -- Potential idempotency tests (where applicable) +## Running tests ```bash -# Run all tests -composer test - -# Run specific demo tests -./demos/vendor/bin/phpunit demos/medical-triage/tests/ +# Run a specific demo +cd demos/hello-world && composer install && vendor/bin/phpunit ``` +Every demo ships with happy-path integration tests, Semantic validation unit tests, Reason layer logic tests, and (where applicable) Potential idempotency tests. + ## Requirements - PHP 8.2+ - [Ray.Di](https://ray-di.github.io/) (dependency injection) +## Background + +Every pattern above is built from the same six-layer vocabulary. You do **not** need to understand the vocabulary to copy a pattern — but when you want to go deeper, start here: + +- [`CLAUDE.md`](./CLAUDE.md) — invariants and reading order (also the AI assistant contract) +- [`docs/GLOSSARY.md`](./docs/GLOSSARY.md) — term-to-file reverse index +- [`demos/order-processing/docs/PHILOSOPHY.md`](./demos/order-processing/docs/PHILOSOPHY.md) — the conceptual rationale + +| Layer | Greek / German | Role | +|---|---|---| +| **Input** | δύναμις (Dynamis) | Raw potential entering the system | +| **Being** | Dasein | Existential state with computed properties | +| **Moment** | 契機 (Keiki) | Transitional phase with deferred Potentials | +| **Final** | ἐνέργεια (Energeia) | Fully actualized result | +| **Semantic** | Sinn | Domain validation rules | +| **Reason** | Sufficient Reason | Business logic and external integrations | + ## License MIT --- -[日本語版はこちら](./README.ja.md) \ No newline at end of file +[日本語版はこちら](./README.ja.md) From e186e85ea2141dd2f5255472b35830651942a881 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Wed, 15 Apr 2026 17:01:17 +0900 Subject: [PATCH 2/2] README: align pattern diagrams with patterns.json (CodeRabbit review) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit pointed out that the Diamond, Cascade Diamond, Complex Convergence and blog-publishing cards described Being-centric flows that don't match docs/patterns.json (which is the ground truth, verified against the source): - order-processing (diamond): being=0, moment=3 — Input goes directly to OrderConfirmed, which injects three Moments. The old ASCII/mermaid showed three parallel Being chains that are not in the #[Be] graph. - loan-application (cascade-diamond): being=0, moment=2 — Input goes directly to LoanApproved, which injects two Moments. The "cascade" is internal to the Moments' Potentials, not a two-stage Being pipeline. - insurance-claim (complex-convergence): being=0, moment=5, final=2 — both Inputs declare #[Be([ClaimSettled, ClaimEscalated])] and Moments are shared across both Finals. The old diagram showed a single converging Being followed by a fan-out. - blog-publishing (staged-sequential): being=1, moment=0 — externally Linear. The distinctive feature is a single Being that orchestrates several Reason services, not a 3-Being / 2-Moment chain. Fix: - Rewrite the four mermaid diagrams to match the live #[Be]/#[Inject] graph; use dashed arrows for injected Moments. - Rename "Sequential + Moments" to "Multi-Reason Being" and rewrite the description to be about Reason orchestration. - Update the "Choose a pattern" use-case descriptions for the four affected rows. - Add a diagram legend at the top of the catalog explaining solid vs dashed arrows. README.ja.md mirrors all of the above. --- README.ja.md | 90 ++++++++++++++++++++-------------------------------- README.md | 90 ++++++++++++++++++++-------------------------------- 2 files changed, 68 insertions(+), 112 deletions(-) diff --git a/README.ja.md b/README.ja.md index 119c264..3d7c937 100644 --- a/README.ja.md +++ b/README.ja.md @@ -15,13 +15,15 @@ | 入力1、出力1、中間状態なし | **最小変換** | [hello-world](./demos/hello-world/) | | 単一フォームの検証と正規化 | **線形** | [contact-form](./demos/contact-form/) | | 順序のある複数の変換 | **連鎖チェーン** | [user-registration](./demos/user-registration/) | -| 独立した関心事を並列処理して収束 | **ダイヤモンド** | [order-processing](./demos/order-processing/) | -| 段階的な中間コミットを伴う連鎖 | **連鎖 + Moment** | [blog-publishing](./demos/blog-publishing/) | +| 独立した関心事が注入Momentを通じてFinalで収束 | **ダイヤモンド** | [order-processing](./demos/order-processing/) | +| 1つのBeingが複数Reasonサービスをオーケストレーション | **マルチReason Being** | [blog-publishing](./demos/blog-publishing/) | | 1入力から判定で複数結果に分岐 | **分岐** | [medical-triage](./demos/medical-triage/) | -| 直列2段、各段に独自の並列性 | **カスケードダイヤモンド** | [loan-application](./demos/loan-application/) | -| 複数入力が収束→並列→分岐 | **複合収束** | [insurance-claim](./demos/insurance-claim/) | +| 段階的なMoment実現(ステージ1がステージ2のゲート) | **カスケードダイヤモンド** | [loan-application](./demos/loan-application/) | +| 複数入力が複数Finalに分岐し、Momentを共有 | **複合収束** | [insurance-claim](./demos/insurance-claim/) | > このカタログの機械可読版は [`docs/patterns.json`](./docs/patterns.json) にあります。 +> +> **図の凡例**: 実線矢印(`→`)は `#[Be]` による変換チェーン。破線矢印(`⇢`)は `#[Inject]` で Final に注入される Moment を表し、各 Moment は Final のコンストラクタ内で自己完結(`be()`)します。 --- @@ -68,39 +70,32 @@ Being変換を連鎖させたユーザー登録:メール検証、パスワー ### ダイヤモンド — [order-processing](./demos/order-processing/) -**フロー:** `Input → [並列Beings] → [並列Moments] → Final` +**フロー:** `Input → Final`(3つのMomentがFinalに注入される) ```mermaid flowchart LR - I([Input]) --> B1([Being]) - I --> B2([Being]) - I --> B3([Being]) - B1 --> M1([Moment]) --> F([Final]) - B2 --> M2([Moment]) --> F - B3 --> M3([Moment]) --> F + I([Input]) --> F([Final]) + M1([Moment]) -.-> F + M2([Moment]) -.-> F + M3([Moment]) -.-> F ``` -並列Beingチェーン(在庫、決済、配送)がMomentを生成し、Final状態で収束するECオーダー処理。 +ECオーダー処理。`OrderInput` は直接 `OrderConfirmed` に遷移し、`OrderConfirmed` が3つの独立した Moment(`InventoryReserved`、`PaymentCompleted`、`ShippingArranged`)を `#[Inject]` します。各 Moment の `be()` は `OrderConfirmed` のコンストラクタ内で呼び出され、3つの関心事が1点で自己完結する「ダイヤモンドメタモルフォーシス」を形成します。 -> 具体: -> ```text -> OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed -> ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ -> └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ -> ``` +> 具体: `OrderInput → OrderConfirmed`(Final に `InventoryReserved`・`PaymentCompleted`・`ShippingArranged` を注入) -### 連鎖 + Moment — [blog-publishing](./demos/blog-publishing/) +### マルチReason Being — [blog-publishing](./demos/blog-publishing/) -**フロー:** `Input → Moment → Being → Being → Moment → Being → Final` +**フロー:** `Input → Being → Final` ```mermaid flowchart LR - I([Input]) --> M1([Moment]) --> B1([Being]) --> B2([Being]) --> M2([Moment]) --> B3([Being]) --> F([Final]) + I([Input]) --> B([Being]) --> F([Final]) ``` -3つのBeingクラス(`ArticlePrepared`、`MarkdownRendered`、`SlugGenerated`)と2つのMomentクラス(`ContentPrepared`、`MetadataResolved`)を通じて、マークダウンレンダリング、スラグ生成、抜粋抽出、著者解決を段階的に処理する記事公開デモ。 +記事公開デモ。外形的には Linear と同じ `ArticleInput → ArticlePrepared → ArticlePublished` です。特徴は中間 Being(`ArticlePrepared`)が複数の Reason サービス(`MarkdownRenderer`、`SlugGenerator`、`ExcerptExtractor`、`AuthorResolver`)をオーケストレーションし、マークダウンレンダリング・スラグ生成・抜粋抽出・著者解決を1つの変換の中でまとめて行う点にあります。 -> 具体: `ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished` +> 具体: `ArticleInput → ArticlePrepared → ArticlePublished` ### 分岐 — [medical-triage](./demos/medical-triage/) @@ -129,54 +124,37 @@ JTASプロトコルを実装した救急トリアージ。1つの入力が型付 ### カスケードダイヤモンド — [loan-application](./demos/loan-application/) -**フロー:** `Input → Stage1(並列 → 収束) → Stage2(並列 → Final)` +**フロー:** `Input → Final`(2つのMomentがFinalに注入され、段階的に実現される) ```mermaid flowchart LR - I([Input]) --> S([Being]) - S --> A1([Being]) --> AM1([Moment]) --> C([Being]) - S --> A2([Being]) --> AM2([Moment]) --> C - C --> D1([Being]) --> DM1([Moment]) --> F([Final]) - C --> D2([Being]) --> DM2([Moment]) --> F + I([Input]) --> F([Final]) + M1([Moment · ステージ1]) -.-> F + M2([Moment · ステージ2]) -.-> F ``` -段階的Moment実現を伴う住宅ローン申請。Stage 1のMomentは適格性確認時に実現、Stage 2のMomentは最終承認時に実現。 +住宅ローン申請デモ。`LoanInput` は直接 `LoanApproved` に遷移し、`LoanApproved` が `CollateralValued` と `InsurancePrepared` を注入します。「カスケード」は Moment 内部の Potential にあり、ステージ1の関心事(身元確認・信用・所得)がステージ2の関心事(物件評価・保険)より先に実現されなければならない点を指します。両ステージは1つの Final に収束します。 -> 具体: -> ```text -> LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed -> └→ IncomeAssessed → IncomeApproved ─┘ -> ↓ -> ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved -> └→ InsuranceQuoted → InsurancePrepared ─┘ -> ``` +> 具体: `LoanInput → LoanApproved`(Final に `CollateralValued`・`InsurancePrepared` を注入) ### 複合収束 — [insurance-claim](./demos/insurance-claim/) -**フロー:** `Input(A) + Input(B) → 収束 → 並列(3) → 分岐 → Final(A) | Final(B)` +**フロー:** 2つの Input が、共有 Moment を注入された 2つの Final のいずれかに分岐する ```mermaid flowchart LR - I1([Input A]) --> C([Being]) - I2([Input B]) --> C - C --> P1([Being]) - C --> P2([Being]) - C --> P3([Being]) - P1 --> D{分岐} - P2 --> D - P3 --> D - D --> F1([Final A]) - D --> F2([Final B]) + I1([Input A]) --> F1([Final A]) + I1 --> F2([Final B]) + I2([Input B]) --> F1 + I2 --> F2 + M1([Moment]) -.-> F1 & F2 + M2([Moment]) -.-> F1 & F2 + M3([Moment]) -.-> F1 & F2 ``` -複数入力の収束、3方向並列評価、分岐Finalを持つ保険請求処理。 +保険請求処理デモ。`ClaimInput` と `PolicyInput` はどちらも `#[Be([ClaimSettled, ClaimEscalated])]` を宣言しており、`$being` の型マッチングによって各 Input がちょうど1つの Final に解決されます。`DamageValued`、`AdjustmentReviewed`、`FraudCleared` などの Moment は両方の Final に注入されるため、どちらの分岐を辿っても同じ自己完結ロジックが共有されます。 -> 具体: -> ```text -> ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [閾値判定] → ClaimSettled -> PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ または -> └→ FraudScreened ─┘ ClaimEscalated -> ``` +> 具体: `ClaimInput` + `PolicyInput` → `ClaimSettled` または `ClaimEscalated`(各 Final に共有 Moment を注入) --- diff --git a/README.md b/README.md index da6f0a4..2695c6f 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,15 @@ Pick the row that best describes your problem. Each link goes to a complete, tes | One input, one output — no intermediate state | **Minimal** | [hello-world](./demos/hello-world/) | | Validate and normalize a single form | **Linear** | [contact-form](./demos/contact-form/) | | Several transformations that must run in order | **Sequential Chain** | [user-registration](./demos/user-registration/) | -| Independent concerns that run in parallel and merge | **Diamond** | [order-processing](./demos/order-processing/) | -| A sequential chain with staged intermediate commits | **Sequential + Moments** | [blog-publishing](./demos/blog-publishing/) | +| Independent concerns converge in a Final via injected Moments | **Diamond** | [order-processing](./demos/order-processing/) | +| One Being orchestrating multiple Reason services | **Multi-Reason Being** | [blog-publishing](./demos/blog-publishing/) | | One input, several outcomes chosen by a decision | **Branching** | [medical-triage](./demos/medical-triage/) | -| Two pipelines in series, each with its own parallelism | **Cascade Diamond** | [loan-application](./demos/loan-application/) | -| Multiple inputs converge, fan out, then branch | **Complex Convergence** | [insurance-claim](./demos/insurance-claim/) | +| Staged Moment realization (stage 1 gates stage 2) | **Cascade Diamond** | [loan-application](./demos/loan-application/) | +| Multiple inputs branch to multiple Finals with shared Moments | **Complex Convergence** | [insurance-claim](./demos/insurance-claim/) | > A machine-readable version of this catalog lives in [`docs/patterns.json`](./docs/patterns.json). +> +> **Diagram legend.** Solid arrows (`→`) show the `#[Be]` transformation chain. Dashed arrows (`⇢`) show Moments injected into a Final via `#[Inject]`, where each Moment self-completes inside the Final constructor. --- @@ -68,39 +70,32 @@ User registration with chained Being transformations: email verification, passwo ### Diamond — [order-processing](./demos/order-processing/) -**Flow:** `Input → [parallel Beings] → [parallel Moments] → Final` +**Flow:** `Input → Final` with three Moments injected into the Final ```mermaid flowchart LR - I([Input]) --> B1([Being]) - I --> B2([Being]) - I --> B3([Being]) - B1 --> M1([Moment]) --> F([Final]) - B2 --> M2([Moment]) --> F - B3 --> M3([Moment]) --> F + I([Input]) --> F([Final]) + M1([Moment]) -.-> F + M2([Moment]) -.-> F + M3([Moment]) -.-> F ``` -E-commerce order processing with parallel Being chains (Inventory, Payment, Shipping) that produce Moments converging in the Final state. +E-commerce order processing. `OrderInput` transitions directly to `OrderConfirmed`, which injects three independent Moments — `InventoryReserved`, `PaymentCompleted`, `ShippingArranged`. Each Moment's `be()` is called inside the `OrderConfirmed` constructor, so the three concerns converge ("diamond metamorphosis") at a single point of self-completion. -> Concrete: -> ```text -> OrderInput ─┬→ StockLocated → QuantityChecked → InventoryReserved ─┬→ OrderConfirmed -> ├→ CardValidated → PaymentAuthorized → PaymentCompleted ─┤ -> └→ AddressValidated → CarrierSelected → ShippingArranged ─┘ -> ``` +> Concrete: `OrderInput → OrderConfirmed` with `InventoryReserved`, `PaymentCompleted`, `ShippingArranged` injected into the Final. -### Sequential + Moments — [blog-publishing](./demos/blog-publishing/) +### Multi-Reason Being — [blog-publishing](./demos/blog-publishing/) -**Flow:** `Input → Moment → Being → Being → Moment → Being → Final` +**Flow:** `Input → Being → Final` ```mermaid flowchart LR - I([Input]) --> M1([Moment]) --> B1([Being]) --> B2([Being]) --> M2([Moment]) --> B3([Being]) --> F([Final]) + I([Input]) --> B([Being]) --> F([Final]) ``` -Article publishing staged through three Being classes (`ArticlePrepared`, `MarkdownRendered`, `SlugGenerated`) and two Moment classes (`ContentPrepared`, `MetadataResolved`), handling markdown rendering, slug generation, excerpt extraction, and author resolution. +Article publishing. Externally the shape is Linear — `ArticleInput → ArticlePrepared → ArticlePublished`. What makes it distinctive is the intermediate Being (`ArticlePrepared`), which orchestrates several injected Reason services (`MarkdownRenderer`, `SlugGenerator`, `ExcerptExtractor`, `AuthorResolver`) to carry out markdown rendering, slug generation, excerpt extraction and author resolution in a single transformation. -> Concrete: `ArticleInput → ContentPrepared → ArticlePrepared → MarkdownRendered → MetadataResolved → SlugGenerated → ArticlePublished` +> Concrete: `ArticleInput → ArticlePrepared → ArticlePublished` ### Branching — [medical-triage](./demos/medical-triage/) @@ -129,54 +124,37 @@ Emergency room triage implementing the JTAS protocol. One input branches to thre ### Cascade Diamond — [loan-application](./demos/loan-application/) -**Flow:** `Input → Stage1(parallel → converge) → Stage2(parallel → Final)` +**Flow:** `Input → Final` with two Moments injected, realized in staged order ```mermaid flowchart LR - I([Input]) --> S([Being]) - S --> A1([Being]) --> AM1([Moment]) --> C([Being]) - S --> A2([Being]) --> AM2([Moment]) --> C - C --> D1([Being]) --> DM1([Moment]) --> F([Final]) - C --> D2([Being]) --> DM2([Moment]) --> F + I([Input]) --> F([Final]) + M1([Moment · stage 1]) -.-> F + M2([Moment · stage 2]) -.-> F ``` -Mortgage application with staged Moment realization. Stage 1 Moments realize at eligibility confirmation; Stage 2 Moments realize at final approval. +Mortgage application. `LoanInput` transitions directly to `LoanApproved`, which injects `CollateralValued` and `InsurancePrepared`. The "cascade" is in the Moments' internal Potentials: stage 1 concerns (identity, credit, income) must realize before stage 2 concerns (appraisal, insurance) can commit, even though both stages converge in a single Final. -> Concrete: -> ```text -> LoanInput → IdentityVerified ─┬→ CreditScored → CreditApproved ─┬→ EligibilityConfirmed -> └→ IncomeAssessed → IncomeApproved ─┘ -> ↓ -> ┌→ PropertyAppraised → CollateralValued ─┬→ LoanApproved -> └→ InsuranceQuoted → InsurancePrepared ─┘ -> ``` +> Concrete: `LoanInput → LoanApproved` with `CollateralValued`, `InsurancePrepared` injected into the Final. ### Complex Convergence — [insurance-claim](./demos/insurance-claim/) -**Flow:** `Input(A) + Input(B) → converge → parallel(3) → Branch → Final(A) | Final(B)` +**Flow:** Two Inputs, each branching to one of two Finals, with Moments shared across branches ```mermaid flowchart LR - I1([Input A]) --> C([Being]) - I2([Input B]) --> C - C --> P1([Being]) - C --> P2([Being]) - C --> P3([Being]) - P1 --> D{Branch} - P2 --> D - P3 --> D - D --> F1([Final A]) - D --> F2([Final B]) + I1([Input A]) --> F1([Final A]) + I1 --> F2([Final B]) + I2([Input B]) --> F1 + I2 --> F2 + M1([Moment]) -.-> F1 & F2 + M2([Moment]) -.-> F1 & F2 + M3([Moment]) -.-> F1 & F2 ``` -Insurance claim processing with multiple input convergence, three-way parallel assessment, and branching finals. +Insurance claim processing. `ClaimInput` and `PolicyInput` both declare `#[Be([ClaimSettled, ClaimEscalated])]`, so each Input resolves to exactly one of the two Finals by `$being` type matching. Moments such as `DamageValued`, `AdjustmentReviewed` and `FraudCleared` are injected into both Finals, so the same self-completion logic is shared regardless of which branch is taken. -> Concrete: -> ```text -> ClaimInput ──┬→ ClaimRegistered ─┬→ ClaimValidated ─┬→ DamageAssessed ─┬→ [threshold] → ClaimSettled -> PolicyInput ─┴→ PolicyVerified ─┘ ├→ AdjusterAssigned ─┤ or -> └→ FraudScreened ─┘ ClaimEscalated -> ``` +> Concrete: `ClaimInput` + `PolicyInput` → `ClaimSettled` | `ClaimEscalated`, with shared Moments injected into each Final. ---