# 通知設計書 70-Artifactsファイル不正エラー

## 概要

本ドキュメントは、Julia の Artifacts モジュールにおいてアーティファクトファイル（`Artifacts.toml`）に `os` や `arch` キーが欠落している、またはアーティファクトの形式が不正な場合に出力されるエラー通知の設計を記述する。

### 本通知の処理概要

`unpack_platform` 関数および `artifact_meta` 関数内で、アーティファクトファイルのエントリが不正な形式（`os` キー欠落、`arch` キー欠落、配列でもDict でもない形式、`git-tree-sha1` キー欠落）の場合にエラーレベルのログを出力する通知である。

**業務上の目的・背景**：Julia のアーティファクトシステムでは、プラットフォーム固有のアーティファクトは `os` と `arch` キーにより対象プラットフォームを指定する。これらのキーが欠落している場合、アーティファクトのプラットフォーム選択が正しく行えない。また、`git-tree-sha1` はアーティファクトの一意識別子として必須である。これらの必須要素の欠落を検出し、開発者に修正を促すことで、パッケージの配布とインストールの信頼性を確保する。

**通知の送信タイミング**：以下の3つの関数で発生する:
1. `unpack_platform` 関数 - プラットフォーム固有エントリに `os` または `arch` キーが欠落している場合
2. `artifact_meta` 関数 - アーティファクトエントリの形式が不正（配列でも Dict でもない）な場合
3. `artifact_meta` 関数 - アーティファクトメタデータに `git-tree-sha1` キーが欠落している場合

**通知の受信者**：Julia パッケージ開発者。Julia のロギングフレームワークを通じて配信される。

**通知内容の概要**：`"Invalid artifacts file at '$(artifacts_toml)': ..."` 形式のメッセージで、問題のあるファイルパスとエントリの詳細が含まれる。

**期待されるアクション**：開発者は `Artifacts.toml` ファイルの該当エントリを確認し、必須キー（`os`、`arch`、`git-tree-sha1`）を追加するか、エントリの形式を正しく修正することが期待される。

## 通知種別

ログ（Error） - Julia 標準ロギングフレームワーク `@error` マクロによるログ出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（関数実行中に即座にログ出力） |
| 優先度 | 高（Error レベル） |
| リトライ | 無 |

### 送信先決定ロジック

Julia の標準ロギングフレームワークにより、現在アクティブなロガーにメッセージが配信される。

## 通知テンプレート

### メール通知の場合

該当なし（ログ出力のみ）

### 本文テンプレート

パターン1（os キー欠落）:
```
Error: Invalid artifacts file at '<path>': platform-specific artifact entry '<name>' missing 'os' key
```

パターン2（arch キー欠落）:
```
Error: Invalid artifacts file at '<path>': platform-specific artifact entry '<name>' missing 'arch' key
```

パターン3（不正な形式）:
```
Error: Invalid artifacts file at <path>: artifact '<name>' malformed, must be array or dict!
```

