mcpField
R
rekor

rekor

github.com/wayai-proデータ・データベース0110 回インストール11 週間前に更新
リポジトリ

rekor について

RekorはAIエージェント向けのデータレイヤーです。`rekor` CLIでデータモデルを設計・管理し、プレビュー環境でスキーマを変更できます。本番エージェントはMCPツールでレコードを読み書きし、外部システムはREST APIで連携します。

主な機能

  1. 01CLIによるデータモデル管理
  2. 02プレビュー環境でのスキーマ設定
  3. 03レコード、リレーション、ファイルの管理
  4. 04外部ソースとトリガーの設定
  5. 05エージェント向けActionとツールセットの定義
  6. 06人の操作によるスキーマの昇格

活用シーン

  1. 01エージェントアプリ用のレコードタイプ設計
  2. 02プレビューでのスキーマ変更の検証
  3. 03本番エージェントによるレコードの読み書き
  4. 04外部システムとレコードデータフローの接続

MCP 対応

設定したActionをMCPサーバーのツールセットにまとめ、MCPクライアントに提供できます。本番エージェントはMCPツールでレコードを読み書きし、CLIはデータモデルの設定と管理に使います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wayai-pro/rekor-skill --skill rekor

インストール後、Claude Code で/rekorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
executors.md
external-sources.md
mcp-factory.md
providers.md
querying.md

詳細

Rekor — AI エージェント向けデータレイヤー

rekor CLI(Rekor のビルダーインターフェース)を利用できます。これを使用してスキーマを設定し、record_types を構成し、プレビュー環境でテストして、本番環境へ昇格させます。本番環境のエージェントは MCP ツールを使用してレコードを読み書きし、外部システムは REST API 経由で連携します。CLI はデータモデルの設計と管理に使用するツールです。

このファイルには概念がすべて含まれています。Rekor オブジェクトモデルではすべてのプリミティブを定義し、タスク → 機能マップでは各リクエストに対応するセクションを案内し、詳細情報の参照先では完全なオプション構文を確認するために、同梱の references/ ファイルを開くタイミングを説明します。

エージェントのガイドライン

  • シェルを使用できる場合は、rekor CLI で Rekor を操作してください。ツールセットに mcp__rekor__* ツールもある場合は、セットアップと構成には CLI を優先し、MCP ツールは本番環境での読み書き操作に使用してください。
  • このスキル、ツールの説明、またはリファレンスドキュメントに記載されている情報のみを提供してください。URL、パス、コマンド、フラグを創作しないでください。
  • 機能を構成する前に、対応する references/*.md ファイルを読んでください。このファイルには意図的に概念と一般的なコマンド形式のみを記載しています。クエリと検索の調整、外部ソース、MCP Factory のアクションとツールセット、エグゼキューター、プロバイダーアダプターの完全なオプション構文は、同梱のリファレンスファイル(詳細情報の参照先に一覧があります)に記載されています。
  • スキーマ関連の作業(record_types、受信 Webhook、トリガー、MCP Factory ツールセット)は、プレビューベースでのみ行います。スキーマを変更する前に、必ずプレビューを作成するか、既存のプレビューを使用してください。
  • 識別子は永続的です。 base、record_type、relationship type、Action、MCP Factory ツールセットの id はそれぞれの識別子であり、変更できません。作成時に一度だけ選択し、以後変更することはできません。表示名と説明は編集できますが、id は変更できません(relationship type には別の名前がなく、その id がラベルも兼ねます)。名前を変更する機能はありません。これらの名前を「変更」するには、新しいエンティティを作成してデータを移行する必要があります(古いエンティティはそのまま残ります)。そのため、最初に明確で安定した小文字のスラッグ形式の id を選んでください(例:patients、treated_by)。
  • 昇格は人間のみが行えます。 スキーマの準備ができたら、正確な rekor bases promote コマンドを提示し、ユーザーが実行するまで待ってください。
  • トークンが表示されるのは作成時の一度だけです。それ以外の操作を行う前に、コピーして保管するよう必ずユーザーに伝えてください。
  • 自動でコミットしないでください。スキーマファイルを扱っている場合は、ユーザーに git diff を提示し、承認を待ってください。

Rekor オブジェクトモデル

一度読めば、概念の全体像を把握できます。セットアップ作業はすべて、以下の要素を組み合わせて行います。コマンドとルールについては下記のコマンドリファレンス全文を、詳細な構文については同梱の references/ ファイルを参照してください。

Organization                      ← account boundary; API tokens, vault secrets
└── Base (production | preview)   ← top-level data container: one per app, domain, or tenant
    ├── CONFIG — edit in PREVIEW, ship with PROMOTE (human-run):
    │     record types (+ their external sources) · relationship types · file types
    │     · triggers · inbound webhooks · Actions · toolsets · seed fixture definitions
    └── DATA — read/write on ANY base, production included:
          records · relationships · files · attachments · batch writes
          (seed apply/reset/clear and seed lease acquire/release run only on previews)

すべてのコマンドに適用される唯一のルール: 本番環境の base では設定の書き込みが拒否されます。プレビュー(rekor bases create-preview)で設定し、その後、ユーザーに rekor bases promote を実行してもらってください。通常のデータ書き込みはどこでも実行できますが、シード用フィクスチャとシード用リースデータの操作はプレビューでのみ実行できます。書き込み時にプレビューまたは 403 エラーが予期せず発生した場合は、本番環境で設定または評価状態に関する操作を行っていないか確認してください。

各プリミティブを一行で

モデルの基盤となるスキーマとインスタンスの組み合わせは、record type → record と relationship type → relationship の2つです。ファイルも同じパターンです(file type → file)。

プリミティブ概要コマンド/セクション
Organizationベース、トークン、シークレットを所有するアカウント境界です。rec_ キーは厳密に1つの組織にスコープされ、別の組織に変更することはできません(--org/REKOR_ORG は機能しません)—
Base最上位のデータコンテナーです。production(設定エンティティは promote 経由でのみ変更でき、名前/タグ/タイムゾーンなどのメタデータは引き続き編集可能)または preview(<prod>--<slug>。設定を編集できるクローンで、元のベースにプロモートします)rekor bases
Record typeレコードタイプを定義する JSON Schema です。実行時に作成され、マイグレーションはありません。スキーマヒント(外部キーの x-fk、検索調整の x-search、アーカイブモードの x-archival、x-timezone、表示用の x-ui)を持ち、任意で外部ソースを宣言できますrekor record-types
Recordレコードタイプに準拠する JSON 行です。システム生成の id に加え、冪等なアップサートのための独自の external_id/external_source を使用します(再アップサートすると既存のレコードが更新されます)。キャンセル(第一級の状態)またはアーカイブ(終端状態/非アクティブ化)が可能ですrekor records
Relationship typerel_type を定義する設定です(その ID 自体がタイプです)。任意でメタデータスキーマと、ソース/ターゲットのレコードタイプ許可リストを指定できます。このタイプのリレーションシップを作成する前に定義しておく必要がありますrekor relationship-types
Relationship2つのレコード間の型付きの有向リンクです(エンドポイントはファイルの場合もあります)。メタデータは検証され、両方向にたどることができますrekor relationships、rekor query-relationships
Filter DSL条件を記述する唯一の言語です。records query、トリガーの --filter、Action の precondition で使用される {field, op, value} と and/or のグループで構成されますRecords → Filtering & search
File typeファイル用のバケット設定です。最大サイズ、許可されるコンテンツタイプ、任意のメタデータスキーマを指定しますrekor file-types
Fileバージョン管理され、パスで指定するコンテンツ(PDF、画像、ドキュメント)です。比較してから設定する書き込み、バージョンごとの履歴と差分に対応し、S3 にマウントできますrekor files
Attachmentレコード単位のシンプルなアップロードです。Files は、より高機能なバージョン管理対応の進化形ですrekor attachments
External sourceレコードタイプ上で宣言します。1つの双方向 field_mapping 契約を通じて、CRUD 操作のバックエンドとして外部 API を使用しますExternal Sources
Triggerレコード/リレーションシップ/ファイルのイベントで実行されます。アクションは、署名付きwebhookの送信、internal_write(関連レコードへのガード付きパッチ)、またはexternal_write(ソース経由で変更を上流にプッシュ)ですrekor triggers
Inbound webhook外部システムがデータを送信する署名付き取り込み URL です。ペイロードはそのまま保存するか、マッピングを通じて変換するか、またはハイドレートできます(「ID が変更された」という簡易通知を受け取ると、Rekor がバインドされたソースを通じてレコード全体を取得します)rekor inbound-webhooks
ExecutorRekor が直接呼び出せない処理(カスタムロジック、mTLS、SOAP、バイナリー認証情報)のためにユーザーがデプロイする小規模な HTTP サービスです。署名付きディスパッチを受け取り、@wayai/executor-sdk で検証しますExecutors
Signing v1トリガー配信、Executor にバインドされたソース呼び出し(オプトインの signing)、Inbound webhook の検証(デフォルトの方式)で使う HMAC リクエスト署名です。双方向で1つのワイヤーフォーマットを使用します。@wayai/executor-sdk が実装しているため、独自実装しないでくださいExecutors, Inbound Webhooks
Action1つのレコードタイプと1つのオペレーションを指定し、形状とガードを設定します(filterable_fields、writable_fields、precondition、binding)。または、複数レコードにまたがるアトミックステップをまとめた複合型にできます。その ID がエージェント向けのツール名になりますrekor actions
ToolsetAction への参照(およびリレーションシップ/バッチ/SQL ツール)で構成する、厳選された MCP サーバーです。mcp.rekor.pro/t/<slug>/mcp で提供されますrekor toolsets
Seed fixture / lease分離されたエージェント評価のための、名前付きで元に戻せるレコードとリレーションシップのベースラインです。定義は設定であり、apply/reset/clear は preview 専用のデータ操作です。アクターにバインドされたリースは、1回の評価実行に対してフィクスチャの状態を排他的にリセット、所有、クリアしますrekor seed、rekor seed lease
API tokenrec_… 認証情報です。権限スコープ型(ベース × レコードタイプ × 環境 × 権限)またはツールセットバインド型(認可対象がそのツールセットのツールサーフェスそのもの)がありますrekor tokens
Secret組織レベルの暗号化された認証情報(文字列またはファイルの BLOB)です。ソース/トリガーの設定から vault:<name> として参照でき、ディスパッチ時に Executor が取得できますrekor secrets
ID ルール。 設定スラッグは恒久的な ID です(エージェントのガイドラインを参照)。自然キーを持つレコードには必ず external_id を設定してください。再試行や再インポート時に、重複を作成せずにアップサートされます。すべてのレコード書き込みは、レコードタイプのスキーマ(および x-fk の参照チェックと日時の正規化)に照らして検証されます。

統合エッジ。 ソース上の field_mapping コントラクトは、すべてのエッジで再利用されます。プロキシ経由の読み取り/書き込み、external_write による外部への書き出し、インバウンド Webhook によるマッピング/ハイドレーションが対象です。まずエンティティを正規の形でモデル化し、その後、操作ごとにエッジを選んでください。統合モデリングのセクションが、判断ガイドおよびパターンカタログです。

一貫性と制限。 単一レコードの get と、対象となるアクティブレコードの records query/query-relationships のリストには、書き込みが即座に反映されます。sql、search、および最近同期されたデータを読み取る一部のクエリ形式(組み込みの created_at/updated_at タイムスタンプをタイムゾーンオフセットなしでフィルタリングするクエリなど)では、書き込みの反映に少し時間がかかることがあります。また、local ティアのベース(評価用クローンのデフォルトです。ベースを参照)では、反映が遅れるのではなく、同じクエリ形式が拒否されます。レコード/リレーションシップの JSON は約 1 MiB が上限です。大きなコンテンツやバイナリコンテンツは Files に保存してください。

タスク → 機能マップ

リクエストに適した機能を選び、コマンドリファレンスの該当セクションに移動してください。

必要なこと使用するものセクション
構造化された業務データを保存・検証するレコードタイプのスキーマ+レコードRecordTypes、Records
レコードを再送せずに1つのフィールドを変更する部分更新(REST PATCH/MCP patch)Records
再試行や再インポート時の重複を防ぐ--external-id によるアップサートRecords
エンティティをリンクし、グラフをたどるリレーションシップタイプ+リレーションシップRelationship Types、Relationships
参照先が実在するレコードに解決されるようにするスキーマフィールドの x-fkRecords → 参照整合性
おおよその名前/テキストで検索するFilter DSL の search 演算子Records → フィルタリングと検索
レポート、集計、結合rekor sqlSQL Query
PDF/画像/バージョン管理されたドキュメントを保存するファイルタイプ+ファイル。S3 経由でマウントFiles
複数の書き込みをすべて成功するか、すべて失敗するようにするrekor batchBatch
過去のデータを一括で読み込む(バックフィル)rekor import run(NDJSON。ストリーミング、再開可能)Bulk Import
データ変更を外部システムに通知するトリガー → webhookTriggers
「A が変更されたら、関連する B を更新する」トリガー → internal_write(非同期またはトランザクション)Triggers
ネイティブレコードを上流 API にミラーリングするトリガー → ソースを再利用する external_writeTriggers、External Sources
外部からのペイロード全体を受け付けるインバウンド webhook(必要に応じてフィールドマッピング)Inbound Webhooks
「レコード X が変更された」という通知を完全なレコードに変換するデータを補完するインバウンド webhook(自分のフィールドを保持するには merge を使用)Inbound Webhooks
外部 API をネイティブ機能のように読み書きするレコードタイプ上の外部ソースExternal Sources
Rekor が直接呼び出せないものを統合するexecutor+@wayai/executor-sdkExecutors
LLM エージェントに、安全でドメイン名に沿ったツールを提供するActions+toolset+toolset にバインドされたトークンMCP Factory
状態に依存する書き込みを競合なく行うAction の precondition(比較して設定)MCP Factory
1つのエージェントツールで複数の書き込みをアトミックに行う複合 ActionMCP Factory
最小権限でマシン/CI からアクセスするスコープ付きトークン(エージェントには create-for-toolset)API Tokens
統合の認証情報を保存するシークレット保管庫(vault:<name> 参照)Secrets
git で設定を管理し、PR でレビューするrekor pull/rekor pushConfig as Code
本番環境の上流に依存しない決定論的なエージェント評価を行う--integrations disabled を指定したプレビュー(破棄可能なデータには --analytics local を併用)+シードフィクスチャBases、Seed Fixtures
プロバイダーのツール定義をインポート/エクスポートするプロバイダーアダプターProvider Adapters
誰が、何を、いつ変更したかを確認するhistory サブコマンド(管理者権限が必要)Records
ネイティブ、プロキシ、ミラーのどれを基盤にするか決めるパターンカタログIntegration Modeling
エージェントがうまく動作するようにスキーマ/ツールを整える原則+レシピModeling Principles
エージェント向けのツールインターフェースを設計するツール設計の原則(意図ベースのツール、必須パラメーター、閉じた選択肢)Modeling Principles

詳細情報の参照先

同梱の references/ ファイルには、オプションの文法がすべて記載されています。その機能を設定する前に、該当するファイルをお読みください。

リファレンスファイル読むタイミング内容
references/querying.md複雑な SQL を記述するとき、search を調整するとき、タイムゾーンを設定するときSQL の例集(配列、ARRAY JOIN、CTE、--param、あいまい検索のランキング)、x-search のモードとしきい値、日時とタイムゾーンの設定
references/external-sources.md外部ソースを設定するときソースの文法全体:field_mapping のルール(値のマッピング、変換、分割/構造化/計算、操作ごとの上書き)、操作ごとのエンドポイント、名前付き書き込みバインディング、id_path のバリエーション、forward_filters、local_filters、ボディの整形、{{current.*}}/{{prior.*}}、キャッシュ/署名/タイムアウト/ブレーカー、SSRF のルール、レガシーアップストリームを使った実例
references/mcp-factory.mdデフォルト以外の Action やツールセットを作成するときAction とツールセットの文法全体:filterable_fields(optional を含む)、expose_*/default_*、writable_fields、base_filter、precondition、binding、複合 Action、ツールの命名、ツールセットのスラッグに対応するベース
references/executors.mdExecutor を構築またはデプロイするとき@wayai/executor-sdk の契約(検証、重複排除、エラーエンベロープ)、署名付き書き戻し、ホスティング先、Vault 証明書取得のパターン、ローカル開発、再試行
references/providers.mdプロバイダーのツール定義をインポート/エクスポートするときプロバイダーごとの正確な rekor providers コマンド形式(OpenAI/Anthropic/Google/MCP)

実行時には、以下も参照できます。

  • rekor <command> --help(および rekor <command> <subcommand> --help) — 各コマンドの正式なフラグ一覧です。
  • rekor status — 認証、接続状況、アクティブな組織、worktree のバインディングを確認します。rekor whoami — 認証済みの ID を確認します。

コマンド、フラグ、URL がこれらの情報源のいずれにも記載されていない場合は、存在しないものとして扱い、決して推測しないでください。


初回セットアップの手順

ユーザーがゼロから始める場合は、以下の手順を案内してください。すでに完了している手順は省略してください。判断する前に rekor bases list で確認します。

1. CLI をインストールする
npm install -g rekor-cli

rekor --version で確認します。CLI は npm で rekor-cli として公開されており、バイナリ名は rekor です。

2. 認証する

API キーで認証します。

rekor login --token rec_xxx

この API が受け付ける認証情報は API キーのみです。 ブラウザーサインイン(--token を指定しない rekor login)は廃止されました。バックエンドはブラウザー認証情報も OAuth 認証情報も検証しなくなったため、この方法で取得したセッションは以降のすべてのコマンドで拒否されます。アカウントの管理者にキーを依頼してください。キーは組織を所有するプラットフォームが発行し、それぞれのキーはすでに一つの組織だけを対象としています。

