AIKernel.NET
version: 0.0.4 / status: Implementation / edition: Draft / published: 2026-06-04 / updated: 2026-06-04

DSL Pipeline and ROM Specification

この文書は、AIKernel.Core に実装された標準 DSL pipeline 形式、 DSL ROM 実行モデル、HistoryROM 保存モデルを定義する。

DSL は C# ソースコードではない。JSON で表現された構造化 Semantic IR である。 AI が生成した計画は、検証され、決定論的な ResultStep pipeline に compile され、 不変 ROM 素材として保存され、再利用可能な capability として呼び出せる。


1. 設計規則

  • DSL は構造化データであり、実行コードではない。
  • root node は必ず Pipeline である。
  • すべての loop は有限である。LoopUntilmaxIterations を必須とする。
  • 未知の node type、未知の capability、不正な ROM 名、不正な field は fail-closed する。
  • Map projection は replay node を増やさない。実行された DSL node と loop transition は ResultStep replay entry として観測される。
  • Suspend は決定論的な停止点であり、background wait ではない。

2. JSON Node Schema

package-public DTO vocabulary は DslNodeTypes の canonical node type name を使用する。 論文や例との互換性のため、parser は CapabilityCallCallCapability の alias、 SuspendForApprovalSuspend の alias として受け付けてよい。ただし正規化済み DSL document は canonical name を出力する。

2.1 Pipeline

{\n  "type": "Pipeline",\n  "steps": []\n}

steps は必須で、pipeline node の配列でなければならない。

2.2 Step

{\n  "type": "Step",\n  "name": "start"\n}

Step は決定論的な実行 node を記録する。外部 capability は呼び出さず、現在の DSL pipeline value をそのまま引き継ぐ。

2.3 CallCapability

{\n  "type": "CallCapability",\n  "name": "Observe",\n  "args": {\n    "mode": "summary"\n  }\n}

nameIDslCapabilityRegistry で解決できなければならない。args は任意。 指定する場合は JSON object とする。文字列値は文字列として保持され、非文字列値は JSON text として渡される。

2.4 Loop

{\n  "type": "Loop",\n  "maxIterations": 3,\n  "body": [\n    { "type": "CallCapability", "name": "Observe" },\n    { "type": "CallCapability", "name": "Decide" }\n  ]\n}

maxIterations は 0 以上の整数でなければならない。各反復は body を実行し、 その後 loop_iterationloop_decision を持つ loop transition delta を記録する。

2.5 LoopUntil

{\n  "type": "LoopUntil",\n  "timeout": "00:00:10",\n  "maxIterations": 10,\n  "body": [\n    { "type": "CallCapability", "name": "Observe" }\n  ]\n}

timeout は必須で、秒数または TimeSpan 文字列で指定できる。 maxIterations も必須である。これは clock が timeout に到達しない場合でも loop を有限に保つためである。各 transition は loop_iterationloop_decision、可能な場合は loop_timestamp を記録する。

2.6 Suspend

{\n  "type": "Suspend",\n  "reason": "user_approval"\n}

Suspend は semantic delta kind suspend を持つ suspended ResultStep を返す。 Resume は別の実行フェーズであり、前回の replay log を因果記録として扱う。


3. 完全な例

{\n  "type": "Pipeline",\n  "steps": [\n    { "type": "Step", "name": "start" },\n    {\n      "type": "Loop",\n      "maxIterations": 2,\n      "body": [\n        { "type": "CallCapability", "name": "Observe" },\n        { "type": "CallCapability", "name": "Decide" }\n      ]\n    },\n    { "type": "Suspend", "reason": "user_approval" },\n    { "type": "CallCapability", "name": "ExecutePlan" }\n  ]\n}

compile flow:

JSON DSL\n  -> DslDocument.FromJson\n  -> IDslPipelineCompiler.Compile\n  -> IKernelPipeline.Execute\n  -> ResultStep + ReplayLog + ReplayLogHash

4. DSL ROM

AI が生成した DSL は不変 ROM 素材として保存し、capability として再利用できる。

4.1 VFS Path と Capability Name

実装上の VFS path は次の形式である。

rom/dsl/{namespace}/{name}.json

呼び出し可能な capability name は次の形式である。

dsl://{namespace}/{name}

namespacename は、どちらも normalize 済みの単一 path segment でなければならない。 dsl://agent/nested/plan1 のような nested capability name は拒否される。

4.2 Save / Load Flow

SaveDslAsRomAsync(namespace, name, jsonDsl)\n  -> DSL を parse / compile\n  -> SHA-256 ROM hash を計算\n  -> VFS に未存在なら JSON を保存\n  -> 既存 path の内容が異なる場合は拒否\n  -> DslRomSnapshot を IDslRomRegistry に登録

load には expected ROM hash が必要である。VFS の内容が expected hash と異なる場合、 load は fail-closed する。

4.3 DSL ROM の呼び出し