パターン4（git-tree-sha1 欠落）:
```
Error: Invalid artifacts file at <path>: artifact '<name>' contains no `git-tree-sha1`!
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| artifacts_toml | Artifacts.toml ファイルのパス | 関数引数 | Yes |
| name | アーティファクト名 | TOML エントリのキー | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | `unpack_platform(entry, name, artifacts_toml)` | `!haskey(entry, "os")` | os キー欠落 |
| API呼び出し | `unpack_platform(entry, name, artifacts_toml)` | `!haskey(entry, "arch")` | arch キー欠落 |
| API呼び出し | `artifact_meta(name, artifact_dict, artifacts_toml)` | `meta` が Vector でも Dict でもない場合 | 不正な形式 |
| API呼び出し | `artifact_meta(name, artifact_dict, artifacts_toml)` | `!haskey(meta, "git-tree-sha1")` | git-tree-sha1 欠落 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `os` と `arch` の両方が存在する場合 | `unpack_platform` は正常に Platform を返す |
| `meta` が正しい形式の場合 | `artifact_meta` は正常にメタデータを返す |
| `git-tree-sha1` が存在する場合 | 正常にメタデータ辞書が返される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[artifact_meta 呼び出し] --> B{name が artifact_dict に存在?}
    B -->|No| C[return nothing]
    B -->|Yes| D{meta は Vector?}
    D -->|Yes| E[各エントリで unpack_platform 呼び出し]
    E --> F{os キー存在?}
    F -->|No| G["@error missing 'os' key"]
    F -->|Yes| H{arch キー存在?}
    H -->|No| I["@error missing 'arch' key"]
    H -->|Yes| J[Platform 構築]
    D -->|No| K{meta は Dict?}
    K -->|No| L["@error malformed, must be array or dict"]
    K -->|Yes| M{git-tree-sha1 存在?}
    M -->|No| N["@error contains no git-tree-sha1"]
    M -->|Yes| O[meta 返却]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Artifacts.toml / JuliaArtifacts.toml | アーティファクトメタデータの読み取り | TOML 形式 |

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| os キー欠落 | プラットフォーム固有エントリに `os` がない | `@error` を出力し `nothing` を返す |
| arch キー欠落 | プラットフォーム固有エントリに `arch` がない | `@error` を出力し `nothing` を返す |
| 不正な形式 | エントリが配列でも Dict でもない | `@error` を出力し `nothing` を返す |
| git-tree-sha1 欠落 | メタデータに `git-tree-sha1` がない | `@error` を出力し `nothing` を返す |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

## セキュリティ考慮事項

`Artifacts.toml` のファイルパスとアーティファクト名がログに出力される。これらは一般に機密情報ではない。

## 備考

- `unpack_platform` は `artifact_meta` から呼び出される。配列型のアーティファクトエントリの各要素に対して呼ばれ、プラットフォーム選択に使用される。
- `artifact_names` 定数は `("JuliaArtifacts.toml", "Artifacts.toml")` として定義されている（Artifacts.jl 行37）。
- エラーが発生した場合、いずれのケースも `nothing` が返され、呼び出し元でアーティファクトが見つからなかったものとして処理される。

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Artifacts.jl | `stdlib/Artifacts/src/Artifacts.jl` | `artifact_names` 定数（行37）と `ARTIFACTS_DIR_OVERRIDE`（行39） |

**読解のコツ**: Artifacts.toml は TOML 形式で、アーティファクト名をキーとし、値は単一 Dict（プラットフォーム非依存）または Dict の配列（プラットフォーム固有）となる。

#### Step 2: プラットフォーム解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Artifacts.jl | `stdlib/Artifacts/src/Artifacts.jl` | `unpack_platform` 関数（行280-304）。**本通知の発生箇所（行283, 288）** |

**主要処理フロー**:
1. **行282-284**: `os` キーの存在チェック - **行283 で `@error`**
2. **行287-289**: `arch` キーの存在チェック - **行288 で `@error`**
3. **行293-298**: タグの収集
4. **行300-303**: `Platform` オブジェクトの構築

#### Step 3: アーティファクトメタデータ取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Artifacts.jl | `stdlib/Artifacts/src/Artifacts.jl` | `artifact_meta` 関数（2引数版 行389-399、4引数版 行401-433）。**本通知の発生箇所（行418, 427）** |

**主要処理フロー**:
1. **行403-405**: `artifact_dict` にキーが存在するかチェック
2. **行409-415**: 配列の場合 - `unpack_platform` で各エントリを処理
3. **行417-420**: Dict でもない場合 - **行418 で `@error`**
4. **行424-429**: `git-tree-sha1` の存在チェック - **行427 で `@error`**

### プログラム呼び出し階層図

```
artifact_meta(name, artifacts_toml; platform, pkg_uuid)  [Artifacts.jl:389]
    |
    +-- load_artifacts_toml(artifacts_toml; pkg_uuid)     [Artifacts.jl:322]
    |
    +-- artifact_meta(name, artifact_dict, artifacts_toml) [Artifacts.jl:401]
            |
            +-- (meta isa Vector)
            |       |
            |       +-- unpack_platform(x, name, artifacts_toml) [Artifacts.jl:280]
            |               |
            |               +-- @error "missing 'os' key"        [行283]
            |               +-- @error "missing 'arch' key"      [行288]
            |
            +-- (!isa(meta, Dict))
            |       |
            |       +-- @error "malformed, must be array or dict" [行418]
            |
            +-- (!haskey(meta, "git-tree-sha1"))
                    |
                    +-- @error "contains no git-tree-sha1"        [行427]
```

### データフロー図

```
[入力]                           [処理]                              [出力]

Artifacts.toml        ------>   parse_toml              ------>   artifact_dict
name (String)         ------>   artifact_meta
platform              ------>       |
                                    +-- meta 取得
                                    +-- 型/キー検証
                                            |
                                            +-- 失敗: @error  ---->  エラーログ (stderr)
                                            |                         return nothing
                                            +-- 成功          ---->  meta (Dict)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Artifacts.jl | `stdlib/Artifacts/src/Artifacts.jl` | ソース | `unpack_platform` と `artifact_meta`。本通知の発生元（行283, 288, 418, 427） |