rekor init も同時に廃止されました。このコマンドは、リポジトリをユーザー自身の組織の一つに紐付けるためのものであり、組織一覧を取得するにはユーザーログインが必要でした。rec_ キーには組織情報がすでに含まれているため、選択する必要はありません。

キーが組織を決定し、それを上書きするものはありません。 既存のコミット済み .rekor.yaml、--org フラグ、REKOR_ORG は、サーバーが読み取らなくなった同じリクエストヘッダーに値を設定するだけなので、何も変わりません。キーが発行された組織とは異なる組織に対して --org を指定しても、キー自身の組織が操作対象となり、エラーは報告されません。別の組織で作業するには、その組織で発行されたキー(REKOR_TOKEN、または rekor login --token)を使用してください。

ユーザーがまだ組織を持っていない場合は、アカウントを管理するプラットフォームから組織を取得します。セルフサービスでの登録は廃止されています。無料プランには、月あたり 5,000 件の操作が含まれます。

3. ベースを作成する

ベースは最上位のデータコンテナーです。アプリ、ドメイン、またはテナントごとに1つ作成します。

rekor bases create <id> --name "<Display Name>" [--tags <comma-separated>]

コマンドごとに --base を指定しなくて済むよう、ユーザーのシェルで REKOR_BASE=<id> を設定します。

本番ベースには有料プランが必要です。 無料プランではこのコマンドはアップグレードを促すメッセージとともに失敗します。代わりにプレビューベースを作成し、そこで作業をすべて行ってください。

rekor bases create <id> --name "<Display Name>" --environment preview

それ以外(record_types、records、relationships、triggers、toolsets)は同じように動作し、完全な開発環境として使えます。

この方法で作成したプレビューには本番環境のオリジンがなく、後からオリジンを関連付けることもできません(API は試行を黙って無視せず、拒否します)。そのため、直接昇格することはできません。アップグレード後、本番環境を別途用意して、設定をコピーしてください。

rekor pull <preview-id>                              # config → rekor-ws/bases/<preview-id>/
rekor unbind                                         # release this checkout's binding to it
rekor bases create <prod-id> --name "<Display Name>" # allowed once on a paid plan
rekor bases create-preview <prod-id> --name dev      # a preview linked to production
rekor pull <prod-id>--dev                            # scaffolds rekor-ws/bases/<prod-id>--dev/
# copy ALL seven entity folders — record-types/, relationship-types/, inbound-webhooks/,
# triggers/, toolsets/, actions/, seeds/ — from rekor-ws/bases/<preview-id>/
# into rekor-ws/bases/<prod-id>--dev/ (push is additive, so anything you skip is
# silently absent rather than reported as a removal)
rekor push <prod-id>--dev
rekor bases promote <prod-id> --from <prod-id>--dev

コピーを ID の編集ではなくファイルコピーとして行うための重要な点が2つあります。push <selector> は <selector> という名前のフォルダーを探すため、base.yaml を編集しただけでは転送先は変わりません。また、pull/push は操作したベースにチェックアウトを紐付けるため、切り替える前に rekor unbind を実行してください。レコードとリレーションシップは設定ではなくデータであり、元のプレビューに残り、pull/push では移動しません。

rekor bases promote にも有料プランが必要です。本番ベースの読み取りと書き込みが停止することはありません。停止するのは新しい設定のデプロイだけです。また、--dry-run と rekor bases rollback はいずれの場合も引き続き利用できます。

4. プレビュー環境を作成する

スキーマの変更(record_types、インバウンドウェブフック、triggers、MCP Factory toolsets)は、本番ベースではブロックされます。スキーマを作業するには、プレビューを作成してください。

rekor bases create-preview <id> --name "<preview-slug>"

作成されたプレビューベースの ID は <id>--<preview-slug> です。すべてのスキーマコマンドで、これを --base として使用します。

オリジンには本番ベースまたは別のプレビューを指定できます。プレビューをクローンすると、<preview-id>--<preview-slug> が作成され、クローン元のプレビューにリンクされます。

別のプレビューからクローンしたプレビューは、local 分析ティアで作成されます。このティアでは、レコードに対する rekor sql、history、リレーションシップのたどり直しが拒否されます。詳しくは「Bases」の分析ティアを参照してください。rekor sql でクエリする予定のスキーマ作業(手順6)用にプレビューオリジンをクローンする場合は、--analytics standard を渡してください。ティアは後から変更できません。本番オリジンのクローンには影響ありません。

手順3(無料プラン)で <id> をプレビューとして作成した場合でも、この手順は実行できますが、得られるメリットはほとんどありません。プレビューからクローンしたプレビューは、オリジンを経由して昇格し、本番環境に直接昇格することはできません。さらに、直前に説明した local ティアで作成され、手順6の promote にも有料プランが必要です。最も簡単なのは、この手順をスキップして <id> で直接作業することです。--base <id>--<preview-slug> と書かれている箇所で --base <id> を渡せば、手順5と6は変わらず、手順6のテストコマンドにも適用できます。手順6では、本番ベースが昇格先に存在しないため、promote をスキップしてください。

5. 最初の record_type を定義する

record_type は、レコードの種類を定義する JSON Schema です。プレビューベースに定義してください。

rekor record-types upsert <slug> --base <id>--<preview-slug> \
  --name "<Display Name>" \
  --schema '{"type":"object","properties":{...},"required":[...]}'

1行を超えるスキーマはファイルに書き込み、--schema @path/to/schema.json を渡してください。

6. プレビューでテストし、昇格をユーザーに依頼する

テストレコードをプレビューに書き込み、クエリを実行します。スキーマが適切になるまで反復してください。

rekor records upsert <slug> --base <id>--<preview-slug> --data '{...}'
rekor sql "SELECT * FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = '<slug>' AND deleted = false" --base <id>--<preview-slug>

準備ができたら、ユーザーが実行する昇格コマンドを提示してください(自分で昇格することはできません)。

rekor bases promote <id> --from <id>--<preview-slug>

まず --dry-run を実行して、差分を確認することをおすすめします。

7. 本番エージェントを接続する

本番エージェントにアクセス権を付与する方法は2つあります。

スコープ付き API トークン — REST/CLI から直接アクセスする場合:

rekor tokens create --name "<agent-name>" \
  --grants '[{"scope":{"bases":["<id>"],"environments":["production"]},"permissions":["read:records","write:records"]}]'

生のトークン(rec_...)は一度だけ表示されます。すぐにコピーしてください。

MCP Factory ツールセット — エージェントごとに専用の MCP ツールを用意する場合(LLM エージェントに推奨):

下記の MCP Factory セクションを参照してください。

最初のレコードタイプを超える機能(リレーションシップ、ファイル、トリガー、インテグレーション、ツールセット、評価)については、上記のタスク → 機能マップで適切な機能を確認してください。設定対象が複数のエンティティにまたがるようになったら、単発コマンドではなく Config as Code(rekor pull/push)を使用してください。変更をレビュー可能なファイルとして管理できます。


クイックスタート

スキーマとインスタンスの基本的な組み合わせを実際に使ってみましょう。--base my-ws はプレースホルダーです。以下の設定書き込み(record-types upsert、relationship-types upsert)では、プレビューベースを指定する必要があります。

1. record_type を作成する
rekor record-types upsert invoices --base my-ws \
  --name "Invoices" \
  --schema '{"type":"object","properties":{"customer":{"type":"string"},"amount":{"type":"number"},"status":{"type":"string","enum":["draft","issued","paid"]}},"required":["customer","amount"]}'
2. レコードを作成する
rekor records upsert invoices --base my-ws \
  --data '{"customer":"Acme Corp","amount":5000,"status":"draft"}'

冪等な upsert を行うには、外部 ID を指定します。

rekor records upsert invoices --base my-ws \
  --data '{"customer":"Acme Corp","amount":5000}' \
  --external-id inv_123 --external-source billing
3. レコードをクエリする
rekor sql "SELECT data.invoice_number.:String as num, data.status.:String as status, arraySum(CAST(data.line_items[].amount, 'Array(Float64)')) as total FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'invoices' AND deleted = false ORDER BY total DESC" --base my-ws
4. リレーションシップタイプを宣言し、レコードをリンクする

リンクする前に、リレーションシップタイプが存在している必要があります。設定として一度宣言します(設定の書き込みなので、プレビュー環境で行ってから昇格してください)。

rekor relationship-types upsert belongs_to --base my-ws \
  --description "Invoice belongs to a customer" \
  --source-record_types '["invoices"]' --target-record_types '["customers"]'

次にリンクします。

rekor relationships upsert --base my-ws \
  --source invoices/rec_abc --target customers/rec_xyz \
  --type belongs_to

任意のメタデータを許可するには --schema を省略します。リレーションシップの --data を JSON Schema に照らして検証するには、--schema を指定します。

各エンドポイントは、内部レコード ID の代わりに external_id でも指定できます。external_id を使ってレコードを upsert した直後で、返された ID を保持していない場合に便利です。

rekor relationships upsert --base my-ws \
  --source-external invoices/inv-2026-001 --target-external customers/cust-42 \
  --type belongs_to

各エンドポイントで指定できるのは --source/--source-external のいずれか1つです(ターゲットも同様です)。external_id がソースシステムにスコープされている場合は、--source-external-source <name> を追加してください。レコードが存在しない場合の動作は、2つの指定方法で異なります。内部 ID は指定された値のまま保存されるため、レコードの作成前にリンクしてもかまいません。一方、外部 ID による指定ではレコードの存在が必須です。存在しない場合、書き込みは明確なエラーとともに失敗します。API でも同様に、source_id/target_id の代わりに source_external_id/target_external_id(および任意の *_external_source)を使用します。

5. リレーションシップをたどる
rekor query-relationships invoices rec_abc --base my-ws \
  --type belongs_to --direction outgoing

コマンドの完全リファレンス

破壊的な delete コマンドは、対話型ターミナルでは確認を求めます。確認を省略するには -y/--yes を指定してください(非対話型または CI 環境では、自動的に確認が省略されます)。

ベース
rekor bases list [--tag <tag>]
rekor bases get <id>
rekor bases create <id> --name <name> [--description <desc>] [--tags <comma-separated>] [--environment <production|preview>] [--analytics <standard|local>]   # production requires a paid plan
rekor bases rename <id> --name <new-name>   # display name only — the id/slug is immutable
rekor bases tag <id> --tags <comma-separated>
rekor bases delete <id> [--purge]            # --purge is preview-only: also reclaims storage
rekor bases create-preview <origin-id> --name <preview-slug> [--description <desc>] [--integrations <enabled|disabled>] [--analytics <standard|local>] [--create-only]
rekor bases update <preview-id> --integrations <enabled|disabled>   # preview-only eval toggle
rekor bases list-previews <origin-id>
rekor bases promote <prod-id> --from <preview-id> [--dry-run] [--record_types <ids>] [--triggers <ids>] [--inbound-webhooks <ids>]
rekor bases promotions <prod-id>
rekor bases rollback <prod-id> --promotion <promotion-id>

タグを使うと、ベースをグループ化できます(例:client:acme,billing)。--tag で絞り込めます。昇格を実行できるのは人間のみです(「環境」を参照)。--record_types/--triggers/--inbound-webhooks で昇格対象を選択できます(省略するとすべてが昇格します)。promotions には過去の昇格が一覧表示されます。rollback は ID を指定して昇格を元に戻します。

create-preview は本番ベースまたは別のプレビューベースを複製します。新しい ID は <origin-id>--<preview-slug> となり、複製元に紐付けられます。そのため、プレビューのプレビューは本番へ直接ではなく、その複製元を経由して昇格します。再実行すると、既存のプレビューに設定が再適用され、データはそのまま残ります。代わりに --create-only を指定すると、既存のプレビューがある場合は失敗します。実行ごとに使い捨てのベースを作成する場合に適しています。他の実行のベースを使ってしまうと、両方の実行が破損するためです。

削除とパージの違い。 rekor bases delete <id> は論理削除です。ベースは一覧に表示されなくなりますが、そのレコード、リレーションシップ、ファイルのメタデータ、設定は保持され、同じ ID を再作成すると復元されます。--purge(プレビューベースのみ)は、これらを完全に削除します。パージした ID は使用済みとなり、再作成できないため、次回の実行では新しい ID を生成してください。使い捨てのベースを破棄するには purge を使用します。通常の delete では、すべてが永久に残ります。

パージしても削除されないものが2つあります。アップロード済みファイルの内容(削除されるのはインデックス用のメタデータのみ)と、分析ストア内のベースの行です。ID が使用済みになると、どちらにもアクセスできなくなりますが、いずれもストレージを占有し続けます。 Eval モード(--integrations disabled)。 プレビューは、外部連携を無効化(デフォルトは enabled)して実行できます。無効にすると、すべての外部接続が停止します。具体的には、record_type のデータソース、外部への external_write トリガー、受信 Webhook のデータ取り込みが対象です。プレビューは、外部システムを呼び出すことなく、独自にシードされたデータをまったく同じスキーマ、ツール、フィールドマッピングで提供します。これにより、本番環境専用の上流システムを汚染したり、稼働中のレート制限や PII に触れたりせず、同じ標準サーフェスに対するエージェントのポリシーを検証できるため、プレビューは決定論的で本番環境にも安全なエージェント評価の対象になります。無効の状態でレコードを書き込んでシードしてください(ソースに紐づく record_type への書き込みはローカルに保存されます)。実際の連携をテストするときは enabled に切り替え、本番環境から再クローンしてドリフトのない状態を保ちます。本番環境のベースは常に enabled です。切り替えはプレビュー専用です。

分析ティア(--analytics)。 プレビューのデータを分析ストアに一切保存しないようにできます。local の場合、レコードとリレーションシップはベース自体に保存され、ミラーリングされません。実行が終わるとデータが不要になる使い捨ての評価用ベースに適しています。

別のプレビューからクローンしたプレビューは、デフォルトで local に作成されます。この構成がセッションごとの評価用クローンです。本番環境のベースからクローンしたプレビューと、rekor bases create から作成するすべてのベースは、デフォルトで standard になります。どちらの方法でも --analytics を指定すれば明示的に選択でき、デフォルトより優先されます。

次の 2 つの影響があります。1 つ目は、読み取り制限ではなくデータ損失です。

  • 変更履歴は一切記録されません。 履歴は移動されるのではなく破棄されます。このようなベースへの書き込みについて、監査行はどこにも書き込まれません。history サブコマンドと監査エンドポイントは空のリストではなくエラーを返しますが、そのエラーの背後に復元可能なデータはありません。履歴が必要になる可能性のあるベースには、決して local を選ばないでください。
  • 分析ストアから取得するはずの読み取りは、空の結果を返さず拒否されます。 レコードテーブルへの生 SQL クエリと、リレーションシップのたどり込みが対象です。単一レコードの読み取りと通常のフィルター DSL によるリスト取得はベース自体から提供され、通常どおり動作します。ただし、ベースだけでは応答できないクエリは、同じく拒否されます。これには、search 演算子、archived を参照するフィルター、タイムゾーンオフセットのない日時リテラルと created_at/updated_at を比較するクエリ、インベース上限(10,000)を超える有効な行を含むスコープのリストが含まれます。この上限は、レコードでは record_type ごと、リレーションシップではベース全体に適用され、ページング前のスコープ全体を基準に測定されます。--limit を小さくしても上限は変わらないため、シードするフィクスチャは上限未満のサイズにしてください。

評価のアサーションは data.* フィールドへの完全一致フィルターを中心に設計し、created_at/updated_at の範囲指定には明示的なオフセットを指定してください(2026-08-01T00:00:00Z)。

一覧で見る、local ベースが提供しないものと、その代わりに使うもの:

local 階層では提供されない機能代わりに
records、relationships、audit_log に対する rekor sql(およびツールセットの sql_query ツール)Filter DSL を使った records query を使用します。それ以外のテーブル(record_types、relationship_types、bases、organization、operations_log)には引き続き応答がありますが、この階層の operations_log には請求関連の行のみが含まれます
すべてのエンティティの history と監査エンドポイント代替手段はありません。この階層では履歴が記録されないため、フォールバックもありません
リレーションシップのたどり(rekor query-relationships、ツールセットのリレーションシップ一覧ツール)エンドポイント ID を使ってクエリするリレーションシップ一覧のサーフェス(GET /v1/{base}/relationships?filter=…)
search を使う、または archived を参照するフィルター条件data.* に対する完全一致/like 条件を使用します。この階層では、アーカイブ済みの行は別階層として扱われません
組み込みの created_at/updated_at を、タイムゾーンオフセットなしの値と比較する条件バインド値にオフセットまたは Z を指定します。独自の data.* datetime フィールドには影響しません
スコープが有効な行数 10,000 件を超えるリストフィクスチャを上限未満に抑えるか、standard ベースを使用します

階層はベースの作成時に固定され、プレビュー専用です。どちらの方向にも切り替えられません。変更時にストアを調整する処理はないため、誤った階層で作成されたベースは置き換えるしかありません(--purge に加えて新しい ID が必要です。パージ済みの ID は再利用できないためです)。作成時に慎重に設定してください:

rekor bases create-preview <origin> --name eval-run-42 --integrations disabled --analytics local --create-only

履歴や SQL を後で必要とするものには、代わりに --analytics standard を渡してください。プレビュー元のクローンも対象です。プレビュー元はデフォルトで local になります。MCP の manage_base create_preview でも同じ analytics パラメーターを受け取ります。create-preview(およびプレビューの origin_base_id から自動作成する場合の rekor push)は、sql_query またはリレーションシップ一覧ツールを公開するツールセットを持つ新しいベースが local に作成された場合に警告を表示します。これらのツールはそこで永久に拒否されます。

