メインコンテンツまでスキップ

Ninka 0.6.0 へのアップグレード

0.6.0 では、プロジェクトから観測できる変更が 11 件あります。すべてのプロジェクトに作業が必要で、 その作業には順序があります。workspace を移動しないと rebuild できず、rebuild しないと生成された consumer コードは意味を持ちません。

端末を開いて、このページを上から順に辿ってください。各ステップには、実行するコマンド・成功時に何が 出るか・前のステップを飛ばすと何が出るかを書いてあります。

始める前に、アップグレードを専用の branch に載せてください。ステップ 2 は workspace の生成ファイルを すべて書き換えるので、その diff は読める形にしておく価値があります。

git switch -c upgrade-ninka-0.6
npm install ninka-authz@0.6.0 # または: npm install -D ninka-authz@0.6.0

.NET プロジェクトは Ninka.Authz の package reference も 0.6.0 に更新します。runtime と成果物は 一緒に動きます。0.6.0 の runtime は 0.5.x の CLI が作った成果物を拒否し、0.5.x の runtime は 0.6.0 の CLI が作った成果物を拒否します。半分だけアップグレードした配備が動く期間はありません。


ステップ 1:workspace を ninka/ に改名する

mv authz ninka
git add -A

fallback も移行期間もありません。これを行うまで、すべてのコマンドは何も読まずに停止します:

error: Ninka workspace moved from ./authz to ./ninka.

Rename it with:

mv authz ninka

Or keep the current location with: --workspace authz

どうしてもディレクトリを移動できない場合は、毎回の実行で --workspace authz を渡します。ただし これで何が得られるかは正確に把握してください、変わるのは Ninka がどこを見るかだけで、それ以外は 何も変わりません。authz/ に置いたままの workspace は、ステップ 2 を行うまで以下のすべてで失敗し 続けます。

確認:

npx ninka verify

workspace のエラーを抜けて、成果物についての指摘に進むはずです。それが次のステップです。次のような 出力になります:

✔ ninka/invoice-access.tegata.json → invoice-access (tegata_hash c2b55b92fb53…)
✘ bundle-0001: no execution bundle is committed (ninka/out/bundles/bundle-0001.build.json is
missing) and this toolchain can build one — run `ninka build` and commit ninka/out/bundles/
✘ the committed artifacts are not the set ninka/ compiles to — 7 artifacts nothing in this
workspace accounts for: …

ステップ 2:成果物を rebuild する

ここで Artifact Contract v2 と新しい Rego entrypoint を吸収します。コマンドは 1 つです:

npx ninka build

build は pin された opa toolchain を必須とし、利用できなければ失敗します。それが buildcompile の違いであり、ここで欲しい挙動です。

✔ ninka/invoice-access.tegata.json → invoice-access (tegata_hash c2b55b92fb53…)
wrote ninka/out/
✔ ninka/out/bundles/bundle-0001.wasm (1 entrypoints)
✔ validation: invoice-access (51 vectors, wasm agrees with the reference evaluator)
− removed 5 v1 artifacts (superseded by policies/ and bundles/): invoice-access.build.json,
invoice-access.manifest.json, invoice-access.rego, invoice-access.validation.json,
invoice-access.wasm
✔ lib/generated/ninka.ts (1 policy)

ninka/out/ 以下のレイアウトが変わっています:

before (0.5.x) after (0.6.0)
authz/out/invoice-access.rego ninka/out/policies/invoice-access.rego
authz/out/invoice-access.manifest.json ninka/out/policies/invoice-access.manifest.json
authz/out/invoice-access.validation.json ninka/out/policies/invoice-access.validation.json
authz/out/invoice-access.build.json ninka/out/bundles/bundle-0001.build.json
authz/out/invoice-access.wasm ninka/out/bundles/bundle-0001.wasm
authz/out/input-contract.json ninka/out/input-contract.json

