Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
d675902
chore(layer): extensions/zankyo の実行ビットを git 上でも揃える
seike460 Sep 28, 2026
6db56d9
chore(proxy): MSRV を依存の実要件 1.94.1 に合わせて CI で検証し、crates.io 公開を止める
seike460 Sep 28, 2026
5672ca0
chore(proxy): 未使用の依存 feature と ZankyoError の variant を削除
seike460 Sep 28, 2026
20d9327
refactor(proxy): 記録権の確保と上限での間引きを State::claim に集約
seike460 Sep 28, 2026
07a4e0f
fix(proxy): 空の ZANKYO_SSM_PARAM を未設定として扱い、設定検証のテストを補う
seike460 Sep 28, 2026
f6c4595
fix(proxy): 記録しない場合も external extension を登録し、SHUTDOWN まで待つ
seike460 Sep 28, 2026
cb5567e
fix(proxy): external extension 構成では子の終了後に grace 待ちをしない
seike460 Sep 28, 2026
d1a42ad
test(proxy): flush 予算テストの実時計依存に余裕を持たせる
seike460 Sep 28, 2026
3543a98
test(proxy): passthrough と spawn_via_proxy の fail-open 配線をテストする
seike460 Sep 28, 2026
02f36a6
docs(changelog): Unreleased に v0.1.0 以降の変更を記載
seike460 Sep 28, 2026
8a4f1ff
fix(proxy): Runtime API への全リクエストで出ていた info ログを debug に下げる
seike460 Sep 28, 2026
6a6a352
fix(proxy): Node.js ランタイムの trace を errorContext.stackTrace に取り込む
seike460 Sep 28, 2026
a2af0aa
fix(proxy): scrub で cookie と文字列化 JSON 内のフィールドもマスクする
seike460 Sep 28, 2026
5340e6d
refactor(proxy): コメントとログ文言を実装に合わせ、効かない記述を削る
seike460 Sep 28, 2026
bc420bf
test(proxy): 終了コードのシグナル写像と scrub の各パターンの置換結果を検証する
seike460 Sep 28, 2026
230c1a4
docs(changelog): Unreleased に scrub・ログ・スタックトレースの修正を追記
seike460 Sep 28, 2026
aa46453
test(proxy): 統合テストの spill dir を Drop で必ず消す
seike460 Sep 28, 2026
5cb5dcd
fix(proxy): spill の回収で dir を消さず、同時に走る書き込みの ENOENT を防ぐ
seike460 Sep 28, 2026
8c5a89c
fix(proxy): SSM 取得の既定タイムアウトを Init 上限の内側の 2 秒に下げる
seike460 Sep 28, 2026
2ea1b37
docs(proxy): FLUSH_BUDGET と PUT_TIMEOUT の説明を実際の動作に合わせる
seike460 Sep 28, 2026
6a9ca3e
refactor(proxy): store と spill の重複した書き込み処理と古い doc を整理する
seike460 Sep 28, 2026
7134a2b
test(proxy): SSE ヘッダと hop-by-hop 除去を本番の経路で検証する
seike460 Sep 28, 2026
8e0d928
fix(cli): キーと本文の関数名が食い違うレコードを invoke 先に使わない
seike460 Sep 28, 2026
7478e45
fix(construct): s3:PutObject の対象を関数ごとの zankyo/{関数名}/ に絞る
seike460 Sep 28, 2026
c1e9095
fix(cli): fixture --out の新しいファイルを mode 0600 で作る
seike460 Sep 28, 2026
4921a1c
refactor(cli): 使われていない region・canonicalize と重複した分岐を消す
seike460 Sep 28, 2026
5a147b4
docs(cli): exit code の JSDoc を実装に合わせる
seike460 Sep 28, 2026
72bd039
fix(cli,construct): npm の tarball に LICENSE と build 済みの dist を必ず含める
seike460 Sep 28, 2026
ffa62a2
docs(changelog): cli と construct の修正を [Unreleased] に追記する
seike460 Sep 28, 2026
e4c254f
test(cli): フェイクが受け取った入力を記録し、exit code と invoke 先を検証する
seike460 Sep 28, 2026
f64f704
fix(cli): list の走査上限を、除外後の件数ではなくページ数で数える
seike460 Sep 28, 2026
7a6efa4
fix(cli): 非 JSON イベントのレコードを replay・diff・redrive の invoke 前に exit 4 で止める
seike460 Sep 28, 2026
f72d727
chore(cli): npm の tarball から使われない d.ts と source map を外す
seike460 Sep 28, 2026
bd243c6
ci: build 後に CLI の bin(dist)を起動して確かめる
seike460 Sep 28, 2026
f2973e7
fix(construct): 既定の SAR アプリケーション ID をプレースホルダから公開中の ARN に直す
seike460 Sep 28, 2026
cdac353
fix(construct): recordRetentionDays を 1 以上の整数に限り、synth で検証する
seike460 Sep 28, 2026
cd35977
fix(construct): SAR の Layer と関数のアーキテクチャが食い違うと attachTo で止める
seike460 Sep 28, 2026
43bce28
test(construct): KMS の環境変数・バケット暗号化・付与する KMS 権限を検証する
seike460 Sep 28, 2026
2b1b35b
docs(construct): npm のページに出す README を追加する
seike460 Sep 28, 2026
e0a9bf4
ci: construct の型検査とテストを aws-cdk-lib の peer 下限でも実行する
seike460 Sep 28, 2026
ee00745
docs(changelog): v0.1.0 のタグと公開した SAR メタデータの差分を注記する
seike460 Sep 28, 2026
950a336
chore: 使っていない score.config.json と .gitignore の *.xlsx を削除する
seike460 Sep 28, 2026
aeadaed
chore(biome): 設定を Biome 2.5.14 の形式へ移行する
seike460 Sep 28, 2026
fe36e02
ci: Node を engines の下限 24 に合わせ、24 と 26 でテストする
seike460 Sep 28, 2026
4c20c1b
ci: CI と Layer ビルドの cargo に --locked を付ける
seike460 Sep 28, 2026
7f45dae
fix(layer): Layer の zip に LICENSE と第三者ライセンスを同梱する
seike460 Sep 28, 2026
4f74dad
test(examples): デモ関数の権限が s3:PutObject だけであることを厳密に検証する
seike460 Sep 28, 2026
4ca7095
fix(examples): E2E 手順の invoke と sam local での再現を、そのまま実行できる形に直す
seike460 Sep 28, 2026
50798c6
fix(sar): SourceCodeUrl をリポジトリのルートから、その版のタグに向ける
seike460 Sep 28, 2026
0122ad4
ci: リリースで上げる版の一致を pnpm gate と CI で確かめる
seike460 Sep 28, 2026
366d836
ci: main への push の run を取り消さず、どのコミットにも CI の結果を残す
seike460 Sep 29, 2026
74b5719
ci: pnpm/action-setup を v6.1.0 に、rustsec/audit-check を node24 のコミットに上げる
seike460 Sep 29, 2026
5197010
ci: Layer の zip のエントリ・mode・静的リンクを検査し、x86_64 のバイナリを起動して確かめる
seike460 Sep 29, 2026
7a8bde4
chore(layer): cross の aarch64 ビルド用コンテナを digest で固定する
seike460 Sep 29, 2026
1df997d
chore(scripts): scripts の .mts を pnpm typecheck で型検査する
seike460 Sep 29, 2026
39fb1e6
docs: リリースの手順を RELEASING.md に書き、SAR テンプレートの公開手順の説明を直す
seike460 Sep 29, 2026
8c296d5
docs(changelog): 0.1.0 の CLI コマンドと construct の例を実装に合わせ、依存の更新を記載する
seike460 Sep 29, 2026
482b03a
docs: 成功呼び出しの /tmp ステージと、SHUTDOWN の reason を問わない timeout 記録を実装どおりに書く
seike460 Sep 29, 2026
c16d5b4
docs(scrub): 例外メッセージなどの自由テキストに denylist が効かないことを書き、デモから外す
seike460 Sep 29, 2026
eba46c2
docs(readme): 自動作成バケットの RETAIN、SSM 経路の権限、CI と同じ clippy を書く
seike460 Sep 29, 2026
69ab6c6
docs(security): 失敗レコードを PUT の前に /tmp へ先書きする write-ahead spill を実装どおりに書く
seike460 Sep 29, 2026
0dc6ce2
docs(readme): exactOptionalPropertyTypes が有効なのは cli と scripts だけだと書く
seike460 Sep 29, 2026
3df7473
docs(spec): SPEC を現行の構成・公開済みのパッケージ名・truncate の条件に合わせる
seike460 Sep 29, 2026
09d639f
fix(scrub): ZANKYO_SCRUB_MODE=off では errorMessage などの自由テキストも書き換えない
seike460 Sep 29, 2026
129ed09
docs(spec): パターン検出の対象を実装どおり AWS アクセスキーと Bearer トークンと書く
seike460 Sep 29, 2026
02a2aae
fix(proxy): spill と PUT がともに失敗したとき、.inflight ステージを消さずに残す
seike460 Sep 29, 2026
d813d7a
fix(proxy): init 時に回収する .inflight の一覧を、中継を始める前に確定する
seike460 Sep 29, 2026
e05878e
fix(cli): 数値の環境変数は正の整数だけを受け付け、小数は既定値に倒す
seike460 Sep 29, 2026
0e6b874
fix(examples): デモの関数名とバケット名をスタックの出力から読み、E2E 手順のプレースホルダをなくす
seike460 Sep 29, 2026
57461f3
docs(cli): exit 4 の説明に形式不正・サイズ超過・再現不能を加え、2 つの README を揃える
seike460 Sep 29, 2026
d576bd5
fix(cli): S3 のレコード本文を読む途中の失敗を exit 3 にする
seike460 Sep 29, 2026
070041c
docs(spec): E2E 手順の redrive に --confirm を付け、fixture を --function で絞る
seike460 Sep 29, 2026
d04040a
docs(proxy): 全経路のボディを上限まで読んでから中継する動作を、コメントと README に書く
seike460 Sep 29, 2026
61c7439
docs(proxy): 非 JSON イベントの CLI での扱いを、record.rs のコメントで実装に合わせる
seike460 Sep 29, 2026
80d2a8d
docs(spec): SHUTDOWN の記録を reason を問わない実装に合わせて書く
seike460 Sep 29, 2026
79f0025
fix(layer): Rust 標準ライブラリと musl libc の表示を Layer の THIRD_PARTY_LICENSES…
seike460 Sep 29, 2026
6a445dc
fix(layer): build-layer.mts の BUILDER を cross build と cargo build に限る
seike460 Sep 29, 2026
4dba6de
fix(layer): Rust 標準ライブラリの COPYRIGHT-library.html を Layer に同梱する
seike460 Sep 29, 2026
e3af76f
fix(layer): 梱包の前に rustc の LLVM の版も LLVM_VERSION と照らし合わせる
seike460 Sep 29, 2026
8b13ade
fix(layer): crate のサブディレクトリにあるライセンスの表示も THIRD_PARTY_LICENSES に載せる
seike460 Sep 29, 2026
dca7055
docs(readme): scripts のテストを pnpm test が実行し、zip と unzip を使うことを書く
seike460 Sep 29, 2026
8564317
fix(proxy): external extension を Extensions API の一時的な失敗で SHUTDOWN 前に終…
seike460 Sep 29, 2026
a6ae507
fix(proxy): Extensions API の応答ボディの読み取りを時間でも打ち切る
seike460 Sep 29, 2026
14173ea
fix(proxy): /next の応答ボディの読み取りを ZANKYO_FORWARD_TIMEOUT_MS で打ち切る
seike460 Sep 29, 2026
12993a2
docs: 記録の保存を「確実」とせず、ベストエフォートであることと失われる条件を書く
seike460 Sep 29, 2026
5ac262f
fix(proxy): SSM の JSON の ZANKYO_SSM_TIMEOUT_MS を設定に重ねず、環境変数でだけ指定できると明記する
seike460 Sep 29, 2026
d33f574
docs: 設定の解決順を「既定値 → env → SSM」に直し、SSM の値で変わらない場合を書く
seike460 Sep 29, 2026
d9d966f
docs: 記録しない agent が読まずに既定値を使う設定を 4 つとも書く
seike460 Sep 29, 2026
d7943d5
docs(proxy): 固定の安全上限を ARCHITECTURE.md に一覧にし、不変条件をこれに合わせて狭める
seike460 Sep 29, 2026
b8b252d
docs(readme): ZANKYO_SPILL_DIR が絶対パスだけを受け付けることと、construct と SSM の併用時の…
seike460 Sep 29, 2026
555111b
docs(architecture): 記録しない agent の設定の説明を README の言い回しにそろえる
seike460 Sep 29, 2026
1334da9
chore: lambda-zankyo 0.1.1 をリリースする
seike460 Sep 29, 2026
cd6f3fa
build(layer): x86_64 の cross コンテナも digest で固定し、リリース手順を cross に限る
seike460 Sep 30, 2026
40cd1a3
fix(proxy): 上限を超えるリクエストボディは残りを読み捨ててから 413 を返し、ランタイムに接続リセットを届けない
seike460 Sep 30, 2026
7f12494
ci(layer): x86_64 も cross の固定コンテナでビルドし、リリースの zip はタグの commit の CI art…
seike460 Sep 30, 2026
2f89f7e
chore(deps): yank された yoke-derive 0.8.3 を 0.8.4 に上げる
seike460 Oct 2, 2026
1f99952
ci(layer): 2 つ目の cross ビルドの前にホスト用の成果物を消し、glibc の違うコンテナで失敗しないようにする
seike460 Oct 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# scripts/licenses/ は、上流の原文をそのまま写したもの。行末の空白も原文のまま残し、
# GitHub の言語の集計からも外す(COPYRIGHT-library.html は大きな HTML)
scripts/licenses/** -whitespace linguist-vendored
146 changes: 132 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,62 @@ on:
permissions:
contents: read

# PR は新しい push で古い run を取り消す。main の push は run ごとの group にして、
# 取り消しも待機中の run の置き換えも起こさず、どのコミットにも結果を残す
concurrency:
group: ci-${{ github.ref }}
group: ci-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
cancel-in-progress: true

jobs:
ts-quality:
name: ts (biome + tsc + test)
name: ts (biome + tsc + test, node ${{ matrix.node }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
# 24 = engines の下限(.nvmrc と同じ)、26 = 次の LTS
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
node-version: ${{ matrix.node }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint # biome check .
# npm の 2 パッケージ・proxy の crate・SAR の版と、SourceCodeUrl のタグ・CHANGELOG の見出し
- run: pnpm check:versions
- run: pnpm build # tsc emit — zankyo-cdk/dist を生成(examples の typecheck/test が依存)
# CLI のテストは src を型除去で実行する。公開する bin(package.json の bin が指す dist)の
# import 書き換えやパスの誤りは、ここで実際に起動して確かめる(bin.js は全コマンドを静的 import する)
- name: smoke-test the cli bin (dist)
working-directory: cli
run: node "$(node -p 'require("./package.json").bin.zankyo')" --version
- run: pnpm typecheck # tsc --noEmit in each package
- run: pnpm test # node --test in each package

construct-peer-min:
name: construct (aws-cdk-lib peer minimum)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: pnpm
- run: pnpm install --frozen-lockfile
# construct/package.json の peerDependencies の下限を正とし、devDependencies より
# 古い宣言値でも型検査とテストが通ることを確かめる(lockfile の書き換えはこのジョブ内だけ)
- name: install the declared aws-cdk-lib minimum
working-directory: construct
run: |
min=$(node -p 'require("./package.json").peerDependencies["aws-cdk-lib"].replace(/^[\^~]/, "")')
pnpm add --save-dev "aws-cdk-lib@$min"
- working-directory: construct
run: pnpm typecheck && pnpm test

rust-quality:
name: rust (fmt + clippy + test)
runs-on: ubuntu-latest
Expand All @@ -38,22 +73,39 @@ jobs:
- uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- run: cargo fmt --all -- --check
- run: cargo clippy --workspace --all-targets -- -D warnings
- run: cargo test --workspace
- run: cargo clippy --locked --workspace --all-targets -- -D warnings
- run: cargo test --locked --workspace

rust-msrv:
name: rust (MSRV)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# proxy/Cargo.toml の rust-version を正とし、rust-toolchain.toml より
# 古い宣言値でもビルドできることを確かめる(RUSTUP_TOOLCHAIN が toml に優先する)
- name: install the declared rust-version
run: |
msrv=$(sed -n 's/^rust-version = "\(.*\)"/\1/p' proxy/Cargo.toml)
rustup toolchain install "$msrv" --profile minimal
echo "RUSTUP_TOOLCHAIN=$msrv" >> "$GITHUB_ENV"
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- run: cargo check --locked --workspace --all-targets

audit:
name: dependency audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm audit --prod
- uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2
# 最新のリリース v2.0.0 は node20 で動く。action.yml の runs.using を node24 に
# 変えただけの main のコミット(#48、未リリース)に固定する
- uses: rustsec/audit-check@858dc40f52ca2b8570b7a997c1c4e35c6fc9a432 # main (v2.0.0 + node24)
with:
token: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -64,19 +116,85 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- name: install musl tools + cmake (aws-lc-sys build)
run: sudo apt-get update && sudo apt-get install -y musl-tools cmake zip
- name: build x86_64
run: cargo build --release --target x86_64-unknown-linux-musl -p zankyo
- name: build aarch64 via cross (docker)
- name: install zip (layer packaging)
run: sudo apt-get update && sudo apt-get install -y zip
# 両 arch とも、Cross.toml で digest に固定したコンテナでビルドする。
# リリースの zip は、タグの commit でこの job が作った artifact を使う(RELEASING.md)
- name: build x86_64 and aarch64 via cross (docker)
run: |
cargo install cross --locked --version 0.2.5
cross build --release --target aarch64-unknown-linux-musl -p zankyo
cross build --locked --release --target x86_64-unknown-linux-musl -p zankyo
# 2 つのコンテナは glibc が違う(x86_64 は 2.31、aarch64 は 2.27)。1 つ目が
# target/release に作ったホスト用のビルドスクリプトは、2 つ目では実行できない
# (GLIBC_2.28 not found)。ターゲット別の成果物(target/<triple>/release)は残す
rm -rf target/release
cross build --locked --release --target aarch64-unknown-linux-musl -p zankyo
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
- name: package layer zips
# 直前ステップで両 arch をビルド済みなので梱包だけ行う
env:
SKIP_BUILD: '1'
run: node scripts/build-layer.mts
# エントリの並びと mode(実行ファイルは 755、ライセンス表示は 644)と CRC を確かめる。
# THIRD_PARTY_LICENSES は、crate でない静的リンクの部品(Rust 標準ライブラリ・musl libc・
# LLVM の libunwind と crtbegin/crtend)の表示も、scripts/licenses/ の原文のまま含むこと。
# COPYRIGHT-library.html(Rust 標準ライブラリのファイルごとの表示)は、原文と同じバイト列であること。
# bin/zankyo は arch どおりの ELF で、動的リンカ(PT_INTERP)を要求しない静的リンクであること
- name: check the layer zips
run: |
shopt -s failglob
expected=$(printf '%s\n' \
'-rwxr-xr-x bin/zankyo' \
'-rwxr-xr-x extensions/zankyo' \
'-rwxr-xr-x zankyo-wrapper' \
'-rw-r--r-- share/licenses/zankyo/LICENSE' \
'-rw-r--r-- share/licenses/zankyo/THIRD_PARTY_LICENSES' \
'-rw-r--r-- share/licenses/zankyo/COPYRIGHT-library.html')
notices=(
scripts/licenses/rust-*/COPYRIGHT
scripts/licenses/rust-*/LICENSE-APACHE
scripts/licenses/rust-*/LICENSE-MIT
scripts/licenses/rust-*/LICENSES/Unicode-3.0.txt
scripts/licenses/rust-*/library/compiler-builtins/LICENSE.txt
scripts/licenses/musl-*/COPYRIGHT
scripts/licenses/llvm-*/libunwind/LICENSE.TXT
scripts/licenses/llvm-*/compiler-rt/LICENSE.TXT)
for pair in x86_64:X86-64 aarch64:AArch64; do
arch=${pair%%:*} machine=${pair#*:}
z=dist/layer/zankyo-$arch.zip
unzip -tq "$z"
diff <(echo "$expected") <(unzip -Z "$z" | awk '$3 == "unx" { print $1, $NF }')
unzip -q "$z" -d "$RUNNER_TEMP/layer-$arch"
node -e '
const { readFileSync } = require("node:fs");
const [file, ...notices] = process.argv.slice(1);
const text = readFileSync(file, "utf8");
const missing = notices.filter((n) => !text.includes(readFileSync(n, "utf8").trimEnd()));
if (missing.length > 0) {
console.error(file + " lacks:\n " + missing.join("\n "));
process.exit(1);
}
' "$RUNNER_TEMP/layer-$arch/share/licenses/zankyo/THIRD_PARTY_LICENSES" "${notices[@]}"
cmp scripts/licenses/rust-*/COPYRIGHT-library.html \
"$RUNNER_TEMP/layer-$arch/share/licenses/zankyo/COPYRIGHT-library.html"
bin=$RUNNER_TEMP/layer-$arch/bin/zankyo
if ! readelf -h "$bin" | grep -q "Machine: .*$machine\$"; then
echo "$z: bin/zankyo is not $machine" >&2
exit 1
fi
if readelf -l "$bin" | grep -q INTERP; then
echo "$z: bin/zankyo is dynamically linked" >&2
exit 1
fi
done
# 引数なし・Lambda の外(AWS_LAMBDA_RUNTIME_API なし)では、usage を出して EX_USAGE(64)で終わる
- name: smoke-test the x86_64 binary in the zip
run: |
rc=0
"$RUNNER_TEMP/layer-x86_64/bin/zankyo" || rc=$?
test "$rc" -eq 64
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: zankyo-layer
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ apikey

# Test artifacts
coverage/
*.xlsx
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
25
24
58 changes: 50 additions & 8 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,68 @@ platform が別プロセスで agent を起動する。in-flight イベントは
`.inflight` ステージを書き、agent が SHUTDOWN で読んで
timeout レコードへ変換する。完了した呼び出しのステージは
proxy が即削除する(残存=未完の証跡)。
agent は passthrough 判定でも終了せず、`SHUTDOWN` だけを購読して
待機する。登録前や `SHUTDOWN` 前に extension が終了すると、
終了コードに関係なく platform が Init を失敗させるため。
このとき設定が壊れている場合に備えて、Extensions API の設定
(`ZANKYO_REGISTER_TIMEOUT_MS`・`ZANKYO_EXT_RETRY_MS`・`ZANKYO_EXT_BODY_KB`・
`ZANKYO_EXT_MAX_POLL_FAILURES`)は読まず、既定値を使う。
同じ理由で、register と `/event/next` の一時的な失敗は再試行し、
`SHUTDOWN` まで終了しない。終了するのは、登録の 4xx 拒否・500
(公式リファレンスが「回復不能。速やかに終了」と定める)・
Runtime API への接続不能の継続(`ZANKYO_EXT_MAX_POLL_FAILURES` 回)の
ときだけで、終了コードは 1 にする。

## 品質・保守性の不変条件

このプロジェクトは次の不変条件を守る。レビュー・生成コードも同じ基準。

- **設定は env → SSM overlay → 既定値の順で解決**。動作ノブ
(上限・タイムアウト・間隔)をコードへ埋め込まない。新しい数値設定は
- **設定は既定値 → env → SSM overlay の順に重ねて解決**(後が優先)。
例外は SSM を読む前に決まるもの。取得に使う `ZANKYO_SSM_PARAM`・
`ZANKYO_SSM_TIMEOUT_MS` は env だけで決め、SSM の JSON では上書きしない
(`ssm_overlay.rs` の `ENV_ONLY_KEYS`)。env の `ZANKYO_DISABLED` の真と
env の設定エラーは、SSM を読まずに passthrough を決める。
- **利用者が調整する動作ノブ(上限・タイムアウト・間隔)をコードへ
埋め込まない**。`ZANKYO_*` で変えられるようにし、新しい数値設定は
`config.rs` の env 読み取り + `ssm_overlay.rs` の
`SSM_NUM_FIELDS` に 1 行で済む。
`SSM_NUM_FIELDS` に 1 行で済む。例外は下の「固定の安全上限」に挙げた
定数だけで、足すときは名前付きの定数にして表にも載せる。
- **拡張はデータの 1 エントリ追加で完結**。scrub パターンは
`scrub_data.rs`、CLI コマンドは `bin.ts` のディスパッチ、
SSM キーは `SSM_NUM_FIELDS`、build arch は `TARGETS`。
- **エラーは握り潰さない**。失敗は `ZankyoError`/`Option` でモデル化し、
捨てる経路はすべて文脈付きの warn で残す。
- **rerun は冪等**。spill は atomic 書き込み → 数・鮮度上限 →
起動時・定期回収 → 全件回収で dir 削除、とライフサイクルが閉じる。
起動時・定期回収 → 送れたファイルの削除、とライフサイクルが閉じる。
spill dir 自体は消さない(同時に走る書き込みが ENOENT で失敗するため)。
- **型は緩めない**。TS は strict + noUncheckedIndexedAccess、`as`
キャストなし(AWS 境界は `ports.ts` の構造的ポート)。Rust は
`#![forbid(unsafe_code)]` + clippy -D warnings。書式は
biome / rustfmt で CI 強制。

## 固定の安全上限

次の値は設定で変えず、コードの定数に固定する。どれもプロトコルや実装の都合で
決まる安全のための上限か、短い待ち時間で、利用者の環境に合わせて変える値ではない。
変えられる値は README の設定表(`ZANKYO_*`)にある。`proxy/tests/docs_it.rs` が、
この表と `proxy/src` の定数を突き合わせる。

| 定数 | 値 | 場所 | 役割 |
|---|---|---|---|
| `EXT_BODY_TIMEOUT` | 1 秒 | `extension.rs` | Extensions API の応答ヘッダーを受けてから、ボディを読み切るまでの上限。登録では、残り時間の方が短ければ残り時間 |
| `ERROR_BODY_MAX_BYTES` | 4096 バイト | `extension.rs` | Extensions API のエラー応答のボディを、診断用に読む上限 |
| `SHUTDOWN_DEADLINE_MARGIN_MS` | 200 ms | `extension.rs` | SHUTDOWN の `deadlineMs` の手前に残す余白。フラッシュ予算は、余白を引いた残り時間と `ZANKYO_FLUSH_BUDGET_MS` の小さい方 |
| `SHUTDOWN_GRACE_CAP_MS` | 1 秒 | `orchestrate.rs` | 子が先に終了したとき、同じプロセスの extension に SHUTDOWN が届くのを待つ上限(`ZANKYO_FLUSH_BUDGET_MS` との小さい方) |
| `DRAIN_SLACK_MS` | 1 秒 | `orchestrate.rs` | 終了時に保存の完了を待つ時間枠で、`ZANKYO_PUT_TIMEOUT_MS` に足す余白 |
| `ACCEPT_BACKOFF` | 50 ms | `proxy.rs` | Runtime API の listen で、accept に失敗したときの再試行間隔 |
| `DRAIN_POLL` | 10 ms | `proxy.rs` | 終了時に、実行中のハンドラが無くなったかを確かめる間隔 |
| `PART_ORPHAN_GRACE` | 60 秒 | `spill.rs` | 書きかけの `.part` を、クラッシュ後の残りとみなして消すまでの猶予 |
| `RECORDED_CAP` | 4096 件 | `inflight.rs` | 記録済みの requestId(二重記録の防止用)を覚えておく件数の上限 |

設定で指定しても効かない場合が 1 つある。記録しない状態の agent は、設定が壊れている
場合に備えて、Extensions API の 4 つの設定を読まず、既定値(`config.rs` の定数)を使う
(上の「全体像」)。

## モジュール対応(proxy/src)

| ファイル | 責務 |
Expand All @@ -63,15 +104,15 @@ proxy が即削除する(残存=未完の証跡)。
| `proxy.rs` | Runtime API の listen・経路判定・接続管理 |
| `handlers.rs` | `/next`・`/response`・`/error`・`/init/error` の個別処理 |
| `upstream.rs` | 上流 Runtime API への転送。hop-by-hop 除去と上限付きボディ読み |
| `extension.rs` | Extensions API。internal ループと external agent(`.inflight` 変換) |
| `extension.rs` | Extensions API。internal ループと external agent(`.inflight` 変換・passthrough 時の待機) |
| `inflight.rs` | `/next`〜確定までのイベント保持(Mutex<HashMap>) |
| `store.rs` | S3 PutObject とレコード組み立て(scrub 適用) |
| `spill.rs` | /tmp 退避の管理。書き込み・回収・保持数上限・廃棄 |
| `record.rs` | 保存レコードのスキーマ生成(serde) |
| `scrub.rs` / `scrub_data.rs` | PII マスキングの純粋ロジックと判定データ |
| `config.rs` / `ssm_overlay.rs` | env 設定解決と SSM JSON overlay(キーはテーブル駆動) |
| `runtime.rs` | 子プロセス起動(passthrough / proxy)と終了コード変換 |
| `ssm.rs` | SSM Parameter Store 取得(10s timeout、fail-open) |
| `ssm.rs` | SSM Parameter Store 取得(既定 2s timeout、fail-open) |
| `error.rs` / `lib.rs` | `ZankyoError` 統一型と公開面 |

## 拡張ポイント
Expand All @@ -80,7 +121,8 @@ proxy が即削除する(残存=未完の証跡)。
パターン自体は `scrub_data.rs` に 1 エントリ。
- **設定項目**: `Config` + env 読み取りに追加。SSM は
`SSM_NUM_FIELDS` に 1 行(フィールド単位パースで 1 キーの
書き損じが全体を壊さない)。
書き損じが全体を壊さない)。SSM を読む前に使う値は表に載せず、
`ENV_ONLY_KEYS` に足す。
- **CLI コマンド**: `cli/src/commands/` に 1 ファイル + `bin.ts` に
1 行。AWS 境界は `ports.ts` の構造的ポートに閉じる。
- **failure type**: `record.rs` enum・写像・CLI の
Expand All @@ -100,7 +142,7 @@ proxy が即削除する(残存=未完の証跡)。
3. 失敗時: イベントを scrub → レコード JSON を生成 → /tmp へ先書き
(write-ahead spill)→ bounded な S3 PutObject を **応答転送の前に**
完了させる。呼び出し終了で環境が freeze されると非同期 PUT は
進まないため、失敗経路だけこの順序を取る(成功経路はコスト 0)。
進まないため、失敗経路だけこの順序を取る(成功経路は spill も PUT もしない)。
PUT が間に合わなければ spill が残り、定期回収・次回 init が拾う。
4. SHUTDOWN(reason: timeout/failure/spindown): external extension の
agent が残った `.inflight` ステージを読み、「応答が返らなかった
Expand Down
Loading
Loading