Config as Code(pull/push)

ベースの設定全体(record_types、リレーションシップタイプ、インバウンド Webhook、トリガー、MCP ツールセット、シードフィクスチャ)を、単発のコマンドではなく、バージョン管理された YAML ファイルとして管理できます。ファイルは rekor-ws/bases/<db>/ の下にエンティティごとに 1 つ配置されるため、変更をプルリクエストで明確にレビューできます。

rekor pull <preview>                 # write the preview's config + a read-only mirror of linked production
rekor push <preview> [--dry-run]     # apply your local files to the preview (--dry-run shows the diff only)
rekor push <preview> --prune         # also delete entities that exist on the server but not in your files
rekor use <preview>                  # bind THIS git worktree to a base (push/pull refuse a different one)
rekor unbind                         # clear this worktree's base binding
  • 編集対象はプレビューのみです。 push が書き込むのはプレビューベースのみです(本番環境の設定を直接編集することはありません)。プレビューを pull すると、リンク先の本番環境の設定も読み取り専用の参照フォルダー(rekor-ws/bases/<prod>/)に並べて書き込まれるため、反復作業中に本番環境で稼働中の設定を確認できます。このフォルダーは読み取り専用として扱われ(push は拒否し、引数なしの pull/push の自動選択対象から除外されます)、pull <production> を直接実行した場合に書き込まれるのも、この読み取り専用の参照のみです。本番環境に反映するには、通常どおり rekor bases promote を実行してください。
  • プレビューを自動作成できます。 origin_base_id: <prod-id>(base_id は指定しない)を含む rekor-ws/bases/<name>/base.yaml を作成します。rekor push はその本番環境ベースからプレビューを作成し、新しい ID を書き戻して、ファイルを適用します。
  • base.yaml はベースの説明用であり、再設定するものではありません。 base_id/origin_base_id に加え、pull はベースの environment、integrations、analytics を記録し、フォルダーがどのベースを対象にしているかを示します。すでに base_id があるフォルダーでは、これらは説明用にすぎません。編集しても何も変わらず、作成時のみ設定できる analytics のティアもこの方法では変更できません。予想外の値があれば、ファイルを編集するのではなく、ベースを再確認してください。唯一の例外は、自動作成ブランチでの analytics です。 origin_base_id があり base_id がない新しいフォルダーでは、宣言したティアが push で作成されるベースに渡され、そこで設定できる唯一の機会になります。元のベースがプレビュー(クローンのデフォルトは local)で、SQL、履歴、トラバーサルを使う場合は、最初の push の前に analytics: standard を指定してください。
  • ワークツリーのバインド(ルーティングガード)。 各 Git チェックアウト(メインまたはリンクされたワークツリー)は、1 つのベースにバインドできます。いったんバインドされると、pull/push は別のベースに対する実行を拒否します。これにより、プロンプトが誤ったターミナル/ワークツリーに届き、別のプレビューの設定を上書きしてしまうよくあるミスを防ぎます。バインドは、未バインドのチェックアウトで最初の pull/push が成功したとき(および新しいプレビューの作成時)に自動で設定され、ワークツリーごとに管理され、コミットされることはありません。現在のバインドは rekor status で確認できます。pull/push がバインドの不一致でエラーになった場合は、ほかの操作をする前に停止してユーザーに確認してください。 通常は、そのプロンプトが別のワークツリー向けであることを意味します。現在のセッションでユーザーから明示的な指示がない限り、rekor unbind/rekor use を実行しないでください。バインドの変更は、ユーザーが作業対象と考えているベースを切り替えることと同様のルーティング上の判断です。
  • シークレットがファイルに書き込まれることはありません。 インバウンド Webhook/トリガーおよび外部ソースのシークレットは、pull 時に除去されます。push 時に新しく追加されたインバウンド Webhook/トリガーには新しいシークレットが生成され(1 度だけ表示されます。保存してください)、既存のシークレットは変更されません。シークレットの値は rekor inbound-webhooks/rekor triggers/rekor secrets で管理してください。
  • 削除はオプトインです。 record_type を削除すると、そのレコードも削除されるため、push はデフォルトでは追加のみを行います。ファイルにないエンティティは報告されますが、保持されます。削除するには --prune を追加してください。
  • ベースのコンテキストを AGENTS.md に記録してください。 pull/push の実行時に、Rekor は各ベースフォルダー(rekor-ws/bases/<db>/)に AGENTS.md と、1 行だけの CLAUDE.md @AGENTS.md シムを作成します(存在しない場合のみ作成し、編集内容は上書きしません)。ベースフォルダーの AGENTS.md には、設定ファイルだけでは表現できないベースの目的、重要な決定事項とその理由、ビジネスルール、用語、インテグレーション固有の注意点を記録してください。ベースの変更に合わせて最新の状態を保ってください。これは、次のエージェントがこのデータレイヤーを操作する前に読む、永続的なメモリーです。ファイルがない場合(古い pull など)は、同じ形式で自分で作成してください。
  • record_type の名前変更は、インプレースではなく再シードです。 record_type の id は識別子であり、ファイル名(record-types/<id>.yaml)と一致していなければなりません。そのため名前を変更するには、ファイル名と内部の id: フィールドの両方を同時に更新する必要があります(一方だけを変更するとエラーになります。または、内部の id: を削除してファイル名がデフォルトとして使われるようにします)。いずれの場合も、これはインプレースの名前変更ではなく、新規作成+古いものの孤立化です。差分には + <new>/- <old> と表示され、push は新しい空の record_type を作成します。古い record_type とそのすべてのレコードは変更されずに残り、レコードは移行されません。データを保持して名前を変更するには、(1)push を実行して新しい空の record_type を作成し、(2)レコードを再シードし(例:rekor records upsert またはバッチ処理)、(3)push --prune を実行して孤立した古い record_type を削除します。これにより、そのレコードも連鎖的に削除されます。同じ「ファイル名=id」のルールは、リレーションシップタイプおよびその他の設定エンティティにも適用されます。
RecordTypes
rekor record-types list --base <ws>
rekor record-types get <id> --base <ws>
rekor record-types upsert <id> --base <ws> --name <name> --schema <json|@file> [--description <desc>] [--icon <name>] [--color <hex>] [--sources <json|@file>]
rekor record-types delete <id> --base <ws>
rekor record-types history <id> --base <ws> [--limit <n>] [--offset <n>] [--diff]

--icon/--colorは、検査 UI 向けの表示ヒントです。--sourcesは外部ソースを宣言します。詳しくは、以下の「外部ソース」セクションをご覧ください。

record_typeを削除すると、そのすべてのレコード(およびそれらを参照するすべてのリレーションシップ)も削除されます。同じ ID で再作成したrecord_typeは空の状態で始まります。

Records
rekor records upsert <record_type> --base <ws> --data <json|@file> [--id <uuid>] [--external-id <id>] [--external-source <src>]
rekor records get <record_type> <id> --base <ws>
rekor records query <record_type> --base <ws> [--filter <json|@file>] [--sort <json>] [--fields <list>] [--limit <n>] [--offset <n>] [--external-source <src>]
rekor records delete <record_type> <id> --base <ws>
rekor records history <id> --base <ws> [--limit <n>] [--offset <n>] [--diff]

historyは、エンティティの変更履歴全体を返します。すべてのバージョンのスナップショット、変更したユーザー、操作、および変更日時が含まれます。管理者専用です。プラットフォーム管理者、またはread:auditを付与されたトークンで利用できます。通常のエージェントトークンは拒否されます。(同じhistoryサブコマンドは、relationships、record_types、relationship-typesにもあります。)localティアの評価用クローンでは変更履歴は保持されません。詳しくは**「Bases → Analytics tier」**をご覧ください。

フィルタリングと検索。 query(REST のGET /records/<record_type>、MCP のquery_records)では、Filter DSL 式を指定します。条件{field, op, value}、またはそれらをまとめたand/orグループを指定できます。演算子:eq、neq、gt、gte、lt、lte、in、not_in、like、ilike、is_null、is_not_null、has、および**search。この DSL だけが受け付けられます。Mongo 形式の省略記法({"data.field":"value"}、{"field":{"$in":[...]}})はサポートされていません**。

アクティブなレコード(およびリレーションシップ)の一覧表示とフィルタリングは、書き込み後の読み取りで一貫性が保たれます。書き込んだばかりのレコードは、次の一覧に遅延なく表示されます。一方、いくつかのクエリ形式では、最近同期されたデータを読み取るため、書き込んだばかりのレコードが表示されるまでに少し時間がかかる場合があります。対象はsearchクエリ(以下を参照)と、タイムゾーンオフセットなしで指定された値と組み込みのcreated_at/updated_atタイムスタンプを比較するフィルタです。(フィールドの一部を投影して要求しても、これ自体が動作を変えることはありません。投影によってクエリが最近同期されたデータを使う経路に切り替わることはありません。)localティアのベースでは、最近同期されたデータのコピーがないため、どちらの形式も遅れて結果が返るのではなく、エラーで拒否されます。別のプレビューからクローンされたプレビューはlocalティアとして作成されます。詳しくは**「Bases → Analytics tier」**をご覧ください。

searchは、フィールドの値を近似検索します。保存されている値と完全には一致しないものの、近い文字列(モデル名、場所、プラン名、入力ミスの可能性がある SKU など)がわかっている場合に使います。結果は一致度の高い順に返され、それぞれに_search_score(0~1。数値が高いほど近い)が付与されます。

// "find vehicles whose model is close to 'honda civic', only active ones"
{ "and": [
  { "field": "data.status",    "op": "eq",     "value": "active" },
  { "field": "data.car_model", "op": "search", "value": "honda civic" }
] }

すべてのフィールドはデフォルトで検索可能なため、searchに設定は不要です。完全一致フィルタとsearchは、1つのクエリで組み合わせられます。完全一致条件とsearchの条件を並べて指定すると、完全一致条件で結果を絞り込み、その範囲内でsearchが順位付けします。フィールドの照合方法を調整するには、x-searchモード(name/text/fuzzy)、threshold、searchable: falseについて、references/querying.mdをご覧ください。検索対象は最新の同期データであるため、少し前に書き込まれたレコードが表示されるまでに、わずかな時間がかかる場合があります。ツールセットを通じてエージェントにsearch(およびその調整機能)を公開するには、list Action のfilterable_fieldsでmatch: searchを宣言します。この指定だけが、この演算子に到達します。

並べ替え。 --sortには、各要素が{"field":"data.<field>","direction":"asc"|"desc"}という形式のJSON 配列を指定します。例:--sort '[{"field":"data.created_at","direction":"desc"}]'。複数の要素は辞書順に並べ替えられます(最初の要素が主キーです)。directionを省略した場合は、デフォルトでascになります。data.name:ascのようなコロン形式の省略記法は受け付けられません。JSON 配列形式を指定してください。検索の関連度順を維持するには、searchを使う際に--sortを省略してください。 日時。 record_type スキーマで日時フィールドを "format": "date-time"(日付のみの場合は "format": "date")として宣言します。Rekor は日時を単一の標準形式で保存します。オフセットのない値には record_type のタイムゾーンが付加されるため、2026-06-11T13:00:00 は 2026-06-11T13:00:00-03:00 として保存・返却されます。query と単一レコードの読み取りで同じ形式になり、UTC への変換は不要です。タイムゾーンは record_type の x-timezone → 基本設定の settings.timezone → UTC の順に決定されます。フィルタリングでは時刻が考慮されます。 eq/neq/in/not_in と範囲演算子は日時を時点で照合するため、指定する表記(T とスペースの違い、オフセットの有無)によって結果は変わりません。日時の完全一致には like(単純な部分文字列一致)ではなく eq を使用してください。生の rekor sql ではこのような書き換えは行われません。日時条件には Filter DSL の query を使用してください。タイムゾーンの設定(CLI の --timezone、REST、settings のマージと置換の動作)については references/querying.md を参照してください。

部分更新と全件更新。 全件 upsert(manage_record の upsert、REST の PUT)では、レコード全体を書き込みます。すべてのフィールドを送信してください。残りのフィールドを再送信せずに特定のフィールドだけを変更する(ステータスを切り替える、フラグを設定する)には、部分更新を使用します。manage_record の patch、生成された update_<record_type> ツール、または REST の PATCH .../records/<record_type>/<id> が使えます。部分更新では、指定したフィールドが保存済みレコードにマージされます(トップレベルでマージし、ネストされたオブジェクトは全体が置き換えられます)。id または external_id で既存のレコードを指定し、マージ後の結果も record_type スキーマを満たす必要があります。外部ソースをバックエンドとする record_type では、指定したフィールドがその上流システムに転送され、更新方法は上流システムによって決まります。マージ後に残りのフィールドを保持する保証は、Rekor に保存されているレコードに適用されます。

キャンセルとアーカイブ。 レコードはデフォルトで更新可能です。同じ external_id で再度 upsert すると、既存のレコードがその場で更新されます(冪等な upsert)。状態は自由に進められます(例:scheduled → confirmed)。スキーマの x-archival.mode を使うと、record_type により厳格なアーカイブ動作を設定できます。immutable(一度だけ書き込み可能。更新はすべて拒否)または on_attribute(設定された終端値に達するまで更新可能)を指定します。レコードは削除とは異なる第一級の状態として、MCP(manage_record の cancel)または REST(POST .../records/<record_type>/<id>/cancel)でキャンセルすることもできます。CLI に cancel サブコマンドはありません。キャンセル済みのレコードは更新できません。レコードは自動的にアーカイブされることもあります(終端状態または不変状態に達したとき、あるいは長期間更新がないとき)。アーカイブ済みのレコードは読み取り可能で、キャンセルもできますが、削除はできません。同じ external_id で再度 upsert すると、アーカイブ済みのレコードを更新するのではなく、新しいレコードが作成されます。リストクエリはデフォルトでアクティブなレコードを返します。 アーカイブ済みのレコードは、rekor records list/rekor relationships list、クエリツール、レコードのトラバーサルでは除外されます。リストからアーカイブ済みレコードをクエリするには、archived に対するフィルタ条件を追加します(例:{"field":"archived","op":"eq","value":true})。どの階層を参照するかは、その条件によって決まります。レコードのトラバーサルにはフィルタを上書きする方法がないため、アーカイブ済みのリンクにアクセスできるのは生の SQL のみです。生の rekor sql にはデフォルトの条件が適用されないため、アクティブなレコードだけを取得するには、自分で archived = false を追加してください(キャンセル済みの行には cancelled = true が設定されています)。 参照整合性(外部キー)。 Record 型スキーマのルート properties の直下にあるプロパティには、x-fk ヒントを追加することで、別の record_type への外部キーを宣言できます。参照元の Record 型はネイティブ(sources: [])である必要があります。ネイティブへの書き込みでは毎回、その値が実在するレコードを指しているか確認されます。参照先が存在しない場合は、無効なデータが気付かれないまま登録されるのではなく、対処方法がわかるエラーで拒否されます。ネストされた宣言や複合宣言(例:insurance.plan_id)、ソースを持つ参照元 Record 型での宣言、Relationship 型の data_schema 内での宣言は、正確なスキーマポインターとともに設定の書き込み時に拒否されます。ネストされた参照はルートプロパティに移動するか、x-fk を削除するか、参照元 Record 型をネイティブにしてください。既存の本番環境のレガシー設定は、リンクされたプレビューで修正している間も引き続き提供されます。昇格のドライランでは、結果としてできる設定全体のブロッカーが報告され、実際の昇格は修正されるまでブロックされます。

"patient_id":      { "type": "string", "x-fk": { "record_type": "patients" } },                 // matches patients by external_id (default)
"professional_id": { "type": "string", "x-fk": { "record_type": "professionals", "key": "code" } }, // matches a named field on the target
"note_patient_id": { "type": "string", "x-fk": { "record_type": "patients", "key": "id" } }     // matches the target's system id
  • key は、値が一致する必要がある参照先のフィールドです。デフォルトは external_id で、参照先のシステム id や、任意のトップレベルフィールド(例:code)も指定できます。
  • external_id のないネイティブレコードを参照する場合は、key: "id" を使用してください。システム ID はレコードの作成時に割り当てられるため、先に参照先を作成し、その id を取得してから参照します。これは 1 回のバッチ処理やシードフィクスチャではできません(これらは external_id で解決されます)。そのため、そちらでは external_id/データキーを使用してください。
  • 作成、完全なアップサート、部分更新、バッチなど、書き込みのたびにチェックされます。値が空または存在しない場合はスキップされます。必須にする場合は、フィールドに required を指定してください。
  • 制約が適用されるのは参照元の型です。参照先は外部ソースを使用していてもかまいません。そのような参照先の行は上流にあるため、Rekor はローカルでの存在確認をスキップします。
  • バッチでは、参照先を、それを参照するレコードより先に書き込んでください(バッチはアトミックなため、参照が不正だとバッチ全体が拒否されます)。この順序が有効なのは external_id/データキーの場合のみです。id キーを使うには、前述のとおり、事前の書き込みで参照先を作成する必要があります。
  • 外部キーは、参照データ(患者、プラン、製品)に使用し、高頻度のイベントログには使用しないでください。チェックを高速に保てるよう、参照される record_type はすぐに利用できる状態に保たれます。
添付ファイル

大きなコンテンツやバイナリコンテンツ(PDF、画像、ファイル)はレコードの添付ファイルとして保存し、レコードデータから参照してください。レコード/リレーションシップの JSON は構造化データ用で、サイズ上限は約 1 MiB であるため、Base64 の塊をインライン化すると拒否されます。ファイル名にはフォルダー構造を表すパスを含めることができます(例:docs/guide.md)。バージョン管理、メタデータスキーマ、比較交換、S3 マウントには、添付ファイルをさらに発展させたFiles(以下)を推奨します。

