手形 (Tegata)
手形 (Tegata) は、Ninka で認可を定義するための宣言的な仕様書です。1 つの手形ファイルが 1 つの認可ポリシーを表し、「誰が、どのリソースに対して、何を、どの条件で行えるか」を記述します。
認可の意図をアプリケーション内の if 文や生成コードへ散らすのではなく、人間が一つの仕様としてレビューできる形にするためのものです。
手形そのものを実行するわけではありません。Ninka は手形の canonical な認可内容を Rego へ決定論的にコンパイルし、その Rego から固定された OPA toolchain が実行用の WASM を build します。ランタイムが評価するのは、この WASM です。
手形の例
{
"tegata": "0.1",
"policy": {
"id": "invoice-access",
"description": "請求書の閲覧・削除・承認"
},
"rules": [
{
"id": "allow-employee-view-own-invoice",
"effect": "allow",
"subject": { "roles": ["employee"] },
"actions": ["view"],
"resource": { "type": "invoice" },
"relationships": [
{
"label": "own_submission",
"subject_attribute": "user_id",
"op": "eq",
"resource_attribute": "submitted_by"
}
]
},
{
"id": "allow-manager-approve-invoice-within-limit",
"effect": "allow",
"subject": { "roles": ["manager"] },
"actions": ["approve"],
"resource": { "type": "invoice" },
"conditions": [
{ "key": "resource.amount", "op": "lte", "value": 500000 }
]
}
]
}
最初のルールは「employee は、自分が提出した invoice を view できる」、2 つ目は「manager は、金額が 50 万円以下の invoice を approve できる」と読めます。
評価規則は設定で変更できません。1 つのルール内の制約は AND、同じ effect のルール同士は OR で組み合わされ、deny は allow に優先します。どの allow にも一致しなければ deny です。正確なフィールド定義と評価規則は 手形スキーマ を参照してください。
人でも AI でも、レビューする仕様は手形
手形は人が書いても、AI エージェントが提案しても構いません。誰が書いた場合でも、責任の境界は同じです。
- 書き手が要件を手形へ落とし込む
- 関所 (Sekisho) が、Ninka に機械的に確認できる構造上・意味上の規則を検査する
- 人間が、その手形が意図した認可要件を正しく表しているかをレビューする
- toolchain が、受け入れた仕様を実行成果物へ変換する
Ninka は「人間が承認した」というフラグをローカルに保持しません。また、元の業務要件そのものが正しいと保証することもありません。人間による受け入れは、プルリクエストのレビューなど、開発・変更管理のプロセス側で行います。詳しくは 認可をレビューする を参照してください。
tegata_hash が識別するのは認可仕様
tegata_hash は、コンパイルに使われる canonical な認可内容を識別します。
ハッシュを計算する前に、Ninka は認可の意味に影響しないレビュー用メタデータを除外し、意味を持たない並び順を正規化します。たとえば policy.description だけを変えてもハッシュは変わりません。一方、canonical なルールの内容を変えればハッシュも変わります。
tegata_hash は、人間がポリシーを承認したことの証明ではありません。また、生成された Rego や WASM のハッシュでもありません。生成されたバイト列には、それぞれ別のハッシュがあります。
手形の認可仕様 → tegata_hash
Rego のバイト列 → rego_sha256
WASM のバイト列 → wasm_sha256
この違いについては 認可コンパイラ と 生成ファイル を参照してください。
audit.ambiguities で解釈を見える形にする
自然言語の要件には、複数の解釈があり得ます。たとえば「マネージャーは 50 万円以内の請求書を承認できる」という要件では、50 万円ちょうどを含むかどうかを決める必要があります。
audit.ambiguities は、こうした解釈上の判断をレビューする人へ明示するための場所です。
"audit": {
"ambiguities": [
{
"code": "assumed_interpretation",
"message": "「50万円以内」を resource.amount lte 500000(整数・JPY)と解釈した。境界値50万円ちょうどは承認可に含む。含まない意図なら lt に変更が必要。",
"related_rules": ["allow-manager-approve-invoice-within-limit"]
}
]
}
曖昧な自然言語要件を手形へ構造化する authoring tool には、行った解釈を canonical なルールへ黙って埋め込むのではなく、レビューできる形で報告することが仕様上求められます。
audit ブロックはレビュー用の情報であり、認可判定の意味には含まれません。tegata_hash からも除外され、生成される判定ロジックにも影響しません。利用できる ambiguity code と正確な制約は 手形スキーマ を参照してください。