Rego の中身も動いています: package ninka.invoice_accesspackage ninka.p_<sha256(policy.id)> になり、manifest の entrypoint は ninka/p_5bb69feb…/allow に なりました。アプリケーション側がこれらを名指しすることはありませんが、外部の opa eval・bundle を 検査するスクリプト・package path をキーにしたダッシュボードは名指ししています。再生成された manifest の値で更新してください。

このステップについて知っておくべきことが 3 つあります。

build は v1 の成果物は消すが、生成された型ファイルは消さない

types.gen.tstypes.gen.cs はステップ 2 を生き残るので、手で削除する必要があります。それが ステップ 3 です。削除するまで、build が成功していても verify は赤のままです。

値を保存できない数値は build を止めるようになった

Tegata が ±2^53 を超える整数を含む場合、build は停止します。0.5.x は exit 0 でコンパイルし、 異なる数値を Rego に出力していました:

error: ninka/invoice-access.tegata.json states a number the compiler cannot carry losslessly:
line 72, column 59: the Tegata states 9007199254740993, but the compiler holds 9007199254740992
and would ship 9007199254740992 into the Rego
The value you reviewed and the value that would execute are different numbers. State a value the
compiler carries exactly — every integer up to 9007199254740992 in magnitude is carried exactly —
or express the quantity in a coarser unit.

Tegata を直してください。compiler が正確に保持できる値を書くか、より粗い単位で表現します (円 → 千円、バイト → KiB)。その後 build を再実行します。

opa が拒否した policy set は、build の失敗になった

pin された opa toolchain が実行された上で policy set を拒否した場合、build(および compile)は exit 1 になり、opa 自身の出力をそのまま表示します:

error: opa v0.65.0 refused this policy set:
error: load error: 3 errors occurred during loading:
invoice-access.rego:191: rego_parse_error: var cannot be used for rule name
invoice-access.rego:191: rego_parse_error: var cannot be used for rule name
invoice-access.rego:191: rego_parse_error: negated expressions cannot be used for rule head
the Rego above is generated from your Tegata, so a refusal here is normally a Ninka defect — report it with the message above.
ninka/out/ still holds the Rego, the manifests and the types; no execution bundle was published.

0.5.x では、同じ拒否が exit 0 の 1 行になっていました:

note: WASM build skipped — Command failed: <the opa command line>

これは breaking です。プロジェクト側を何も変えていなくても、Ninka を上げただけで緑だった pipeline が赤になり得ます。同時に、これは機能の後退ではありません。 旧来の exit 0 は、 bundle を 1 つも生成できなかった build を成功として報告していました。workspace には .wasmbuild.json も残らないまま、CI にも pre-commit hook にも、policy を書いた agent にも「build は 通った」と伝えていたということです。0.6.0 は「toolchain が Ninka の生成物を拒否した」と「toolchain が 入っていない」を畳むのをやめました。回復可能なのは後者だけであり、soft path を通るのも後者だけです。 opa の無いマシンでの compile は、Sekisho チェック・Rego・manifest を書いたうえで note: WASM build skipped を出して exit 0 のままですし、そのマシンでの build は exit 1 のままです。 これは 0.5.x と同じ挙動です。

Rego はあなたの Tegata から生成されたものなので、ここでの拒否は通常あなたの policy の問題ではなく Ninka の defect です。上記のメッセージを添えて報告してください。

build を呼ぶスクリプトを確認してください。 0.5.x では許容されていた 2 つの書き方が、失敗に 気づけるかどうかを決めるようになります:

grep -rn "ninka build\|ninka compile" package.json Makefile .github/workflows/ scripts/ 2>/dev/null
  • exit status を無視している。 npx ninka build || true の形、set +e の区間、出力の最終行だけを 読む wrapper は、本物の失敗を捨てるようになります。結果は exit status です。
  • status ではなく bundle の存在で判定している。 失敗した build は、すでにコミットされているものを 消しません。上記の拒否のあとも ninka/out/bundles/bundle-0001.wasm はディスク上に残り、実行前に コミットされていたものと byte 単位で同一です。test -f ninka/out/bundles/*.wasm で後段を判定して いると、bundle があるので処理は進みます。前の build の module を使って。判定は、それを生成する はずだったコマンドの exit status で行ってください。

同じ規則が、そもそも実行できない opa にも及ぶようになりました。 build は toolchain を 解決できない場合には以前から exit 1 でした。未対応のプラットフォーム、ダウンロードの失敗、 存在しないファイルを指す NINKA_OPA_PATH。覆われていなかったのは、解決には成功したうえで なお実行できない場合です。存在するが実行できないファイル(mode が違う、ディレクトリ、 プログラムではないもの)を NINKA_OPA_PATH が指していると、その検査を素通りして compile の soft path に乗り、buildnote: WASM build skipped を出して bundle が無いまま exit 0 で 終わっていました。0.6.0 ではここも exit 1 になります:

error: the opa NINKA_OPA_PATH names (/opt/toolchain/opa) could not be run: spawnSync /opt/toolchain/opa EACCES
`build` publishes an execution bundle, so a toolchain it cannot run is a failed build — `compile` is the command that writes everything that does not need opa.
ninka/out/ still holds the Rego, the manifests and the types; no execution bundle was published.

compile は変わりません。プロセスは走っていないので、これは今も「toolchain が利用不可」であり、 回復可能な側のままです。compile は Sekisho チェック・Rego・manifest を書き、note: を出して exit 0 で終わります。変わったのは、bundle を publish せずに exit 0 で終わらない という build の約束を、 path の pre-flight ではなく結果の側で守るようになったことです。

CI で NINKA_OPA_PATH を設定しているなら、この変更はその値が誤っていることを伝えます。 binary を移動した container image、read-only で mount されたパス、実行ビットを失ったまま復元された cache、いずれもこれまでは build が緑になり、.wasm は生成されませんでした。ここでのエラーは、 どちらの経路で binary が選ばれたかをそのまま名指します。指定したときは the opa NINKA_OPA_PATH names (…)、pin されたものを使ったときは opa v0.65.0。この flag の先の binary はあなたのものであり、Ninka はそれを probe も checksum もしないからです。


ステップ 3:旧・生成型ファイルを削除し、TypeScript の consumer コードを移す

3a. types.gen.* を削除する

rm -f ninka/out/types.gen.ts ninka/out/types.gen.cs

これらを書くものはもう存在せず、ステップ 2 も消してくれません。ninka/out/ は厳密な集合になりました。 compile が生成しないものがそこにあれば、それは指摘対象です。残したままだと、build が成功していても verify は赤のままです:

✘ the committed artifacts are not the set ninka/ compiles to — 2 artifacts nothing in this
workspace accounts for:
ninka/out/types.gen.ts is not something a compile of ninka/ writes — everything under
ninka/out is generated, so nothing accounts for it. Delete it, or keep it outside the
generated tree

3b. 何がそれに依存していたかを探す

grep -rn "types\.gen" --include='*.ts' --include='*.tsx' . | grep -v node_modules
grep -rnE 'policies\.[a-zA-Z]' --include='*.ts' --include='*.tsx' . | grep -v node_modules

0.5.x のプロジェクトでは、変更が必要な 2 つの形が見つかります:

lib/authz.ts:5:import type { PolicyRef } from "../authz/out/types.gen";
lib/authz.ts:28:export { policies } from "../authz/out/types.gen";
app/api/invoices/route.ts:13: const allowed = await check(policies.invoiceAccess, {

3c. import と呼び出し箇所を書き換える

ステップ 2 はすでに Consumer Projection を書いています。ファイル 1 つ、既定では <source root>/generated/ninka.ts、export される名前はちょうど 2 つ(createNinkapolicies)です。 実行 bundle をファイル内に抱えているので、それを import することが統合のすべてです。

// before — 0.5.x
import { check, policies } from "@/lib/authz";
const allowed = await check(policies.invoiceAccess, input);

// after — 0.6.0
import { createNinka, policies } from "@/generated/ninka";
const authz = await createNinka();
const allowed = authz.check(policies["invoice-access"], input);

変更は 2 つあり、互いに独立しています:

  • composition root は createNinka() 0.5.x では ninka init が runtime を配線する手書きの lib/authz.ts を scaffold していました。あの stub はもう生成されず、必要でもありません。projection そのものが統合点です。独自のロギング・リクエストコンテキスト・エラーハンドリングを入れた lib/authz.ts を持っているなら、それは残してください。createNinka() を一度呼んで re-export する 薄い wrapper にし、あなたのコードとして保守します。
  • 0.6.0はpolicy idを厳密に指定する形にした。 policies.invoiceAccesspolicies["invoice-access"] になった。0.6.0の時点でpolicy idはデータのままで識別子には変換されず、camelCaseの形はその版には 存在しなかった。この形は0.8.0で再び変わる。 導出した参照名(今回は衝突を検査する)が戻ってくる ので、最新版まで一気に上げるなら、この手順を終えたあと 0.8.0へのアップグレード へ進んでほしい。この0.6.0の形で止まらないこと。

policies から取らずに手で組み立てた ref は拒否されます:

ninka: policy ref for "invoice-access" carries no tegata_hash — it cannot be bound to the loaded
bundle. Pass the policies.<name> reference your generated Ninka projection exposes for
"invoice-access"

3d. projection をコミットする

git add lib/generated/ninka.ts # source root の場所に合わせてください

生成物ですが、あなたの source です。アプリケーションが import するものであり、verify が比較する 対象でもあります。リポジトリの他のファイルと同じようにコミットしてください。

Ninka が想定と違う場所に projection を書いた場合、あるいは書き先を決められず拒否した場合は、 今すぐステップ 6 に進んでください、path 解決の規則は compilebuildverify で同じなので、 一度で片付けるほうが簡単です。


ステップ 4:C#: --out-csharp で再生成する

--lang csharp は撤去され、types.gen.cs は成果物集合の一部ではなくなりました。C# の Consumer Projection は、あなたが指定した場所に書かれます。C# には解決の基準になる source root の規約が ないからです:

npx ninka build --out-csharp Generated/Ninka.g.cs
✔ ninka/out/bundles/bundle-0001.wasm (1 entrypoints)
✔ validation: invoice-access (51 vectors, wasm agrees with the reference evaluator)
✔ lib/generated/ninka.ts (1 policy)
✔ Generated/Ninka.g.cs (1 policy)

旧フラグはそのまま拒否されます:

$ npx ninka build --lang csharp
error: build does not accept "--lang" (usage: ninka build [--out <file>] [--out-csharp <file>])

続いて C# の呼び出し箇所を更新します:

// before — 0.5.x
var authz = await Authz.Load("authz/out");
var allowed = authz.Check(Policies.InvoiceAccess, new InvoiceAccessInput { … });

// after — 0.6.0
var authz = NinkaProjection.Create();
var allowed = authz.Check(InvoiceAccessInput.Policy, new InvoiceAccessInput { … });
  • NinkaProjection.Create()Authz.Load(...) を置き換えます。projection が抱えている bundle で Authz.FromEmbedded(...) を呼ぶので、配備すべきディレクトリはありません。
  • 0.6.0はPolicies.<Name>を無くした。 policy refはinput contract上に移り、<Name>Input.Policyに なった。0.8.0で再び移る。 生成されたPolicies.<Name>containerへ戻るので、0.6.0より先のバージョン へ上げるなら 0.8.0へのアップグレード を参照してほしい。
  • input contract の型名は i_<hash> で、名前が衝突しない限り global using の PascalCase alias が 併せて生成されます。つまり InvoiceAccessInput はそのまま使え、衝突する policy 群には alias が 付かず i_<hash> で直接指定します。alias は糖衣で、名前の本体は hash です。

Generated/Ninka.g.cs は TypeScript の projection と並べてコミットします。


ステップ 5:runtime の取得経路を確認する

bundle を runtime に渡す方法は 2 つあり、0.6.0 はどちらが既定の経路かを変えました:

embedded(通常の経路)。 createNinka() / NinkaProjection.Create() は projection ファイルに コンパイル済みで埋め込まれた bundle を使います。ディスクからは何も読まず、配備するディレクトリも、 設定する path もありません。ステップ 3・4 で projection に移ったなら、ここは完了です。 ステップ 6 へ進んでください。

directory(引き続きサポート、ただし任意)。 Ninka.load(dir) / Authz.Load(dir) は配備された 成果物ディレクトリを読みます。変わったのは 2 点です:

  • 既定値authz/out から ninka/out になったので、引数なしの load() は別の場所を見ます;
  • dirあなたが配備する任意のファイルシステム path です。ninka/out は既定値であって、runtime が 要求する場所ではありません。配備先が /srv/app/authz なら、それを渡してください。

引数なしの load()"authz/out" を使っているなら、配備が実際に作る path を明示的に決めて渡して ください。

確認。配備した成果物に runtime を向けて読み込みます。v1 の成果物集合は拒否され、その旨を 述べます:

ninka: <dir> holds artifact v1 build files (invoice-access.build.json) but no execution bundle in
<dir>/bundles. Recompile the artifacts with the current Ninka (`npx ninka build`)

ステップ 2 のあとにこれが出るなら、配備が古い成果物を運んでいます。旧ディレクトリを拾っている コピー処理を探してください。


ステップ 6:CI に、プロジェクトが compile するのと同じ引数を渡す

プロジェクト側を何も変えていないのに pipeline が赤くなる可能性が最も高いステップなので、 意識的に行ってください。

ninka verify は、正典の成果物から各 Consumer Projection を再生成し、byte 単位で比較するように なりました。そのためにはどのファイルと比較するのかを知る必要がありますが、verifycompile が 何をしたかを記憶していません。自力で path を解決できる場合はしますし、できない場合は拒否します:

✘ cannot tell where the Consumer Projection belongs: /path/to/project has src/ and lib/, and no
tsconfig.json "rootDir" to choose between them. — pass the same --out this project compiles with

src/lib/ が並んでいて rootDir が無いのは、TypeScript のごく普通のレイアウトです。 何も変えていないプロジェクトがアップグレードだけでこれに当たり得ますし、今まで当たらなかった プロジェクトも、誰かが 2 つ目のトップレベルディレクトリを追加した日から当たり始めます。

これが何であるかをはっきりさせておきます: 0.5.x の verify は projection を一切検査して いませんでした。同じプロジェクトで exit 0 になり、出力に projection の行は 1 行もありません。 以前は検査に通っていたのではなく、検査していなかったということです。0.6.0 は、アプリケーションが 実際に import する生成ファイルまで検証範囲を広げました。その代償として、どのファイルを見ればよいかを 述べない invocation を成功として扱えなくなったのです。

規則: compile に渡すのと同じ --out / --out-csharpverify にも渡す。

# CI
- run: npx ninka build --out src/generated/ninka.ts --out-csharp Generated/Ninka.g.cs
- run: npx ninka verify --out src/generated/ninka.ts --out-csharp Generated/Ninka.g.cs

緑はこう見えます:

✔ invoice-access: match (tegata_hash c2b55b92fb53…)
✔ src/generated/ninka.ts: Consumer Projection matches (1 policy)
✔ Generated/Ninka.g.cs: Consumer Projection matches (1 policy)
verify: all artifacts match

source root が一意に決まるプロジェクトなら、引数なしの verify がそれを解決するのでフラグは不要です:

✔ lib/generated/ninka.ts: Consumer Projection matches (1 policy)
verify: all artifacts match

手で確認しておく価値のある罠が 2 つあります:

  • --out は記憶されません。 渡されたその 1 回の実行にだけ効きます。既定でない path に compile した あとで引数なしの verify を実行すると、path は最初から解決し直されます。つまり既定の path を 見るか、上記のように拒否するかであって、先の compile が書いたファイルを見つけには行きません。 compile に渡したものは verify にも渡します。
  • C# の projection は --out-csharp を渡したときだけ検査されます。 C# のみの workspace で 引数なしの verify は exit 0 になり、Generated/Ninka.g.cs には一切触れません。 − no TypeScript Consumer Projection to check と出して、そこで終わります。引数なしの verify が 緑であることは、C# projection が最新であることの根拠になりません。 CI の行に --out-csharp を 入れてください。

ステップ 7:wrapper スクリプトから未知の引数を取り除く

未知の引数は、以前は無視されていました。今は exit 2 で拒否されます:

$ npx ninka verify foo
error: verify does not accept "foo" (usage: ninka verify [--out <file>] [--out-csharp <file>])

これは、タイプミス・古いバージョンの名残のフラグ・別コマンド向けの引数を捕まえます。0.5.x では いずれも黙って何もせず、CI を通っていたものです。

確認。リポジトリ内の Ninka 呼び出しを一度ずつ実行し、出力を読んでください:

grep -rn "ninka " package.json Makefile .github/workflows/ scripts/ 2>/dev/null

--lang csharp を使っているものはステップ 4 で扱います。


ステップ 8:Decision Log の consumer を前方互換にする

Decision Log を消費しているなら、このステップを読んでください。SIEM に送っている、テストで 突き合わせている、スキーマで検証している、といった場合です。していないなら飛ばして構いません。

Decision Log の契約は規範として明文化され、そのうち 1 つの条項が consumer に新しいことを求めます:

C8。consumer は、契約が名前を挙げていない field を許容しなければならず(MUST)、知らない field を 持っていることを理由に entry を拒否または破棄してはならない(MUST NOT)。entry の field 集合は 閉じていない。

0.6.0 は新しい field を 1 つも出しません。 wire format も変わっていません。これは今日failure として 観測できる移行ではなく、将来のリリースが field を追加してもあなたが壊れないようにするための契約です。 リリースノートが目の前にある今のうちに済ませてください。

consumer の次の点を確認してください:

  • 閉じた/厳格なスキーマ(additionalProperties: false、Zod の .strict()、.NET で [JsonExtensionData] を持たない strict deserialization);
  • field 集合に対する網羅的な match;
  • 認識できないキーを、運ぶべきデータではなくエラーとして扱っている箇所。

これらを緩めてください。認識できないものは無視し、entry を拒否しないことです。

ついでに: マスキングについて

規則そのものは変わっていませんが、半分だけ書き留めてしまいやすい部分です。Decision Log の値は raw でない限りマスクされraw の源は 2 つあります:

  1. vocabulary.jsondecision_log.unmasked に列挙された属性;
  2. action.nameresource.type:これらは常に raw です。呼び出し箇所のリテラルであって 実行時データではないからです。decision_log.unmasked にこれらを列挙するとエラーになります。

挙動が 1 つ変わっており、それはログの本文を変えます: subject.propertiesresource.properties が 属性マップではなくスカラー(文字列・数値・真偽値)を保持していた場合、0.5.x はそれをマスクせずに 書き出していました。今はマスクされます:

0.5.x {"subject":{"properties":"ssn-123-45-6789"}, …}
0.6.0 {"subject":{"properties":"***"}, …}

これらの入力形について旧来のログ本文を前提にしたアサーションや下流パーサがあれば、更新してください。 判定(decision)には影響しません。


ステップ 9:ninka docs -o の path 前提を更新する

静的な Authorization Reference を公開していて、かつ pipeline のどこかが export の内部 path を 知っている場合以外は、このステップを飛ばして構いません。

この export は policy ごとに 1 module を書かなくなり、bundle ごとに 1 module を書きます:

0.5.x 0.6.0
policies/document-access.a9741ad21c7a.wasm bundles/bundle-0001.2d5ba8a5d58e.wasm
policies/member-management.dda2e807906f.wasm
policies/project-access.446fa6cfe3bb.wasm

export したディレクトリを静的ホストにコピーしているだけなら、何も変わりません。 index.html は 両バージョンで同一、その中の href はすべて相対、snapshot ディレクトリ名も YYYYMMDD-HHmmss のままです。 次で確認できます:

npx ninka docs -o ./reference
find ./reference -type f
./reference/20260818-061146/index.html
./reference/20260818-061146/data/reference.json
./reference/20260818-061146/assets/app.css
./reference/20260818-061146/assets/app.js
./reference/20260818-061146/bundles/bundle-0001.726e7d8b5870.wasm

変更が要るのは、次のいずれかがある場合だけです:

  • policies/*.wasm に一致する CDN ルール・キャッシュヘッダのルール・アップロード許可リスト・path の 書き換え、bundles/*.wasm に合わせてください;
  • 特定 policy の module への deep link:policy ごとの module はもう存在しません;
  • data/reference.json を自分で読むコード:wasmHrefpolicies[].wasmHref から bundles[].wasmHref に移り、top-level に bundles 配列が追加されました。

空の -o は拒否されます

-o "" はこれまで受け付けられていましたが、その意味は「ディレクトリの指定なし」ではありません。 空文字はカレントディレクトリに解決されるため、snapshot はプロジェクトのルート、つまりソースの隣、リポジトリの中へ 書き出されていました。同じ意図を --output= や裸の -o と書いた場合は 拒否されていました。0.6.0 ではどの綴りの空値も同じく拒否し、exit 2 になります:

error: -o requires a directory to export into (`-o .` for the project root)

失われるものはありません。プロジェクトのルートは path であり、名指せるからです。 ninka docs -o . は同じ YYYYMMDD-HHmmss ディレクトリを同じ場所に書きます。

ディレクトリを変数経由で渡しているスクリプトを確認してください。 REFERENCE_DIR が未設定のままの npx ninka docs -o "$REFERENCE_DIR" は、リポジトリの中へ 書き出したうえで成功を報告していました。今は usage error で止まります。

snapshot の version field は改名され、値は変わっていない

snapshot のメタデータで、artifact_format_versionsnapshot_format_version になり、値は 1 の ままです

これはキーの改名であって、version の bump ではありません。 旧い名前は、別の契約の名前(0.6.0 で別途 version 2 になっている artifact format の名前)を、 export snapshot 自身の format に 流用したものでした。両者は独立した version 系列であり、snapshot format 自体は変わっていないので、 その version は自分の名前のもとで 1 のままです。

data/reference.json をパースしているなら snapshot.snapshot_format_version を読んでください。 そこで artifact_format_version === 1 をアサートしていたのなら、そのアサーションはもともと artifact format についてのものではありませんでした。


ステップ 10:rebuild し、verify し、テストを走らせる

npx ninka build --out <your projection path> [--out-csharp <your C# projection path>]
npx ninka verify --out <your projection path> [--out-csharp <your C# projection path>]
✔ invoice-access: match (tegata_hash c2b55b92fb53…)
✔ lib/generated/ninka.ts: Consumer Projection matches (1 policy)
✔ Generated/Ninka.g.cs: Consumer Projection matches (1 policy)
verify: all artifacts match

続いてアプリケーション自身のテストを走らせ、このアップグレードが動かす 2 つのカテゴリに注意して ください:

  • 認可の結果。 ステップ 2 が数値リテラルで停止したなら、policy の閾値はあなたが思っていた数値では なかったということであり、それを直せば判定が変わります。その policy を覆うテストを再実行してください。
  • Decision Log のアサーション。 スカラーの properties のログ本文を前提にしているものは更新が 必要です(ステップ 8)。

最後に、Ninka が生成したものをすべてコミットします:

git add ninka/ lib/generated/ninka.ts Generated/Ninka.g.cs
git status # 生成物が未追跡・変更のまま残っていないこと

build の後に git status が綺麗であることは、verify が CI で強制するのと同じ性質です。両者が 食い違うなら、CI のコマンドとローカルのコマンドに同じ引数が渡っていません。ステップ 6 に戻って ください。

関連項目

  • 0.8.0へのアップグレード:このページが導いた先から続く、次のアップグレード。参照構文が再び変わる。
  • CLI:フラグ・終了コード・Consumer Projection の書き先。
  • 生成ファイルninka/out/ 以下の各ファイルが何であるか。
  • 認可をテストするninka-authz verify が何を検査し、アプリケーション境界のテストがどこに属するか。