rekor attachments upload <record_type> <id> --base <ws> --filename <name> [--content-type <mime>] [--file <path>]
rekor attachments url <record_type> <id> --base <ws> --filename <name>
rekor attachments list <record_type> <id> --base <ws> [--prefix <path>]
rekor attachments delete <record_type> <id> <attachment-id> --base <ws>

upload に --file を指定するとローカルファイルを直接アップロードします。--file を指定しない場合、upload はバイトデータを PUT するための署名付き URL を返します。url は既存の添付ファイルを取得するためのダウンロード URL を返します。--prefix を指定すると、list の結果をパスのプレフィックス(例:docs/)で絞り込めます。

ファイル

第一級の、バージョン管理されたパスでアドレス指定されるファイルです。添付ファイルをさらに進化させたものです。PDF、画像、生成されたレポート、その他の大容量またはバイナリコンテンツを、ファイルタイプ(ストレージポリシー(最大サイズ、許可されるコンテンツタイプ)と任意のメタデータスキーマを設定する「バケット」)内のファイルとして保存します。ファイルは変更可能なpathでアドレス指定されます。名前を変更してもアドレスが移動するだけで、バイト列は変わりません。ファイルは比較交換(--if-matchを使い、現在のコンテンツハッシュが一致する場合にのみアップロード)、構造化メタデータ、レコードへのリンクに対応しています。

ファイルタイプを設定します(プレビューベースで設定してから、昇格します)。

rekor file-types upsert <id> --base <ws> --name <name> [--max-size <bytes>] [--allowed-content-types <json|@file>] [--metadata-schema <json|@file>]
rekor file-types list --base <ws>
rekor file-types get <id> --base <ws>
rekor file-types delete <id> --base <ws>

ファイルを操作します。

rekor files put <file_type> <path> --base <ws> --file <local> [--content-type <mime>] [--metadata <json|@file>] [--label <tag>] [--if-match <sha256>]
rekor files get <file_type> <path> --base <ws> [--output <local>] [--meta] [--version <n>]
rekor files list <file_type> --base <ws> [--prefix <path>] [--depth <n>]
rekor files mv <file_type> <from> <to> --base <ws>
rekor files rm <file_type> <path> --base <ws>
rekor files history <file_type> <path> --base <ws> [--limit <n>] [--offset <n>]
rekor files diff <file_type> <path> --base <ws> --from <n> --to <n>
rekor files mount <file_type> --base <ws> [--mode <read_only|read_write>] [--path <prefix>] [--expires-in <seconds>]

**ファイルコンテンツのバージョン。**ファイルのコンテンツが変更されるたびに、変更前のコンテンツは不変のバージョンとして保持されます。putで--label(例:--label "proposal 1")を付けてバージョンにラベルを付け、rekor files get --version <n>で以前のバージョンを読み取ります(デフォルトでは最新のバージョンが読み取られます)。ファイルの名前変更や再ラベル付けなど、メタデータのみの変更では新しいバイト列が作成されないため、新しいバージョンは作成されません。rekor files history <file_type> <path>でファイルのバージョン一覧を表示し、rekor files diff <file_type> <path> --from <n> --to <n>で2つのバージョンを比較できます。メタデータの差分に加え、テキストファイルの場合は行単位のコンテンツ差分が表示されます。

ファイルタイプのファイルシステムとしてのマウント。rekor files mount <file_type>を実行すると、S3互換の認証情報が発行されます。S3に対応するハーネスやツール(s3fs、クラウドストレージマウントSDKなど)を使ってバケットをローカルフォルダーとしてマウントし、通常のファイルシステム呼び出しでファイルを読み取れます。ツールごとの連携は不要です。エンドポイント、バケット名、アクセスキーが表示されます(シークレットは一度だけ表示されます)。パス形式のアドレス指定を使用して、S3クライアントをこれらの情報に接続してください。--path <prefix>(繰り返し指定可能)を使うと、認証情報をサブツリー内に制限できます。また、--mode read_only(デフォルト)または--mode read_writeでアクセス権を設定できます。書き込み用認証情報の発行には、ファイルへの書き込みアクセス権が必要です。read_writeマウントではファイルを書き戻すこともできます。書き込みは競合から保護され、バージョン管理されます。各変更は、読み取り開始時のバージョンと照合されます(新規作成にはそのパスが未使用である必要があり、更新には読み取り後にファイルが変更されていないことが必要です)。そのため、古い内容での上書きは、同時に行われた変更を黙って消去するのではなく、拒否されます。書き込みはすべて新しいバージョンとなり、完全な履歴が保持されます。(read_onlyマウントは読み取り専用です。書き込みは別の場所からrekor files putまたはAPIを使って行ってください。)

**ファイルのレコードへのリンク。リレーションシップの参照先としてファイルを指定できます(エンドポイントの種類はfileです)。GET /v1/{base}/records/{record_type}/{id}/related-filesを使うと、レコードにリンクされたファイルの一覧を取得できます。POST /v1/{base}/records/{record_type}/{id}/attachを使うと、ファイルを作成してレコードにリンクする処理を1回で行えます(リクエストボディはファイルのバイト列、file_type、rel_type、pathはクエリパラメーターです)。リンクのリレーションシップタイプがcascade**として宣言されている場合、リンク(または所有するリレーションシップ)を削除するとファイルも削除されます。cascade以外のリンクは通常の参照であるため、複数のレコードで共有されているファイルは削除されずに残ります。本番環境のエージェントはmanage_file MCP ツール(テキストコンテンツの作成/メタデータの取得/一覧表示/移動/削除/履歴/差分)でファイルを管理し、manage_file_typeでファイルタイプを管理します。

SQL クエリ

ベースデータに対して読み取り専用の SQL クエリを直接実行します。フィルタリング、集計、JOIN、CTE、配列操作に対応しています。

rekor sql "<query>" --base <ws> [--param key=value ...] [--file query.sql]

テーブル: records、relationships、record_types、relationship_types、bases、operations_log、organization、audit_log

organization テーブルでは、組織レベルのメタデータを参照できます。plan 列と status 列は維持管理されておらず、課金上の意味はありません。プランはここではなく、アカウントを管理するプラットフォームに紐づいています。これらを利用権限として読み取らないでください。組織の作成時期によって、空文字列または古いデフォルト値が格納されています。

3 つのテーブルには**base_id 列がない**ため、ベースを識別する実際の列に {base_id:String} をバインドしてください。

テーブルベースのスコープ指定条件
basesid = {base_id:String}
operations_logdata.base_id.:String = {base_id:String}
organizationなし — 組織レベルであり、ベースごとの行はありません

そのため、このベーススコープのエンドポイントでは organization を照会できません。組織全体を対象とする SQL サーフェス(POST /v1/orgs/{org_id}/sql)から読み取ってください。このエンドポイントでは {org_id:String} のみでスコープを指定します。いずれの場合も、org_id = {org_id:String} を指定してください。

audit_log テーブルには、rekor records history の変更履歴が記録されています。アクターを含め、すべてのエンティティの全バージョンが含まれます。JOIN 経由を含め、このテーブルを参照するクエリには同じ管理者制限が適用されます。利用できるのはプラットフォーム管理者、または read:audit が付与されたトークンです。このテーブルと operations_log は追加専用のため、どちらにも deleted = false 条件は不要です。

重要: 追加専用の audit_log と operations_log を除き、常に org_id = {org_id:String} と base_id = {base_id:String}(上の表に従ってベースを識別する列にバインド)に加え、deleted = false を指定してください。追加専用の 2 つのテーブルには deleted 列がないため、この条件を指定すると拒否されます。両方のスコープ指定条件は必須です。ベース ID は組織内でのみ一意であり、グローバルには一意ではないため、データを分離するには org_id が必要です。どちらのプレースホルダーも、認証済みの組織とベースに基づいてサーバー側でバインドされます。records テーブルには archived と cancelled のブール列もあります。アクティブなレコードのみを照会するには、archived = false を追加してください。クエリでは常に各行の最新バージョンが参照され、重複排除はサーバーが処理します。

評価用クローン: 別のプレビューからクローンされたプレビューは local 分析ティアで実行されます。この環境では records、relationships、audit_log に対する SQL は拒否されます。それ以外のテーブルには引き続き応答します。Bases → Analytics tier を参照してください。

JSON フィールドへのアクセス: ネイティブの JSON 型には data.field.:Type サブカラム構文を使用してください。型安全な変換が必要な場合(Int64 と Float64 のどちらで格納されているかが異なる整数など)は、CAST(data.field, 'Type') を使用してください。

例:

# Simple query
rekor sql "SELECT data.invoice_number.:String as num, data.status.:String as status FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'invoices' AND deleted = false" --base my-ws

# Aggregation
rekor sql "SELECT data.status.:String as status, count() as cnt FROM records WHERE org_id = {org_id:String} AND base_id = {base_id:String} AND record_type = 'invoices' AND deleted = false GROUP BY status" --base my-ws

配列集計、埋め込み配列を展開する ARRAY JOIN、レコードとリレーションシップを結合する CTE、--param バインド、曖昧一致/jaroWinklerSimilarity によるランキング付きテキスト照合を含む、すべてのサンプルについては、references/querying.md を参照してください。

リレーションシップタイプ

リレーションシップタイプは rel_type を定義します。そのタイプのリレーションシップを作成する前に、リレーションシップタイプを定義する必要があります(設定操作のため、プレビュー後にプロモートします)。--schema(任意)でリレーションシップのメタデータを検証できます。--source-record_types/--target-record_types(任意)を指定すると、接続可能な record_types を制限できます。

rekor relationship-types upsert <rel_type> --base <ws> [--description <text>] [--schema <json>] [--source-record_types <json>] [--target-record_types <json>]
rekor relationship-types list --base <ws>
rekor relationship-types get <rel_type> --base <ws>
rekor relationship-types delete <rel_type> --base <ws>
rekor relationship-types history <rel_type> --base <ws> [--limit <n>] [--offset <n>] [--diff]

リレーションシップタイプを削除すると、そのタイプのリレーションシップもすべて削除されます。

関係
rekor relationships upsert --base <ws> --type <type> [--source <col/id> | --source-external <col/external_id> [--source-external-source <name>]] [--target <col/id> | --target-external <col/external_id> [--target-external-source <name>]] [--id <id>] [--external-id <key> [--external-source <name>]] [--data <json>]
rekor relationships get <id> --base <ws> [--rel-type <type> [--external-source <name>]]
rekor relationships delete <id> --base <ws> [--rel-type <type> [--external-source <name>]]
rekor relationships history <id> --base <ws> [--limit <n>] [--offset <n>] [--diff]
rekor query-relationships <record_type> <id> --base <ws> [--type <type>] [--direction outgoing|incoming|both] [--limit <n>] [--offset <n>]

各エンドポイントでは、--source/--source-external のいずれか1つを指定します(ターゲットも同様です)。外部アドレス指定ではアクティブなレコードのみが解決され、レコードが存在している必要があります。内部 ID は指定されたとおりに保存されます。

関係には、それ自体の外部キーを付与することもできます。upsert 時に --external-id を指定すると作成が冪等になります(同じキーで upsert を再試行すると、重複行を作成せず、最初の行が更新されます)。また、get/delete では、--rel-type でスコープを指定すると、ID の代わりにこのキーを受け付けます。API では、これらはトップレベルの external_id/external_source フィールド(バッチの upsert_relationship オペレーションおよび生成されるリンクツールでも同様)と、アドレス指定用の GET/DELETE /relationships/<external_id>?rel_type=<type> に対応します。

--type は宣言済みの関係タイプである必要があります。--data はそのタイプのスキーマに照らして検証されます。

統合のモデリング(カノニカル優先)

以下の統合エッジ(インバウンド Webhook、トリガー、外部ソース)は、record_type を外部システムに接続します。どのエッジを使うか、またその背後のエンティティをどのように構成するかは、これを基準に判断します。これは、エージェント向けのツールサーフェスを構成する、終盤のエージェントによる利用を想定したモデリング原則のセクションを補完するものであり、データの基盤となる構成方法を定めます。

唯一のルール:まずエンティティをカノニカルにモデリングし、どの統合にも依存しない形にします。そのうえで、オペレーションごとに、どのようにデータの基盤を構成するかを決めます。 record_type はエンティティそのものです。ビジネス上の名称を使ったプロパティ、適切な列挙値、妥当なデフォルト値を備えた、すっきりとしたスキーマにします。上流ペイロードの形をそのまま使ってはいけません。統合は宣言的なエッジに置き、スキーマやツールサーフェスに混在させてはいけません。利用者(エージェントやクエリ)は、フィールドが rekor ネイティブなのか、レガシーシステムからミラーリングされたものなのかを判別できないようにします。

  • まず正規モデルを作成します。 バックエンドのペイロードではなく、ドメインとエージェントの実際の利用フローからスキーマとツールの範囲を導きます。各ビジネスルールは、適用可能な最も信頼性の高いレイヤーに配置します。スキーマ(列挙型、required、デフォルト値)>トリガー(リアクティブな不変条件)>ツール制約(writable_fields/precondition)>プロンプトの順です。また、強制可能なデータ不変条件をプロンプトのルールとして記述してはいけません。適切な粒度にします。利用フローで触れるものだけをモデル化し、必要に応じて追加で拡張します(推測に基づくスキーマは、追加するより削除するほうが困難です)。
  • スワップテストを行います。 エンティティのバックエンドを切り替える(レガシー → ネイティブ → 別のシステム)と、そのスキーマや意味上のツールの範囲(ツール名、data フィールド、フィルターパラメーター)を変更する必要があるなら、モデルに統合の詳細が漏れています。モデルを修正してください。統合に依存しないモデルだけが切り替え可能です。同じ正規コントラクトを、あるベースではネイティブに提供し、別のベースではソースの field_mapping だけを差し替えてレガシー API にプロキシできます。バックエンドの切り替えで実際に変わるのは、エンベロープのアドレス指定パラメーター(external_id/external_source)であり、これはソースが引き継ぎます。詳しくは MCP Factory リファレンスの 外部アドレス指定はソーストポロジーによって公開されます を参照してください。これはサーバー側で移動する仕組みであり、情報の漏れではありません。ただし、作成時に external_id を渡すプロンプトやハーネスは、バックエンドの選択に依存してしまうため、エージェントへの指示には含めないでください。レガシーシステムにないカタログ項目は、同じベースにネイティブの record_type として追加し、同じツールセットを通じて公開します。
  • オフライン評価は、追加コストなしで得られる成果です。これは逆方向からのスワップテストです。 プレビュー専用の --integrations disabled 評価トグル(上記の ベース を参照)が機能するのは、モデルが統合に依存しないからです。スワップテストでは、エンティティの表面を変えずにバックエンドを切り替えますが、評価トグルでは、表面を変えずにバックエンドを取り外します。ソースを無効にしても、同じ正規スキーマ、ツール、フィールドマッピングで引き続き提供でき、今度はシード済みのローカルデータを使います。つまり、まず正規モデルを作成すれば、本番環境に安全な決定論的エージェント評価を追加コストなしで実現できます。これは別々の機能ではなく、1つの原則です。
  • ネイティブかプロキシかは record_type ごとに選択します。ソースの操作ブロックでは、上流システムが公開する操作を宣言します。 ソースのない record_type はネイティブ(すべての CRUD がローカル)です。ソースのある record_type はプロキシ経由であり、すべての書き込みは上流に送られ、読み取りは上流に対して解決されます(ローカルには何も保存されません)。ソースの list/get/create/update/delete ブロックで、上流がサポートする操作(読み取り専用の get/list、または完全な読み書き)を選択します。ソースにない操作は未サポートであり、暗黙的にネイティブとして処理されることはありません。1つの record_type の操作ごとにネイティブとプロキシを分けるのではなく、record_type 間で組み合わせます。1つのツールセットで、ネイティブ経由のツールとプロキシ経由のツールを自由に組み合わせられます(プロキシ経由の invoices と、ネイティブで補完した plans/activities を並べて使うなど)。
  • ツールごと、またはフィールドごとにネイティブかプロキシかを振り分けてはいけません。 ネイティブかプロキシかは record_type ごとに選択し、ツールごとには選択しません。writable_fields で制限するのは、ツールが書き込むフィールドであり、書き込み先ではありません。(同じ操作に対する2つのプロキシツールが、ソースの異なる名前付き書き込みバインディングを選択することはできます。詳しくは「外部ソース」を参照してください。ただし、これは書き込み先となる上流のエンドポイントを選ぶだけです。すべてプロキシのままであり、一方のツールをネイティブ、もう一方をプロキシにすることはありません。)1つの record_type で「ネイティブ読み取り+プロキシ書き込み」を混在させると、読み取り整合性に穴が生じます(同期処理がない限り、ネイティブ読み取りにはプロキシ書き込みが反映されません)。その同期処理を追加するなら、ネイティブ書き込みと external_write トリガーを組み合わせるほうが明らかに優れています。整合性のある構成はすべてプロキシかすべてネイティブ+同期の2つです。ツールごとに混在させる構成は、整合性のない中間案です。
  • ネイティブミラーを優先し、やむを得ない場合にのみプロキシを使います。 同期を保つネイティブ record_type なら、ローカルでのクエリ/結合/フィルタリング、高速性、トランザクション対応の書き込み、監査、上流から独立した可用性が得られます。読み取り時の古さが許容されない場合、信頼できる唯一の情報源である上流システムで書き込みを同期的に確認する必要がある場合、またはデータセットが大きすぎるかアクセス頻度が低く、ミラー化に適さない場合にのみ、読み取りをプロキシ経由にします。
  • ハイブリッドエンティティ(ミラー化されたフィールドと rekor 所有のオーバーレイ)は、1つの record_type にまとめます。 上流にないフィールド(ワークフローの status、タグ、スコアなど)は、ミラー化されたフィールドと同じレコードに配置します。統合クエリ/フィルタリングに必要だからです(status が別の record_type にあれば、list where status=X は実行できません)。所有権を分けるためにエンティティを分割すると、実際のクエリ機能を犠牲にして管理作業を増やすことになるため、分割しないでください。例外は、オーバーレイ自体が独自のライフサイクル/履歴を持つ、より豊かなエンティティである場合です。その場合は、関連する record_type とリレーションシップを使用します。スカラー属性は、分割する理由にはなりません。
  • field_mapping は双方向の単一コントラクトであり、あらゆる接点で再利用します。 同じソースコントラクトが、プロキシ読み取り、書き込みの上流反映、受信 Webhook のデータ補完(source_binding)、external_write による送信を支えます。変換を一度だけ定義し、各接点で再利用します。
  • 参照型 Webhook は、ペイロードのコールバックをたどらず、ソースの get でデータを補完します。 成熟した Webhook の多くは参照型です(「レコード X が変更されたので、取得しに行く」)。ペイロードが小さく、古いスナップショットを含まず、順序のずれも自動的に修正できます。ID を取り出し、バインド済みソースの get で取得して解決します。ペイロードに指定されたコールバック URL は SSRF の攻撃経路となるため、無視します。 パターンカタログ — 上流が提供する内容と必要なものに応じて、エッジを選択してください。