{\n  "type": "CallCapability",\n  "name": "dsl://agent/plan1"\n}

DslRomCapabilityRegistry は ROM snapshot を解決し、metadata を検証し、 compile 済み inner pipeline を実行し、その DslPipelineValue を返す。 ROM 呼び出しは replay metadata にも記録される。


5. Replay and Metadata

DSL 実行は、node execution、loop transition、capability call、suspend point、 DSL ROM call の semantic delta を記録する。

安定 ROM metadata key は次の通り。

Key 意味
dsl_rom_hash JSON DSL 内容の SHA-256 hash。
dsl_rom_call dsl://agent/plan1 などの capability name。
dsl_rom_path rom/dsl/agent/plan1.json などの VFS path。
dsl_rom_namespace ROM namespace。
dsl_rom_name ROM name。
dsl_rom_replay_log_count inner ROM pipeline が生成した replay entry 数。
dsl_rom_replay_log_hash inner ROM pipeline が生成した replay hash。

これらにより、どの DSL ROM が実行され、どの inner pipeline replay が outer execution に畳み込まれたかを証明できる。


6. HistoryROM

チャット履歴は、不変な署名付き ROM 素材として保存できる。 DSL ROM と異なり、HistoryROM は実行可能 capability ではない。 これは履歴素材であり、Core の他の ROM asset と同じ VFS / ROM 署名検証経路で読み込まれる。

6.1 VFS Path と ROM Id

実装上の VFS path は次の形式である。

rom/history/{namespace}/{name}.md

登録される ROM id は次の形式である。

history://{namespace}/{name}

namespacename は、どちらも normalize 済みの単一 path segment でなければならない。 history://agent/nested/demo のような nested ROM id は拒否される。

6.2 Save / Load Flow

SaveHistoryAsRomAsync(namespace, name, records)\n  -> 順序付き chat record を正規化\n  -> 署名付き Markdown ROM を生成\n  -> VFS に未存在なら Markdown を保存\n  -> 既存 path の内容が異なる場合は拒否\n  -> RomLoader で読み込み、署名を検証\n  -> HistoryRomSnapshot を IHistoryRomRegistry に登録

host がすでに署名付き Markdown HistoryROM を持っている場合は SaveMarkdownAsRomAsync を利用できる。LoadHistoryRomAsync は expected ROM hash を任意で受け取り、 VFS 内容が一致しない場合は fail-closed する。

6.3 安定 Metadata Key

Key 意味
history_rom_hash 検証済み SHA-256 ROM hash。
history_rom_id history://agent/demo などの ROM id。
history_rom_path rom/history/agent/demo.md などの VFS path。
history_rom_namespace History ROM namespace。
history_rom_name History ROM name。

7. Failure Rules

次の条件は fail-closed する。

  • 空または非 object の DSL JSON。
  • Pipeline 以外の root node。
  • 未知の node type。
  • 必須 field の欠落または型不一致。
  • 負の maxIterations または負の timeout
  • compile 時の未知 capability name。
  • capability registry の例外。
  • capability が successful null value を返す場合。
  • DSL pipeline value の key / value が不正な場合。
  • DSL ROM hash mismatch。
  • 同じ ROM capability へ異なる内容を再登録する場合。
  • 不正な DSL ROM capability name。
  • HistoryROM signature mismatch。
  • HistoryROM expected hash mismatch。
  • 同じ HistoryROM id へ異なる内容を再登録する場合。
  • 不正な HistoryROM id。

8. Host Integration Notes

Server/API host は AI system が JSON DSL を提案することを許可してよいが、 再利用可能 capability として扱う前に、host 側で検証し DSL ROM として保存しなければならない。 browser/WASM client は trusted ROM を直接書き込まず、server boundary を呼び出すべきである。

チャット履歴 exporter / scraper は、ROM 生成経路の内部で現在時刻を取得せず、 決定論的な timestamp を IHistoryRomStore / HistoryRomStore に渡すべきである。 これにより HistoryROM は再現可能になり、検証済み hash も replay 間で安定する。

外部 module 連携では、assembly 参照 Provider、process-backed adapter、dsl:// ROM capability へ name を route する IDslCapabilityRegistry を登録する。registry が境界であり、 Core は provider 実装を知らない。

v0.0.4 以降、このモデルの公開 contract surface は AIKernel.Abstractions.DslAIKernel.Abstractions.HistoryAIKernel.Abstractions.TimeAIKernel.Dtos.DslAIKernel.Dtos.HistoryAIKernel.Dtos.Time に配置される。Core は内部で Result ベース実装を維持してよいが、 公開 adapter はこれらの contract package を対象にする。


変更履歴

  • v0.0.4 (2026-06-04): 標準 DSL pipeline、DSL ROM、HistoryROM 仕様と公開 contract package mapping を追加。
Source: architecture/18.DSL_PIPELINE_AND_ROM_SPEC-jp.md