パターンソース/エッジの形読み取り書き込み使用する場面
ネイティブsources: []ローカルローカルrekor がデータを所有する場合
プロキシ読み取りソースの list/get上流の最新データ—鮮度が重要な場合、またはミラーリングするには大きすぎる参照データの場合
ライトスルーソースの create/update(読み取りには get/list)上流の最新データ→ 上流(ID が返されます)上流が信頼できる唯一の情報源であり、ローカルミラーなしで同期的な確認が必要な場合
プッシュ同期ミラー受信 Webhook によるハイドレーション+バインドされたソースの getローカルローカル上流が変更通知をプッシュし、最新のミラーをローカルでクエリしたい場合
双方向ミラーハイドレーション(merge)+external_write トリガー(watched_fields)ローカルローカル(→ トリガー経由で上流)双方向に同期されるハイブリッドエンティティで、すべてネイティブのツールを使う場合

双方向ミラーは、ハイブリッドエンティティに適した慣用的な構成です。ネイティブの record_type を1つ用意し、ツールはすべてネイティブにして、同期を宣言的なエッジとして構成します。ハイドレーションには merge を使うと、再同期時にマッピングが管理するフィールドのみが更新され、オーバーレイは保持されます。また、external_write の watched_fields: "mapped" を使うと、オーバーレイのみの変更によって上流への不要な書き込みが発生しません。ハイドレーションの書き込み先はネイティブ(ソースなし)である必要があります。同じ record_type に対するプロキシ書き込みではなく、外向きエッジは external_write トリガーです。さらに、skip_inbound_webhook_writes によって再同期時にトリガーが再発火しないようにすることで、ループを防ぎます。

識別キー。 カタログ/参照エンティティ(プラン、アクティビティ、場所)には、external_id も兼ねる安定した slug をキーとして使い、record_type をまたぐ x-fk 参照を解決できるようにします。人物/関係(メンバー、予約、登録)には、rekor の内部 uuid をキーとして使います。

受信 Webhook(データの取り込み)

外部システムは受信 Webhook を介してデータを Rekor にプッシュします。それぞれに固有の取り込み URL が用意されます。

rekor inbound-webhooks create --base <ws> --name <name> --secret <hmac-secret> [--id <id>] [--record_type-scope <comma-separated>] [--field-mapping <json>] [--source-binding <json>] [--ingest-auth <json>]
rekor inbound-webhooks list --base <ws>
rekor inbound-webhooks get <id> --base <ws>
rekor inbound-webhooks delete <id> --base <ws>

--secret は共有シークレットであり、必須です。デフォルトでは、送信元が取り込みリクエストに署名し、Rekor が HMAC を検証します。署名方式は、id、timestamp、method、path、body に対する Signing v1(X-Data-Signature: v1,<hex>)と、Rekor が鮮度を確認する X-Data-Timestamp の組み合わせ(トリガーとプロキシ呼び出しでも同じ方式を使うため、1つの署名処理で両方向に対応できます)、または旧式の送信元向けの、body のみを対象とする従来の HMAC のいずれかです。v1 の配信は冪等です。重複した配信(同じ X-Data-Id を含む再試行またはリプレイ)に対しては、再度書き込む代わりに最初のレスポンスを再送します。リクエストごとに署名する代わりにアカウントごとの固定ヘッダーで認証する送信元では、--ingest-auth '{"type":"static_header","header":"X-Account-Key"}' を指定すると、そのヘッダーの値を --secret と照合して(定時間比較で)検証します。Rekor は署名ではなく、設定されたヘッダーを照合します。--record_type-scope を指定すると、受信 Webhook が書き込める record_type を制限できます(省略するとすべてが対象です)。受信 Webhook を作成/削除できるのはプレビューのベースのみです。準備ができたら本番環境に昇格してください。

書き込む前に受信ペイロードを変換します。 デフォルトでは、受信 Webhook はペイロードをそのまま保存します。外部システムの未加工の形式から正規化されたレコードを直接保存するには、マッピングを指定します。外部ソースで使用されるものと同じ field_mapping の仕様(名前の変更、値のマッピング、日付の再フォーマット、計算/合成)が、受信方向に適用されます。

  • --source-binding '{"record_type":"<id>","source":"<name>"}' を指定すると、既存のソースの field_mapping を再利用できます。その record_type の読み取り/書き込みをプロキシする際の変換を受信配信にも適用できるため、双方向で1つの仕様を使えます。
  • --field-mapping '{"to_external":{"status":"state"}}' は、ソースのない純粋なネイティブ record_type 向けのインラインマッピングです。to_external の名前変更は読み取り時に自動で逆変換されます(上流の state → Rekor の status)。または、to_record/computed を明示的に指定します。 この 2 つは相互排他的です。マッピングは、webhook の作成時とプロモーション時に検証されます(source_binding が、field_mapping を持つソースを引き続き解決できる必要があります)。これにより、エグゼキューター不要のネイティブミラー同期を実現できます。受信 webhook の to_record と、external_write トリガーの to_external を組み合わせることで、単一のソース契約を再利用しながら、ネイティブの record_type をプレーンな HTTP のアップストリームと双方向で同期できます。

Webhook のハイドレーション(通知+取得)。 多くのシステムはレコード全体ではなく、「レコード X が変更されました。ID はこれです」という参照形式の webhook を送信します(Stripe は ID による再取得を推奨しており、Shopify、Salesforce、HubSpot、レガシー CRM も同様です)。このような webhook を record_type の読み取りソースに指定すると、Rekor は配信のたびにレコード全体を自動で取得し、その後、正規レコードを保存します。

rekor inbound-webhooks create --base <ws> --name orders-ref --secret <token> \
  --record_type-scope orders \
  --source-binding '{"record_type":"orders","source":"shop_api"}' \
  --ingest-auth '{"type":"static_header","header":"X-Account-Key"}' \
  --hydration '{"id_path":"record_id","event_path":"event","event_map":{"ResourceDeleted":"delete"}}'

配信時、Rekor は薄い本文からレコード ID(id_path)を読み取り、紐付けられたソースの読み取りエンドポイントを呼び出してレコード全体を取得し、ソースの field_mapping を介して正規化したうえで、external_id をキーにアップサートします。これは、プロキシ読み取りに対応する受信側の動作です。イベントフィールド(event_path と event_map)はアップサートまたは削除に振り分けられます(削除の場合は取得をスキップし、ミラーリングされたレコードを削除します)。それ以外はすべてアップサートになります。取得と書き込みは非同期で、自動リトライ/バックオフが行われるため、送信元には即座に受け付けたことを返します。進行状況は rekor inbound-webhooks deliveries --base <ws> で確認できます。--source-binding(読み取りエンドポイントを提供)と、単一のネイティブ --record_type-scope が必要です。セキュリティ: Rekor が取得するのは、抽出した ID を使ってソースに設定された URL だけです。ペイロード内のコールバック URL は無視され、アクセスされることはありません。参照形式の送信元では、通常、各配信に署名しないため、--ingest-auth(静的ヘッダー)を組み合わせます。

再同期時に独自のフィールドを保持する — merge。 デフォルトでは、再同期のたびにレコード全体が置き換えられるため、ローカルで追加したフィールド(ワークフローのステータス、タグ、スコア、割り当て、内部メモなど)は上書きされます。--hydration に "merge":true を追加すると、再同期で更新されるのはソースのマッピングが管理するフィールドだけになり、レコードに追加したそれ以外のフィールドは保持されます。これにより、1 つの record_type でアップストリームのミラーとローカルの拡張情報の両方を保持でき、独自のフィールド(例:status=qualified)でエンティティを引き続き一覧表示/フィルタリングできます。最初の同期では、マッピングされたフィールドを使ってレコードが作成されます。アップストリームで後からフィールドがクリアされた場合も反映され、マージ後のレコードは引き続きスキーマ検証されます。例:--hydration '{"id_path":"record_id","merge":true}'。

トリガー(データの送信)

レコードまたはファイルが変更されると、トリガーが自動的に実行されます。トリガーのアクションは次のいずれかです。

  • webhook — 外部システムへの HMAC 署名付き HTTP POST です(--url/--secret)。
  • internal_write — Rekor が外部サービスを介さず、参照先のレコードを更新します。条件に一致する書き込みがあると、対象レコードを特定し、条件付きパッチを適用します(対象が想定どおりの状態にある場合にのみ更新する、任意の比較・設定 precondition を指定できます)。「A が変更されたら、関連する B を更新する」場合に最適です。たとえば、予約を作成すると、枠が空いている場合に限り、その枠を使用中に変更します。--action で指定します(以下を参照)。対象イベントは record.created/updated のみです。モードは 2 種類あります。async はトリガーとなる書き込みの直後にパッチを適用します(結果整合性。precondition が一致しなかった場合は記録されますが、トリガーとなる書き込みはそのまま確定します)。transactional はトリガーとなる書き込みと同時にパッチをアトミックに適用します。precondition が一致しない場合、書き込み全体が拒否され、ロールバックされます(何も作成されません)。2 つの書き込みをまとめて成功または失敗させる必要がある場合(たとえば、枠が空いていない限り予約を作成しない場合)は、transactional を使用してください。
  • external_write — Rekor は外部ソースの書き込み経路(フィールド変換、エンドポイント、本文の形式、認証)を再利用して、変更されたレコードを外部システムに書き込みます。エグゼキューターは不要です。ネイティブの record_type をレガシー API と同期させる場合に使用します。レコードは Rekor にネイティブに保存し、各書き込みを上流システム独自の形式で送信できます。このアクションではソースを指定します:{type:"external_write","record_type":"<source-owner>","source":"<name>","op":"create"}。record_type はソースを定義する record_type です(ネイティブのミラーでは、兄弟関係にあるソース連携 record_type を指定します。省略した場合は、トリガー対象の record_type が既定値になります)。op はイベントに応じて既定で設定されます(created→create、updated→update、deleted→delete)。上書きも可能です。create 時には、Rekor はレスポンスから上流側で割り当てられた ID を読み取り、トリガー対象のレコードに external_id として関連付けます(ネイティブレコードから上流側の対応レコードを参照でき、再試行による重複も防げます)。無効にするには link_external_id:false を指定します。更新と削除は、そのソースにすでに関連付けられているレコードに対してのみ送信されます。既定では、一致するすべての更新が上流に送信されます。watched_fields を追加すると、上流にマッピングされたフィールドが実際に変更された書き込みだけに update の送信を限定できます。"mapped" を指定すると、ソースが上流にマッピングするフィールドだけを監視します(Rekor が管理するフィールド、つまりソースが外部にマッピングしないフィールドのみを変更する書き込みでは、不要な上流への更新をスキップします)。または、データフィールド名を明示した配列を指定できます。作成と削除は常に送信されます。配信は非同期で行われ、webhook と同様に署名、再試行、デッドレター処理が適用されます(rekor triggers deliveries で確認できます)。対象イベントは record.created/updated/deleted のみです。
rekor triggers create --base <ws> --name <name> --events <comma-separated> --url <url> --secret <hmac-secret> [--id <id>] [--record_type-scope <comma-separated>] [--filter <json>]
# internal_write action (instead of --url/--secret):
rekor triggers create --base <ws> --name <name> --events record.created --record_type-scope appointments \
  --action '{"type":"internal_write","target":"slots","match":{"source_field":"data.slot_id"},"patch":{"status":"busy"},"precondition":{"field":"data.status","op":"eq","value":"free"},"mode":"async"}'
# external_write action — mirror a native record_type's writes out through a source's write path:
rekor triggers create --base <ws> --name <name> --events record.created,record.updated --record_type-scope appointments \
  --action '{"type":"external_write","record_type":"upstream_appointments","source":"legacy","op":"create"}'
rekor triggers list --base <ws>
rekor triggers get <id> --base <ws>
rekor triggers delete <id> --base <ws>
rekor triggers deliveries --base <ws> [--status <pending|delivered|failed|dead>] [--trigger-id <id>]

--events はカンマ区切りのリストです(JSON 配列ではありません)。有効なイベント:record.created、record.updated、record.deleted、record.cancelled、relationship.created、relationship.updated、relationship.deleted、file.created、file.updated、file.deleted。例:--events record.created,record.updated。ファイルイベントは、ファイルの書き込み時(作成/内容またはメタデータの変更/削除)に実行されます。ファイルトリガーの --record_type-scope ではファイルタイプを指定し、--filter ではファイルのメタデータ(例:data.status)を照合します。ファイルイベントはwebhook のみに対応します(internal_write/external_write アクションはレコード専用です)。create/update のような単独の名前は一致しないため、何も通知されません。webhook の場合、--secret は受信側が検証する HMAC 署名用のシークレットです。--record_type-scope を指定すると、実行対象を特定の record_type に限定できます(すべてを対象にする場合は省略)。トリガーから参照されている間、internal_write の対象レコードは利用可能な状態に保たれます。external_write の場合、参照先のソースは作成時に検証されます(指定した record_type とソースが存在し、各 op に対応する書き込みエンドポイントが存在する必要があります)。トリガーからソースを参照しても、トリガー対象の record_type がプロキシに変わることはありません。ネイティブのままです。 --filter '<json>' を指定すると、条件に一致するレコードに対してのみ実行されます。クエリと同じフィルター DSL が、書き込まれるレコード(またはリレーションシップ)に対して評価されます。たとえば、--filter '{"field":"data.status","op":"eq","value":"paid"}' を指定すると、status が paid の場合にのみ実行されます。条件は and/or グループで組み合わせられます。不正なフィルターは作成時に拒否されます。

トリガーは HMAC 署名されます(X-Data-Timestamp とともに、id+timestamp+method+path+body に対する X-Data-Signature: v1,<hex> を使用します。受信側はタイムスタンプの鮮度を確認します。これはプロキシされたリクエストで使われるものと同じ方式です)。また、受信側で重複排除できるよう、X-Data-Id/X-Data-Delivery-Id も付与されます。配信は確実に行われます。失敗した試行はバックオフを伴って再試行され、繰り返し失敗するとデッドレター化されます。rekor triggers deliveries でステータスを確認してください。デフォルトでは、インバウンド Webhook からの書き込みでトリガーが再実行されることはありません(skip_inbound_webhook_writes: true)。トリガーを作成・削除できるのはプレビューベースのみです。

Executor(外部で処理を実行)

Rekor は記録、署名、ディスパッチを行いますが、実際の外部処理(サードパーティ API の呼び出し、クライアント証明書の提示、Rekor では実行できないロジックの実行)は、トリガーまたは外部ソースの送信先として設定する、小規模なステートレス HTTP サービスであるエグゼキューターが担います。Rekor はディスパッチするすべてのリクエストに署名します。エグゼキューターは署名を検証し、処理を実行して、結果を書き戻します。

エグゼキューターは本当に必要ですか? 通常の REST/JSON API なら、外部ソースだけで十分です(エグゼキューターは不要です)。また、同じソースの書き込みパスは external_write トリガーでアウトバウンドにも再利用できるため、ネイティブの record_type を通常の HTTP アップストリームにミラーリングする場合もエグゼキューターは不要です。トリガーでカスタムロジックを実行する場合、またはソースへの呼び出しを直接の HTTP リクエストにできない場合(mTLS、SOAP、バイナリ認証情報、負荷の高い処理)にのみ、エグゼキューターを作成してください。インバウンド Webhook は逆方向の処理に使います。エグゼキューターからインバウンド Webhook を呼び出して、結果を書き戻します。

このパッケージを使って必ずこれらのリクエストを受信してください。署名検証を独自に実装してはいけません(ミスがあると、誰でもエグゼキューターに偽造リクエストを送れるようになります)。SDK は署名とタイムスタンプを検証し、冪等性キーを使って再試行を重複排除し、エラーを正規化します。あとはハンドラーを 1 つ書くだけです。

import { createExecutor, toFetchHandler } from '@wayai/executor-sdk'
const handler = toFetchHandler(createExecutor({
  secret: process.env.REKOR_SIGNING_SECRET!,
  handler: async (ctx) => { /* ctx.body is verified; do the work, return a result or nothing */ },
}))
// Hono: app.post('/rekor', (c) => handler(c.req.raw))  •  Cloudflare: export default { fetch: handler }

実行場所: まずはサーバーレスプラットフォーム(Cloudflare Workers、Vercel、Deno Deploy、AWS Lambda。すでに使用しているものを選んでください。インターフェースはプラットフォームに依存しません)を選びます。ほとんどのエグゼキューターは認証済み API 呼び出しだけであり、サーバーレス関数は安価で高速、かつ使用量がゼロになると停止します。サーバーレス関数では対応できない場合(相互 TLS クライアント証明書、長時間実行する処理、生の TCP/SOAP、ネイティブ依存関係)に限り、長時間実行するコンテナまたはサーバー(Fly.io、Railway、Render、VM)を利用してください。

インターフェースの全容、フレームワーク別の実装、Vault 経由で証明書を扱うパターン、ローカル開発については、references/executors.md(このスキルと同梱)を参照してください。

外部ソース(record_type を外部 API に接続)

record_type では、1 つ以上の外部ソースを宣言できます。レコード操作で、設定済みのソース名と一致する external_source が指定されると、Rekor は読み取り/書き込みを自前のストアではなく外部 API(またはエグゼキューター)にプロキシします。これにより、エージェントは別途インテグレーションコードを用意せずに、同じ rekor records/MCP 呼び出しを通じて stripe をバックエンドとする請求書を読み書きできます。

record_type スキーマの一部としてソースを設定します(プレビューのみ。スキーマ変更と同じ手順で昇格します)。

rekor record-types upsert invoices --base my-ws--preview --name "Invoices" \
  --schema @schema.json --sources @sources.json

各ソースでは、以下の項目を定義します(完全な文法、各オプションのルール、レガシーな上流 API の実例については references/external-sources.md を参照してください)。

  • name — レコードの external_source と一致する必要があります。
  • auth — ヘッダーと値のテンプレートです。シークレットは直接指定するか、vault:<name> で参照します。直接指定したシークレットは環境ごとに管理されます。昇格時にコピーされないため、本番環境で直接設定してください(新たに昇格したソースは未設定のままになり、設定するまでリクエストは明確なエラーで失敗します)。vault:<name> の参照は参照として引き継がれます。
  • field_mapping — 省略可能です(省略すると ID のまま受け渡します)。to_external/to_record は、スキーマと上流 API のフィールド名を対応付けます。単純な名前の変更のほか、詳細なルール(transform、values[常に Rekor 側のキーを使用]、default、date_format、array_mode、target)も指定できます。高度な形式として、1 つのフィールドを複数のパラメーターに分割(targets)、複合値を分解(separator+parts)、複数の上流フィールドから Rekor フィールドを合成(computed テンプレート)、および操作ごとのオーバーライドがあります。
  • get/list/create/update/delete — 操作ごとのエンドポイントテンプレートです。それぞれ固有の url(トークン {{external_id}}、{{query.*}}、{{data.*}}、{{current.*}}/{{prior.*}}、{{auth.*}})と method を指定できるため、RPC スタイルの動詞パスや、すべてのリクエストが POST の上流 API に直接対応できます。response_path/total_path/success_path/message_path でエンベロープを解除します。
  • 名前付き書き込みバインディング(create/update/delete)— 1 つの正規エンティティへの書き込みが複数のバックエンドエンドポイントに振り分けられる場合、書き込み操作を名前付きエンドポイントのバリエーションのマップとして宣言します。呼び出し元は名前でバリエーションを選択し(ツールの bindings を使用)、1 つの record_type を維持できます。
  • id_path — 上流のレコードで external_id が格納されている場所を指定します(ドットパス、複合テンプレート、または create 専用/リクエストテンプレート形式)。id をキーにしない上流 API で使用します。
  • forward_filters(list に指定)— エージェントの eq フィルター条件を上流に転送します(許可する fields と query/body の転送先を指定)。読み取りマッピングからも {{filter.<field>}} として参照できます。
  • local_filters(list に指定)— フィルターパラメーターのない上流 API 向けです。コレクションの範囲が限定されていることを宣言し、全件を取得したうえで、Rekor がフィルターとソートをメモリー上で適用します(search 以外のすべての演算子に対応。ネイティブページネーションを使用)。forward_filters とは併用できません。max_rows は省略可能です(デフォルトは 500)。
  • static_body/body_template/request_encoding — 定数、テンプレート、フォームエンコードによるリクエストボディの整形を指定します(レガシーな動詞形式で ID をボディに含める場合など)。
  • injections/executor_secrets — ヘッダーまたはボディに含める、リクエストごとの追加の Vault シークレットと、ディスパッチ時にエグゼキューターが取得する名前付き認証情報(mTLS 証明書など)を指定します。
  • cache_ttl+stale_if_error/signing/timeout_ms/breaker — 読み取り時のキャッシュ、HMAC 署名(エグゼキューター用)、リクエストごとのタイムアウト、ソースごとのサーキットブレーカーを指定します。

URL は絶対 https(または allow_insecure_http: true を指定した http)である必要があります。また、トークンを含められるのはパスまたはクエリのみで、ホストには含められません。それ以外は SSRF ガードにより拒否されます。

バッチ(アトミック)

最大1,000件の操作をアトミックに実行します。すべて成功するか、すべて失敗します。

rekor batch --base <ws> --operations '[
  {"type":"upsert_record","record_type":"invoices","external_id":"inv-1","data":{"customer":"A","amount":100}},
  {"type":"upsert_record","record_type":"customers","external_id":"cust-1","data":{"name":"A"}},
  {"type":"upsert_relationship","rel_type":"belongs_to","source_record_type":"invoices","source_external_id":"inv-1","target_record_type":"customers","target_external_id":"cust-1"}
]'

操作の種類:upsert_record、delete_record、upsert_relationship、delete_relationship、upsert_record_type、delete_record_type

リレーションシップ操作では、各エンドポイントを内部 ID(source_id/target_id)または外部キー(source_external_id +任意の source_external_source)で指定します。各エンドポイントにつき、指定できるのはどちらか一方だけです。操作は1つのトランザクション内で順番に実行されるため、上記の例では、1回のアトミックな呼び出しで2つのレコードを作成し、それらをリンクします。リンクは、先行する操作で書き込まれたばかりの external_ids を解決し、解決できない場合はバッチ全体がロールバックされます。

結果の読み取り:デフォルトの(テーブル形式の)出力では、操作ごとに1行の概要(インデックス、種類、結果の ID)が表示されます。操作ごとの完全なペイロード(書き込まれたすべてのレコード/リレーションシップの全内容)を表示するには、--output json を追加します。バッチはアトミックなため、1つの操作が失敗するとバッチ全体がロールバックされ、コマンドは Operation <N> failed: <reason> を出力してゼロ以外の終了コードで終了します。このメッセージには、失敗したインデックスが示されます。部分的な書き込みは行われません。

一括インポート

過去データの一括取り込みには、専用のインポート機能を使用します。通常のアップサートと同様に書き込みますが、トリガーのファンアウトはスキップします(バックフィルされた行では、Webhook や内部/外部への書き込みカスケードは実行されません)。そのため、write:records に加えて専用の write:imports 権限が必要です。

CLI を使用してください。ファイルはストリーミング処理されるため、サイズはメモリに制約されません。また、チャンク分割を行い、以下の再開処理や月境界のケースも自動で処理します。

rekor import run patients --file patients.ndjson --base prod   # one JSON object per line
rekor import list [--limit <n>] [--offset <n>] --base prod     # sessions, newest first
rekor import rollback <import_id> --base prod                  # undo (prompts only in a terminal)

run は生成した request_key を出力します。実行が途中で停止した場合に備えて、これを控えておいてください。途中で停止した場合、rekor import run … --request-key <key> --start-chunk <n> を実行すると、ファイルを再送信せずにそのチャンクから再開できます。最初に使用したものと同じ --chunk-size を指定してください。チャンク番号はこの値から算出されるため、異なるサイズで再開すると、インデックス N が別の行を指してしまいます。--start-chunk を使用する場合、CLI ではこのフラグの明示的な指定が必須です。実行が途中で停止した場合は、再開するチャンクのインデックスが表示されます。表示された --start-chunk/--chunk-size/--request-key を指定し、その他のフラグも変更せずに、同じコマンドを再実行してください。コマンドを最初から入力し直さないでください。--start-chunk が大きすぎると行が黙ってスキップされ、--base を省略すると別のベースで再開されてしまいます(--org は何も作用しません。組織はキーによって決まります)。--chunk-size は1,000以下です。--no-finalize を指定すると、後で再開できるようセッションが開いたままになります。

CLI ではなく、言語ランタイムやスケジュール済みジョブなどを使って自分で実行する場合は、REST インターフェイスを使用できます。

POST /v1/{base_id}/import/begin        {"request_key":"<your-run-id>","record_type":"<record_type>"}
POST /v1/{base_id}/import/chunk        {"import_id":"<from begin>","chunk_index":0,"rows":[{"external_id":"…","data":{…}}, …]}
POST /v1/{base_id}/import/{import_id}/finalize
POST /v1/{base_id}/import/{import_id}/rollback   — undo the import (deletes only rows it CREATED)
GET  /v1/{base_id}/import/{import_id}/rollback-plan?counts=true  — what an undo would reach, before doing it
GET  /v1/{base_id}/import/sessions     — list sessions (newest first) to find or recover a stuck run

コントラクトの要点:

  • begin は request_key ごとに冪等です(論理的な実行ごとに1つ選択してください)。応答を受信できなかった場合も安全に再送でき、同じセッションが返されます。セッションが開いている間に、同じキーを異なるレコードタイプで再利用すると 409 が返されます。1つの実行につき、1つのキーと1つのレコードタイプを使用してください。セッションが確定すると、そのキーは再び使用可能になります(翌日の同じジョブの実行で再利用すると、新しいセッションが作成されます)。begin が 503 を返した場合、残りの利用枠を確認できず、セッションも作成されていません。同じ request_key で再試行してください。
  • チャンクは最大1,000行で、chunk_index でインデックス付けされ、サーバー側で受領結果が記録されます。同じチャンク(同じインデックス、同じ内容)を再送すると、適用し直すことなく記録済みの結果が返されるため、タイムアウトや接続切断が発生しても安全に再試行できます(シードリースの完全一致する再試行と同様で、ほかのすべてのデータ書き込みとは異なります)。内容が異なるチャンクを同じインデックスで再送すると 409(IMPORT_CHUNK_HASH_MISMATCH)が返されます。編集済みの入力から再開するには、新しいセッションが必要です。
  • 行は external_id でアップサートされます。内容がすでに一致する行は書き込みなしでスキップされるため、全件リフレッシュを再実行しても実際に変更された項目だけが書き換えられます。ただし例外が1つあります。一致する行が約45日間書き込まれていない場合は、アーカイブ扱いに移行せず、定期的に再インポートされるレコードをアクティブとしてカウントし続けるため、バージョンを更新して(履歴に更新を記録して)書き換えられます。そのため、それより間隔の長いリフレッシュではすべての行が書き換えられ、rows_skipped は長い間隔をまたいだ冪等性の保証としては信頼できません。
  • すべての検証とアーカイブ/ワークフローのゲートは、通常の書き込みと同様に適用されます。immutable レコードタイプへのインポートは新規作成のみです。ネイティブのレコードタイプのみが対象です(ソースに紐付くタイプには一括書き込みできません)。
  • 24時間アイドル状態のセッションは、開いている枠が回収されます(これはベースで次の begin または finalize が実行されたときに発生するため、操作されていないアイドルセッションはその時点まで残る場合があります)。1つのベースで開いておけるセッションは最大でも数個です。完了したら finalize を実行してください。セッションはUTC の月境界でも終了します。含まれる行の利用枠は開始した月に属するため、新しい月に送信された最初のチャンクは 409 IMPORT_SESSION_CLOSED を返し、details.status: "expired" を示します。復旧するには、再度 begin を呼び出し(同じ request_key で新しいセッションが返されます)、そのチャンクを再送してください。すでに書き込まれた行はスキップされるため、月をまたいでも余分に必要なのは begin の1回だけで、再インポートは発生しません。details.status が closed の場合は、実行が明示的に確定済みであることを意味します。その実行を自動的に再開しないでください。 取り消し: rekor import rollback <import_id>(または REST ルート)を実行すると、インポートによって作成された行のみを論理削除します。単に上書きされた行はそのまま残り、インポート後の値も維持されます(バージョンを戻す機能はありません)。削除された行を参照するリンクも削除されるため、参照先のないリンクは残りません。処理はページ単位で行われ、各呼び出しは swept と complete を返します。complete が true になるまで呼び出しを続けてください。CLI では自動的にループします。ターミナルでは、最初に現在の該当件数を表示して確認を求めます(--yes を指定すると省略できます)。それ以外の場所(スクリプト、CI、エージェントなど、TTY ではない環境)では確認プロンプトは表示されず、ほかの破壊的なコマンドと同じ慣例に従って、直ちに処理が始まります。件数を事前に確認したい場合は、まず GET /v1/{base_id}/import/{import_id}/rollback-plan?counts=true を実行してください。再試行は常に安全です。すでに処理されたページはそのままのため、リトライ可能な 503(ベースがビジー状態)で失敗しても、取り消した内容が復元されることはありません。もう一度呼び出してください。インポート自体と同様に、トリガーは一切発火しません。削除もリンクの削除も何も通知しないため、削除を別のシステムに同期するトリガーはこれらを認識せず、そのシステムには行が残ります。実行には write:imports、レコードタイプに対する write:records、および write:relationships が必要です(この処理では常にリンクが削除される可能性があります)。取り消したレコードにファイルが添付されていた場合、添付リンクは削除されますが、ファイル自体は残ります。取り消しで削除されるのはインポートによって作成されたものだけで、ファイルはその後に追加されたためです。不要であれば、明示的に削除してください。知っておくべき制限がさらに2つあります。すでにアーカイブストレージに移動した行には手が届かないため、実質的に取り消せる期間はおおむねアーカイブの間隔までです。また、immutable レコードタイプでは再インポートによる上書きもできません。そのため、これらのタイプへのインポートは最初から正確なデータを用意する必要があります。通常は、修正したデータを再インポートするほうが適切です。行は external_id でアップサートされるため、修正版を再実行するとその場で上書きされます。

ご利用のプランには、毎月、レコード上限と同数の一括インポート行が含まれます。上限を超えた行は20行ごとに1 op として計算され、リクエストごとに切り上げられ、最低0.1 op となります(適度なサイズに分けて送信してください。小さく分割しても料金は下がりません)。実際に書き込まれた行のみが対象です。スキップされた(変更のない)行と再生されたチャンクは無料のため、再実行時に課金されるのは変更分だけです。ただし、前述の約45日ごとのアーカイブ書き換えは例外で、それより間隔を空けずに疎な更新を行うと、すべての行が書き換えられ、課金されます。begin/finalize は無料です。rollback の呼び出しごとに1 op かかるため、大規模なインポートの取り消しはページごとに1 op かかります。また、事前確認の rollback-plan は ?counts=true を指定すると1 op(インポートの行を走査して件数を数えるため)、指定しない場合は0.1 op かかります。インタラクティブな(トークンを使わない)インポートは従量課金の対象外ですが、インポートした行にはプランのレコード上限が適用されます。

シードフィクスチャ(分離された評価データ)

フィクスチャとは、プレビューベースに適用する、名前付きで元に戻せるレコード(およびリレーションシップ)のセットです。エージェントの評価に、クリーンで再実行可能な初期状態を用意できます。設定をコードとして記述し、名前で操作することで、評価ハーネス(スコープを限定したトークンを使うヘッドレス/クラウド環境のものも含む)は、汚れた状態のベースを引き継ぐことなく、各実行の前後でデータをリセットできます。

フィクスチャをベースの設定フォルダー内のファイルとして作成し、ベースと一緒にプッシュします。

# rekor-ws/bases/<preview-base>/seeds/demo.yaml
id: demo
description: Overdue-bills demo baseline
records:                       # author FK targets BEFORE the records that reference them
  - record_type: customers
    external_id: cust-1
    data: { name: Ada }
  - record_type: bills
    external_id: bill-1
    data: { customer_id: cust-1, status: overdue, amount: 120 }
relationships:                 # endpoints reference records by external_id
  - rel_type: owes
    source: { record_type: customers, external_id: cust-1 }
    target: { record_type: bills, external_id: bill-1 }
exclusive_record_types: [customers, bills]   # optional: reset also removes non-declared records of these types
rekor push                       # store the fixture on the preview (pushes with the rest of the config)
rekor seed apply demo --base <preview>   # write the fixture's records/relationships
rekor seed reset demo --base <preview>   # restore the declared baseline (fixes records a run mutated)
rekor seed clear demo --base <preview>   # delete every row the fixture owns (teardown)
rekor seed list --base <preview>         # show the fixtures defined on the base

同時実行される評価や、結果が不明な評価実行では、reset と clear を別々に呼び出す代わりに、アクターに紐づくシードリースを使用してください。新しい UUIDv7 を一度生成し、リリースするまで変更不可能なタプルとして保存します。owner_ref は安全な実行ラベルにすぎず、権限が付与されることはありません。1~200文字で、英字または数字で始め、それ以外は英字、数字、または ._:@/+~=- のみを使用してください(空白は不可)。

rekor seed lease acquire demo --base <preview> \
  --lease-id <uuidv7> --owner-ref <safe-run-id>
rekor seed lease status --base <preview> --lease-id <uuidv7>
rekor seed lease release demo --base <preview> \
  --lease-id <uuidv7> --owner-ref <safe-run-id>

acquire はフィクスチャをアトミックにリセットし、プレビュー全体のフィクスチャデータ操作をロックします。release はフィクスチャが所有するデータをアトミックに消去し、ロックを解除します。同じ検証済みユーザーまたは Rekor トークンのみが、このタプルを再試行、確認、または解放できます。完全一致する再試行は何も行わず、解放済みの ID は再利用できません。別の認可済みアクターにわかるのは、ベースがロックされていることだけです。acquire がタイムアウトし、結果が不明な場合は、同じタプルで再試行してください。永続台帳に記録できる ID はプレビューあたり 1,000 個までです(警告は 800 個と 950 個で開始)。上限に達したら、使い捨てのプレビューを置き換えてください。

REST での同等のエンドポイントは POST /v1/{base_id}/seed-leases/acquire、POST /v1/{base_id}/seed-leases/release、および GET /v1/{base_id}/seed-leases/status[?lease_id=…] で、いずれもベースにスコープされた write:seeds の複合グラントが必要です。最初の acquire/reset と最初の release/clear の遷移には、それぞれ定額の op が 1 つかかります。status、競合、完全一致する再試行、繰り返しの release はコストがかかりません。

ルールと保証:

  • external_id による冪等性。 apply は各レコードを external_id でアップサートするため、再適用すると既存レコードをその場で更新し、重複は作成しません。レコードがすでに存在する場合でも、複製は作成されません。
  • reset はベースラインを復元します。 宣言済みのレコードをその場で再適用し(実行中に変更されたレコードを修正します。たとえば、トリガーによって切り替わったステータスなど)、フィクスチャが宣言しなくなったフィクスチャ所有の行を削除します。各評価実行の間に reset を使うと、確実にクリーンな状態から開始できます。
  • exclusive_record_types を指定すると、reset はレコードタイプ全体に対して権威ある状態になります。 エージェントが実行中に作成したレコードには所有権マーカーが付かないため、通常の reset ではそれらが残り、実行を重ねるごとに蓄積します。評価で書き込むレコードタイプを指定すると、reset はフィクスチャが宣言していない該当タイプのレコードを、作成者を問わずすべて削除します。他のフィクスチャの行も対象です。また、削除されたレコードを指すリレーションシップも削除します。フィクスチャが宣言したリレーションシップから参照されているレコードは、records に含まれていなくても必ず残ります。これはオプトインであり、reset のみが対象です(apply/clear の動作は変わりません)。エージェントが作成したリレーションシップでも、保持されるベースラインレコード同士をつないでいるものは残ります。ベースに存在しないレコードタイプを指定しても、reset では何も行われません(存在確認は promote 時に行われます)。共有プレビューで排他的なタイプを選ぶ際は慎重にしてください。そのタイプについては、フィクスチャが唯一の信頼できる情報源になります。
  • clear はティアダウンです。 フィクスチャが所有する行だけを削除し、それ以外には手を加えません。フィクスチャは予約済みの所有権マーカーで所有権を記録し(external_source は使用しません)、ティアダウンがシードデータ以外に触れることはありません。
  • プレビュー専用です。 apply/reset/clear は、スキーマ変更と同様にプレビューベースでのみ実行され、本番環境では拒否されます。フィクスチャ定義は他の設定と同様にベースとともに promote されますが、データ操作の対象はプレビューに限られます。
  • トリガーによる副作用はありません。 フィクスチャの適用/リセットはベースラインのセットアップであり、トリガーは発火しません。そのため、データの復元によって連鎖的な変更が発生することはありません。
  • API から操作できます。 3 つの動詞はフィクスチャ名を指定して REST API から実行できるため、1 つのプレビューベースに対する write:seeds スコープのトークンを持つクラウド評価ハーネスが、自身でデータをリセットできます。
  • リースはフィクスチャデータ操作を全体的にロックします。 シードリースが 1 つでも有効な間は、すべてのフィクスチャに対する通常の apply、reset、clear 呼び出しが FIXTURE_TARGET_IN_USE を返します。フィクスチャ定義の設定に対する CRUD は引き続き利用できます。
プロバイダーアダプター

任意の LLM プロバイダーのツール定義をレコードタイプとしてインポートする(rekor providers import <provider>)、レコードタイプをツール定義としてエクスポートする(rekor providers export <provider>)、またはプロバイダー固有のツール呼び出しをレコードに変換する(rekor providers import-call)ことができます。対応プロバイダー:openai、anthropic、google、mcp。コマンド形式とペイロードの形状については references/providers.md を参照してください。

MCP ファクトリー(カスタムツールセット)

基本の record_types から、用途に特化した MCP サーバーを作成します。各ツールセットはドメイン固有のツールを提供するため、エージェントには汎用的な Rekor 操作ではなく、create_invoice や list_payments が表示されます。

# 1. Author first-class Actions — one record_type + one operation each; the id is the tool name
rekor actions upsert get_invoice    --base my-ws --record_type invoices --operation get
rekor actions upsert list_invoices  --base my-ws --record_type invoices --operation list
rekor actions upsert create_payment --base my-ws --record_type payments --operation create
rekor actions upsert list_payments  --base my-ws --record_type payments --operation list

# 2. Compose a curated toolset that references those Actions by id
rekor toolsets upsert invoicing-agent --base my-ws \
  --name "Invoicing Agent" \
  --action get_invoice --action list_invoices \
  --action create_payment --action list_payments \
  --relationship "invoice_payment:list" \
  --batch "invoices:create,update" --batch "payments:create" --batch "invoice_payment:create" \
  --sql-query

# Get the MCP connection URL (Streamable HTTP)
rekor toolsets url invoicing-agent
# → https://mcp.rekor.pro/t/invoicing-agent/mcp

# List all toolsets
rekor toolsets list --base my-ws

# Get toolset config (with resolved schemas)
rekor toolsets get invoicing-agent --base my-ws --resolved

# Delete a toolset
rekor toolsets delete invoicing-agent --base my-ws

アクション参照の形式:--action <action_id>(または <action_id>=<surface_name> を指定すると、このツールセット内での名前を変更できます)。まず rekor actions upsert <id> --record_type X --operation Y でアクションを作成します。1 つの record_type と 1 つの operation を指定し、その id がエージェントに表示されるツール名になります。アクションは複合アクションにもできます。rekor actions upsert <id> --config '{ "steps": [...] }' を使うと、複数のネイティブな書き込み(レコードの作成/更新/削除+リレーションシップの作成/削除)を、ステップごとのガードを備えた 1 つのアトミックなツールにまとめられます(references/mcp-factory.md → Composite Actions を参照)。 リレーションシップ指定の形式:rel_type:op1,op2(操作:create、list、delete) バッチ指定の形式:record_type_or_rel:op1,op2

詳細な制御は、ツールセットが参照するファーストクラスのアクションで行います。整形設定を指定して、rekor actions upsert <id> --record_type X --operation Y --config '{…}' でアクションを作成します(1 つの record_type と 1 つの op)。次に、ツールセットから参照します(--action <id>、またはツールセットの --config 内の actions: [{ action, action_name?, description_override? }] エントリー)。アクションごとの設定項目は、それぞれ 1 行で記載しています(文法の全容と JSON の例は references/mcp-factory.md を参照してください)。

  • tool name — Action の id はエージェント向けのツール名です。ツールセットの参照では、action_name によってサーフェスごとに名前を変更したり、description_override によって説明を置き換えたりできます。名前はツールセット内で一意である必要があります。(ツールセットにインラインで宣言するリレーションシップツールでは、name/names マップを使用します。)
  • filterable_fields — list Action の選択したフィールドを、型付きパラメーター(生のフィルターではなく、ネイティブ引数)として公開します。各フィールドで指定する項目は、param、match(exact/range/text/any_of/member/search)、enum、pattern、optional、description です。宣言したフィールドは、デフォルトで必須です(ツールが尋ねる項目です)。optional: true を指定すると任意になり、範囲の上下限は常に任意です。param は最終的なパラメーター名ではなく、語幹です。text → <param>_contains、range → <param>_min/_max(日付の場合は _after/_before)、search → <param>_search となり、exact/any_of/member ではそのまま使用します。ランク付けされた search オペレーター(およびフィールドの x-search チューニング)に到達するのは、match: search のみです。references/mcp-factory.md を参照してください。
  • expose_* + default_* — list Action の機構パラメーター(filter/sort/limit/offset/fields)は、デフォルトで非表示になっているため、ツールは純粋にセマンティクスを表します。expose_<param>: true を指定すると、パラメーターを再び公開できます。default_* を指定すると、パラメーターが非表示のまま適用されるサーバー側の値を設定できます(非表示の limit のデフォルトは余裕のあるページサイズです)。
  • writable_fields — create/update Action の書き込み側における同等の設定です。設定可能なフィールドを厳密に限定する許可リスト(最小権限を意図したツール)であり、record_type のスキーマから、型付けされた豊富な data スキーマも生成します。
  • base_filter — list Action のすべての呼び出しに対して、Filter DSL の述語をサーバー側で AND 結合します。エージェントには見えません。広範な record_type から、対象を絞ったツールを切り出せます(list_active_practitioners は、status = active を組み込んだ list Action です)。モデルが入力方法を知っている必要のある任意の status パラメーターを公開する必要はありません。対象は list のみで、ネイティブの record_type、またはリストエンドポイントで local_filters を宣言しているソース連携型のものに限られます。セキュリティ境界ではありません。常に最新の状態に保たれる述語には、リテラルの日付(時間の経過とともに古くなる)ではなく、範囲オペレーターとともに、date-time フィールドで値 "$now" を使用します(starts_at gt $now は未来のみを対象にします)。これは設定専用であり、フィルター引数にはなりません(references/mcp-factory.md を参照)。
  • precondition — create/update Action における Filter DSL の比較更新です。レコードの現在の状態に対してチェックされ、一致しない場合は 409 となり、変更は行われません。エージェントには見えません。脆弱な読み取り後の書き込みを、競合のない単一の呼び出しに置き換えます(例:スロットがまだ free の場合にのみ book_slot を実行)。
  • binding — プロキシソースの op で、書き込み Action がディスパッチする名前付き書き込みバインディングを選択します(External Sources を参照)。これにより、1 つの正規の record_type の書き込みを複数のエンドポイントに振り分けられます。

エージェントを、ちょうど 1 つの base にスコープされたトークンを使って、ツールセットの URL に接続します。エージェントに表示されるのは、設定したツールだけです。ドメインに完全に特化しており、Rekor の概念は一切ありません。最小権限を実現するには、次のコマンドでツールセットに紐付いたトークンを一度に発行します:rekor tokens create-for-toolset <slug> --base <db>。ツールセットに紐付いたトークンの認可範囲は、ツールセットのツールサーフェスそのものです。対象となるのは、指定された record_type とオペレーション、リレーションシップ、バッチ、そして有効にした場合に限り SQL です。それ以外にはアクセスできません。そのため、トークンが漏えいしても公開したツールの範囲を超えてアクセスされることはなく、エージェントごとにローテーションまたは取り消しができます。対話形式で設定する場合は、rekor toolsets upsert --mint-token でもトークンを作成できますが、ツールセットとトークンをまとめて出力するこの方法は、自動的な認証情報の取得には対応していません。

自動設定では、rekor tokens create-for-toolset <slug> --base <db> --token-only を実行してください。フェイルクローズ方式で取得する手順と JSON レスポンスの形式については、下記の API Tokens を参照してください。 ツールセットはプレビューベースでのみ作成・変更できます。準備ができたら本番環境に昇格します。公開済みのツールセットが破損する場合(record_type/rel-type の削除、または型指定フィルター/writable_fields/base_filter/precondition/bindings が依存するフィールドの削除)は、昇格がブロックされます。ドライランでは、最初に競合が一覧表示されます。mcp.rekor.pro/t/{slug}/mcp は、トークンのスコープが設定されたベースからツールセットを解決します。そのため、昇格済みツールセットには本番環境のトークンで接続し、まだ昇格していないツールセットのサンドボックステストにはプレビューベースのトークンを使用してください(解決ルールについては references/mcp-factory.md を参照してください)。

API トークン

エージェント、インテグレーション、CI/CD 向けにスコープを設定したトークンを作成します。トークンは、特定のベース、record_type、環境、権限に制限できます。トークンは保存前にハッシュ化され、生の値が表示されるのは作成時の一度だけです。スクリプトでシークレットが必要な場合は --token-only を使用してください。--json を指定した場合、ラップ解除されたシークレットフィールドは .data.token ではなく .token です。

自動化では --token-only を優先してください。トークンの形式を検証し、テーブル、JSON、MCP URL を付けずに一度だけ使えるシークレットのみを出力します。出力せず、シェルトレースを有効にしないで取得してください。

TOKEN="$(rekor tokens create-for-toolset <slug> --base <db> --token-only)"
case "$TOKEN" in rec_*) ;; *) echo "Token creation failed" >&2; exit 1 ;; esac

ワークフローで --json を使う必要がある場合、Rekor CLI のレスポンスはすでにラップ解除されています。トップレベルの .token を抽出し、.data.token は絶対に使用せず、null を受け入れずに失敗するようにしてください。

TOKEN="$(rekor tokens create-for-toolset <slug> --base <db> --json \
  | jq -er '.token | strings | select(startswith("rec_"))')"

プローブ/テスト/診断用トークンには --ttl を指定して発行してください。自動的に期限切れになるため、使い捨てトークンを手動で取り消したりクリーンアップしたりする必要はありません。--description を使用して、トークンを保持しているもの(サービス、認証情報、パイプラインなど)を記録しておけば、後で取り消したときに何が壊れるかを把握できます。

# Create a full-access token
rekor tokens create --name "my-key" --grants '[{"scope":{"bases":["*"]},"permissions":["*"]}]'

# Create a scoped token (read-only on one base)
rekor tokens create --name "client-a-reader" \
  --grants '[{"scope":{"bases":["client-a"],"environments":["production"]},"permissions":["read:records","read:record_types"]}]'

# Capture the one-time secret for automation (validates rec_ and prints nothing else)
TOKEN="$(rekor tokens create --name "client-a-reader" --token-only \
  --grants '[{"scope":{"bases":["client-a"]},"permissions":["read:records"]}]')"

# Disposable probe token — auto-expires, no cleanup needed (--ttl takes s/m/h/d)
rekor tokens create --name "probe" --ttl 10m \
  --grants '[{"scope":{"bases":["*"]},"permissions":["*"]}]'

# Absolute expiry + a note about who holds the token
rekor tokens create --name "temp-key" \
  --grants '[{"scope":{"bases":["*"]},"permissions":["*"]}]' \
  --expires-at 2026-12-31T23:59:59Z \
  --description "CI pipeline for repo X"

# List tokens (shows status, last_used_at, expires_at, description)
rekor tokens list

# Revoke a token (permanent)
rekor tokens revoke <token_id>

# Clean up stale tokens — selects by staleness ONLY (expired, or unused past the
# window), never by name. Previews first; revoking requires --yes.
rekor tokens prune                        # expired tokens only
rekor tokens prune --unused-since 30d     # + tokens with no activity for 30 days
rekor tokens prune --unused-since 30d --yes

取り消しのガードレール:過去 7 日間に使用されたトークン、またはツールセットにバインドされたトークン(コンシューマートークン。MCP 接続が保持している可能性があります)の取り消しは、警告とともに拒否されます。上書きするには --force を指定してください。トークンに依存するものがないことを人が確認していない限り、--force を指定したり、--include-bound を指定して削除したりしないでください。取り消しは取り消せず、稼働中のトラフィックにただちに影響します。期限切れのトークンは、制約なく取り消せます。

権限:read:records、write:records、read:record_types、write:record_types、read:relationships、write:relationships、read:relationship_types、write:relationship_types、read:attachments、write:attachments、read:files、write:files、read:file_types、write:file_types、read:inbound_webhooks、write:inbound_webhooks、read:triggers、write:triggers、read:toolsets、write:toolsets、read:actions、write:actions、read:seeds、write:seeds、read:bases、write:bases、read:audit(読み取り専用。変更履歴へのアクセスを許可します。管理者の承認が必要で、他の権限からは暗黙的に付与されません)、write:imports(過去のデータの一括インポート。トリガーを実行せずにインポートを確定するため、write:records とは別の権限であり、他の権限からは暗黙的に付与されません)、またはすべての権限を付与する *。

スコープフィールド:bases(必須)、record_types(省略可能。省略するとすべてが対象)、environments(省略可能。production、preview、または両方を対象にする場合は省略)。

トークンには権限の上限が適用されます。自身と同じか、より狭いスコープのトークンのみ作成できます。

シークレット(ボールト)

認証情報を組織レベルで保存します。API キー、署名用シークレット、または認証情報として扱うべきデータ(クライアント証明書、キーストア、サービスアカウントの JSON など)が対象です。シークレットは保存時に暗号化され、レスポンスでは常にマスクされます。ソース/トリガー設定(エグゼキューターの署名用シークレットなど)から参照するか、エグゼキューターが実行時に読み取るようにします。

# Store a string secret
rekor secrets create --name stripe-key --value sk_live_xxx --tags billing

# Store a credential file (base64-encoded) with its type, and an expiry — e.g. a client certificate
rekor secrets create --name partner-cert --file ./partner.p12 \
  --content-type application/x-pkcs12 --expires-at 2027-01-01T00:00:00Z

rekor secrets list                         # List (values masked)
rekor secrets list --expiring [--days 30]  # Only secrets expiring/expired within the window
rekor secrets get <id>                      # Metadata (value masked)
rekor secrets rotate <id> --value <new> [--expires-at <iso>]  # Install a new value (never auto-generates)
rekor secrets delete <id>

有効期限がある認証情報(年次更新の証明書、期限付きトークンなど)には --expires-at(ISO-8601)を設定します。そうすると rekor secrets list --expiring で、インテグレーションに支障が出る前に更新が必要なものを確認できます。有効期限は情報提供のみを目的としています。Rekor がシークレットを自動的に無効化することはありません。

アカウントと診断
# `rekor init` is retired — a rec_ key already carries its organization (see First-Time Setup)
rekor whoami                 # Show the authenticated identity
rekor status                 # Auth, connectivity, active org, worktree binding, CLI version
rekor update                 # Update the CLI to the latest published version
最新の状態を保つ

CLI とこのスキルの両方を最新の状態に保ってください。

  • CLI を更新する — rekor update を実行します(npm では rekor-cli として公開されています。rekor --version で確認してください)。
  • このスキルを更新する — mkdir -p .claude && npx skills add wayai-pro/rekor-skill -y を実行して、最新の公開済みスキルを .claude/ に取得します。

CLI は両方の最新の公開バージョンをバックグラウンドで確認し、どちらかが古い場合は1行の通知を表示します。更新するには、上記の該当するコマンドを実行してください。REKOR_NO_UPDATE_CHECK=1 を設定すると両方の確認を無効にできます(NO_UPDATE_NOTIFIER または CI が設定されている場合も無効になります)。

報告

バグや問題を Rekor チームに報告し、修正まで追跡してください。報告は重複排除されます。対応中に同じ報告が再度送信された場合は既存の報告に統合されます。解決済み、または最終的な却下ではない人間による報告を元の報告者が再提出すると、存続期間中の再判定上限に達していない限り、再調査のために再開されます。

更新通知が表示されている場合(最新の状態を保つを参照)、報告を送信する前に更新して、もう一度確認してください。新しい CLI またはスキルでは、すでにバグが修正されている可能性があります。

# File a report (deduplicated). --dedup-key collapses repeat occurrences of the same issue.
rekor report create --title "Upsert 500s on large docs" --description "..." \
  [--severity high] [--steps "..."] [--error-message "..."] [--dedup-key "<stable-key>"] \
  [--base-id <id>] [--record_type <name>] [--record-id <id>]   # entity pointers aid investigation

# Track and verify your own reports
rekor report list [--status shipped]      # your reports with titles, newest first (--status shipped = awaiting your check)
rekor report get <report_id>              # title + description + status + the message thread
rekor report accept <report_id>           # the shipped fix works → resolved
rekor report contest <report_id> --reason "still reproduces because ..."   # the fix didn't work, or a dismissal is wrong → back to the team

不具合の検証ループ。 ⚠️ 現在、CLI からは利用できません。 report list/get/accept/contest はユーザー単位で処理され、呼び出し元を報告を送信した人物に対応付けます。また、API キーは個人ではなく組織を識別するため、これら4つのコマンドは拒否されます。報告の送信(rekor report create)は引き続き利用できます。ユーザー単位の機能が再び利用可能になるまでは、アカウントの管理者を通じて送信済みの報告をフォローアップしてください。この段落の残りでは、設計上のループについて説明します。

チームが不具合をエスカレーションし、修正がリリースされると、報告のステータスは shipped に変わります。メールが届き、rekor status で一度通知されます(または rekor report list --status shipped でタイトルから検索できます)。rekor report get <id> を読み、元のタイトルと説明、現在のステータス、チームからのメモを確認して、問題なく動作する場合は accept、そうでない場合は contest --reason "..." を実行してください。機能強化の場合は検証すべき不具合修正がないため、問題がクローズされると直接 addressed に変わります。実際に存在すると考える dismissed の報告に対しても contest を実行でき、チームに差し戻されます。異議申し立てには上限があり、チームが却下を最終決定として扱う場合もあります。それ以降はサポートに連絡してください。人間が送信した報告の一覧表示、読み取り、対応ができるのは、あなた自身が送信したものに限られます。エージェントが作成した報告は、管理者のトリアージキューに残ります。


出力形式

機械で読み取り可能な JSON 出力を得るには、--output json を追加します(デフォルトは table です)。

rekor records get invoices rec_abc --base my-ws --output json

データ入力

--data、--schema、--tools、または --operations フラグは、次のいずれかを受け付けます。

  • インライン JSON:'{"key":"value"}'
  • ファイル参照:@path/to/file.json

環境

ルールはRekor オブジェクトモデルに記載されています。設定の書き込みはプレビュー環境でのみ、データの書き込みはどの環境でも可能で、プロモーションは人間が実行します。実際の手順は次のとおりです。

# 1. Create the preview
rekor bases create-preview my-base --name "add-invoices"

# 2. Make config writes against it
rekor record-types upsert invoices --base my-base--add-invoices --name "Invoices" \
  --schema '{"type":"object","properties":{"amount":{"type":"number"}}}'

# 3. Ask the user to run the promotion (human-only — you cannot promote):
#    rekor bases promote my-base --from my-base--add-invoices

my-base 自体がプレビュー環境(無料プランでの構成で、rekor bases create <id> --environment preview を指定する場合)でも、手順1は引き続き機能します。create-preview はプレビュー環境をコピー元にすることもできます。ただし、手順3は機能しません。プロモーションは有料プランが必要であり、プレビュー環境から複製した環境は、本番環境へ直接ではなく、コピー元を経由してプロモーションされます。また、この複製環境は local 分析ティアで永続的に作成されます(Bases → Analytics tierを参照)。そのため、--analytics standard を渡さない限り、rekor sql、history、トラバーサルには使用できません。設定の書き込みは my-base に直接行い、そこで終了してください。

エージェントが利用する際のモデリング原則

上記のコマンドリファレンスは、仕組みについて説明しています。ここでは、それらを組み合わせてエージェントを活用するアプリを信頼性の高いものにする方法を説明します。仕組み上、ほぼどのような形にもできますが、これらの原則では、誤りを起こしやすいLLMエージェントでも成功できる形を選びます。これらはドメインに依存しません。請求書、予約、チケットのいずれをモデル化する場合にも適用できます。これらはエージェント向けのツールサーフェスを形作ります。エンティティのバックエンド(ネイティブ、プロキシ、ミラー)をどうするか、また統合の境界をどう形作るかについては、上記の**統合モデリング(カノニカル優先)**を参照してください。

唯一のルールは、正しいことだけが簡単に表現でき、間違ったことは不可能になるようにモデル化することです。 手順を繰り返し飛ばすエージェントと、ライフサイクル全体をきちんと実行するエージェントの差は、通常、プロンプトやモデルではなく、スキーマとツールの形にあります。

  1. 1つの意図につき、1つのアトミックな書き込みにします。 N回の個別の書き込みが必要なアクションは、そのうち1つを飛ばしてシステムを中途半端な状態にする可能性がN回あります。1つのユーザーの意図は1つの書き込みにまとめてください。1つの意図が本当に複数のレコードにまたがる場合は、rekor batchを使い、すべてコミットするか、すべてロールバックされるようにします。
  2. 状態はエンティティに保持し、重複させないでください。 状態の各要素は、それが表すエンティティ上の1か所だけに保持します。ステータスを2つ目のレコードにも複製すると、エージェントは両方を同期して更新する必要があり、複数回の書き込みという問題が再発します。フィールドをコピーするのではなく、信頼できる情報源をリンクするか、そこにクエリしてください。
  3. タスクだけを公開し、それ以外は公開しないでください。 エージェント向けツールは、タスクだけを表現する必要があります。生成されたツールは、すでに仕組み(sort、limit、offset、フィールド選択、生のフィルターDSL)を隠しています。Actionsの作成方法に関するその意味については、以下のツール設計の原則を参照してください。エージェントは、読み取り時の型付きfilterable_fieldsと書き込み時のwritable_fields(ツールが見るのは、そのタスクで設定するフィールドだけです)を使って意味を指定し、配線を扱う必要はありません。
  4. ガードは引数ではなく設定に置きます。 エージェントが忘れることのないよう、従うべき指示としてではなく、サーバー側で不変条件を適用します。preconditionを使うと、状態に依存する書き込みを競合状態なしで、エージェントに意識させずに行えます。スキーマのrequiredと列挙型は、不正な入力を拒否します。拒否メッセージは復旧のための経路です。エージェントが自力で修正できるよう、読みやすく、実行可能な内容にしてください。
  5. 入力の選択肢を絞ります。 自由度が1つ増えるごとに、誤りの可能性も増えます。列挙型(選択肢を閉じた集合にする)、型付きfilterable_fields(自由形式のフィルター文字列ではなくネイティブのパラメーターを使う)、安定したexternal_idキー(べき等なアップサートを行い、IDを勝手に作らせない)、書き込み時のx-fk(参照先が実在するレコードであることを要求する)で制約してください。
  6. 理想的なエージェントではなく、誤りを起こしやすいエージェントに合わせてモデル化します。 エージェントは手順を飛ばし、入力していないフィールドに空文字列を送り、IDをでっち上げることがあります。requiredはフィールドの欠落を拒否し、列挙型は値の捏造を拒否し、x-fkは架空の参照を拒否し、preconditionは順序の誤った書き込みを拒否します。それぞれが、気付かないままのデータ破損を、明確で修正可能なエラーに変えます。
  7. オペレーター向けサーフェスとエージェント向けサーフェスを分けます。 設定を作成するためのサーフェスと、それを呼び出すためのサーフェスは分離してください。人間やCI向けの広範なトークンでスキーマやツールセットを設計し、ツールセットに紐付いたトークン(rekor tokens create-for-toolset)では厳選されたツールだけを呼び出せるようにし、その範囲を越えてアクセスできないようにします。ツール名はアクションと対象数が分かるもの(book_slot、list_invoices、assign_payment)にして、名前だけでエージェントがツールの機能を把握できるようにします。

さらに: データを正規化し、自己記述的に保ってください。datetimeフィールドにはformat: date-timeを宣言し、record_typeのx-timezoneを設定して、すべての値にオフセットを持たせます。また、文脈がなくてもレコードを推論できるよう、不透明なコードより読みやすい列挙値を優先してください。そして、よく使われる操作を意図的に最適化してください。最も頻繁に使われるアクションを、名前の分かりやすい1回のツール呼び出しで済むようにし、まれな操作にはより多くの手間を許容します。

ツール設計の原則

エージェントが実際に呼び出すツールの形を決めます。Rekor のデフォルト設定ではすでにこれらが実装されています。問題が起きるのは、ツールを再び広げてしまう場合です。そのため、以下の各ルールでは、何を追加しないかを説明します。緩い仕様のコストを負うのは、トークンを扱う可能性のある最も能力の低いモデルです。オプションのパラメーターには、モデルが架空のプレースホルダー(null、none、sem_filtro、.*)を入力する可能性があります。それが実際のフィルターとして解釈されると、何も一致せず、エラーではなく「結果なし」として返され、再試行のループを引き起こします。

  1. ツールはエンドポイントではなく、意図を表します。 find_patient_by_phone や book_appointment のように目的に沿った名前を付け、1つの質問だけに答えるようにします。何かを検索する方法が2つあるなら、2つの Action にします。2つのオプションのフィルターを持つ1つのツールにはしません。
  2. 仕組みは隠します。 filter、sort、limit、offset、fields はデフォルトで公開しません。ツールの inputSchema は純粋に意味だけを表すものにします。エージェントが本当に操作する必要がある場合に限り、expose_<param>: true を設定して公開し、その代わりに default_limit/default_fields を設定してサーバー側で決定します。
  3. 宣言したパラメーターは必須です。任意にするなら、その理由を明確にします。 filterable_fields の項目はツールが答える質問なので、デフォルトでは必須です。本当に絞り込みに使うフィルターには optional: true を追加します。ツールにそのような項目がいくつも増えてきたら、それは意図ごとに分割すべきサインです。(範囲フィールドは上下限の両方を必須にはできないため、常にオプションです。)
  4. 離散値を取る文字列パラメーターには、すべて制約を設けます。 enum(候補の集合から選ぶ形式。書き込み時にも検証されるよう、record_type スキーマで宣言するのが最適です)または pattern(^\+[1-9][0-9]{6,14}$ など、1つの有効な形式)を設定します。制約のないオプションの文字列フィルターは、架空の値が入り込む原因になります。
  5. エージェントに判断させるべきでないことは、サーバー側で注入します。 base_filter は読み取り可能な範囲を制限し、precondition は状態に依存する書き込みをユーザーに見えない形でガードし、writable_fields は書き込み可能な項目を制限し、external_source/bindings はルーティングを行います。これらはいずれも、エージェントに公開するパラメーターではありません。
  6. 拒否のメッセージで、次の操作を示します。 エラーメッセージは復旧のための手段です(MCP クライアントは error.details を破棄するため)。そのため、パラメーター名と修正方法を示す必要があります。不正な値をフィルターに変換して0件の結果を返すのではなく、明確なエラーにするべき理由はここにあります。

逆のルール: 分割する基準は、組み合わせの数ではなく、意図です。明確な名前を付けた3つのツールは、5つのパラメーターを持つ1つのツールより優れています。よく似た15個のバリエーションは、ツールの選択精度も下がるため、どちらよりも劣ります。

レシピ:原則 → それを実現する機能

上記の原則はエージェント層に関するもので、バックエンドに依存しません。以下は、それらを実装する具体的なツールセットの設定項目です。つまり、意図を実装に結び付けるための対応表です。各設定項目の詳細は、上記のツールセットのセクションをご覧ください。

  • 1つのツール=1つの意図。ツールの公開範囲を整える — 操作ごとに異なるnamesを指定します(names: { "list": "search_invoices" })。同じrecord_typeに対する2つのツールでも同様です。また、filterable_fieldsリストを厳選します。
  • 機構(filter / sort / limit / offset / fields) — デフォルトでは非表示です。expose_<param>: trueで個別に再公開し、default_*で非表示のまま適用されるサーバー側の値を設定します。
  • フィルターを任意にする — filterable_fields[].optional: trueを指定します(宣言されたフィールドはデフォルトで必須です。rangeフィールドの上下限はもともと任意であり、optional: falseを指定すると拒否されます)。
  • 選択肢を限定する — filterable_fields[].enum、またはrecord_typeスキーマのフィールドにenumを指定します(こちらが推奨されます。書き込み時にも値が検証され、フィルターパラメーターにも反映されます)。
  • 構造化されたIDやコードを制約する — filterable_fields[].patternを指定します(例:^pat-[0-9]+$)。ツールスキーマに公開され、実行時にも適用されます。
  • 値を必須にする — 自動で適用されます。宣言されたfilterable_fieldsの項目は、optional: trueを指定しない限り必須です(rangeフィールドの2つの境界値は常に任意です)。必須パラメーターでは空欄や空の選択入力が拒否されるため、モデルは""や[]で要件を満たしたように見せかけることはできません。
  • 明確で実行可能なエラーを返し、黙って失敗しない — 書き込みフィールドではx-fkを使用します。読み取りパラメーターでは、空の値やenum/patternに反する値を拒否します(読み取り/書き込み間の一貫性)。
  • エージェントに表示するフィルターなしで、ツールの対象を絞る — list Actionのbase_filterを使用します(非表示で、常に適用されます)。
  • ツールの公開範囲がこれらの原則に沿っているか確認する — rekor pushはツール設計に関する警告を表示します(すべてのフィルターが必須である、1つのツールに複数の任意フィルターがある、制約のない文字列フィルターがある、型指定されたパラメーターと併せて生のfilterによる回避手段が残されている、など)。警告のみであり、pushが阻止されることはありません。
  • 状態に依存する書き込みを原子的かつ競合なく行う — preconditionを指定したcreate/updateツールを使用します(比較して設定する方式です。エージェントには非表示で、競合時には409を返します)。
  • エージェントを適切な値へ誘導する — filterable_fields[].descriptionでは、フィールドの種類、取得元、使用する場面を明記します。実際のデータ値ではなく、プレースホルダーの形式を使用してください。

注意点: enumがあると、エージェントは値を「選ぶ」よう促されます。常に入力すべき必須パラメーターには適していますが、通常は省略すべきoptional: trueのパラメーターには適しません(選択肢が固定されていると、省略ではなく選択を促してしまいます)。任意のフィルターにはpattern(または通常の自由入力パラメーター)を優先してください。さらによいのは、そのフィールドにenumが必要なほど重要なら、それが本当にツールの意図であり、必須にすべきではないか検討することです。

ベストプラクティス

  • 冪等なアップサートには外部 ID を使用する — リトライに安全で、重複も発生しません。
  • コンテキストごとに 1 つのベースを使用する — データを分離できます(テスト実行ごと、エージェントごと、環境ごと)。
  • スキーマ変更にはプレビューを使用する — プレビュー用ベースで record_types、トリガー、受信 Webhook を変更します。人間に昇格を依頼してください。
  • アトミック性を確保するにはバッチ処理を使用する — 複数の書き込みをすべて成功または失敗させる必要がある場合に使用します。
  • ネストされたデータよりリレーションシップを優先する — 埋め込む代わりにレコードをリンクします。トラバーサルと柔軟なクエリが可能になります。
  • 大容量またはバイナリのコンテンツにはファイルを使用する — レコードデータとリレーションシップのメタデータは構造化 JSON 用で、サイズは約 1 MiB までです。base64 の塊をインラインで埋め込むことは拒否されます。PDF、画像、その他のバイナリコンテンツは ファイル(rekor files put <file_type> <path> --file <local>)として保存してレコードにリンクするか、レコード単位のシンプルな添付ファイル(rekor attachments upload …)として保存してください。
  • まずスキーマを定義する — レコードを書き込む前に record_type のスキーマを定義します。検証によって不正なデータを早期に検出できます。
  • 書き込み後のクエリには遅延を見込む — 単一レコードの読み取り(records get、relationships get)には書き込みがすぐに反映されますが、sql、records query、query-relationships、search への反映には少し時間がかかることがあります。書き込み直後にクエリを実行する必要がある場合は、少し待つか、直接取得を使用してください。
  • トークンの有効期限を設定する — 有効期間の短いトークンには --expires-at を使用します。使用しないトークンは速やかに失効させてください。
  • トークンはすぐに保存する — 生のトークンが表示されるのは作成時の 1 回だけです。ターミナルを閉じる前に安全に保管してください。

コメント