@aiquants/enrichment-core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -19
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1586 -643
- package/dist/index.d.ts +1586 -643
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,13 +10,16 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
10
10
|
- **Canonical Types & Schemas**: `EnrichmentSyncStatus`, `DocumentStructuredData`, `BoundingBox`, `CircuitBreakerStatus` 等の正準 TypeScript 型および Zod スキーマ。
|
|
11
11
|
- **EnrichmentClient**: ハイブリッド検索 (`POST /ai/search/hybrid`) を呼ぶ HTTP クライアント SDK。要求・応答のスキーマ (`SearchRequestSchema` / `SearchResponseSchema`) は Python 側 `HybridSearchRequest` / `HybridSearchResponse` と項目ごとに一致する。詳細は下の「Search client contract」。
|
|
12
12
|
- **Pipeline flow as data** (`flow.ts`): 文書種 (`DOCUMENT_KINDS` / `classifyDocumentKind`)、段 (`PIPELINE_STEPS`)、種類ごとの段の DAG (`PIPELINE_FLOWS` / `flowFor` / `orderedSteps`)。ワーカーの実行順とコンソールの図はこの 1 つの表から導く。段は自分を閉じるテナントのフラグ (`gates`) と、閉じたときの意味 (`skip` / `fail`) を宣言し、流れは段ごとにその意味を上書きできる (`FlowStep.gatePolicy`)。流れの中の門は `flowStepGates` で読む。詳細は下の「Pipeline flow contract」。
|
|
13
|
+
- **Source catalog** (`sourceCatalog.ts`): 源の目録 (`GET /ai/sources`) の厳格な型 (`SourceCatalogSchema` / `SourceSpecSchema`) と語彙 (`SOURCE_CREDENTIALS` / `SOURCE_CAPABILITIES`)、画面の助け (`sourceOfUri` / `identifierMatches` / `pastedIdentifier`)。源を宣言するのは Python のコアの登録簿だけで、画面は目録を読み、源の型の表を持たない。詳細は下の「Source catalog contract」。
|
|
13
14
|
- **Pipeline records** (`pipelineRecord.ts`): 1 回の実行 (`PipelineRunRecordSchema`) と段ごとの記録 (`PipelineStepRecordSchema`)、段を除いた実行の要約 (`PipelineRunSummarySchema`、一覧向け)、段が自身について報告する値 (`StageProvenanceSchema`、Python 側の `StageProvenance` と項目ごとに一致)、段の集計 (`PipelineStepMetricSchema`)、飛ばした理由の文法 (`SkipReason` / `formatSkipReason` / `parseSkipReason`、読む対象が無かったときの値 `NOTHING_TO_READ_TOKENS` / `NothingToReadTokenSchema`)。測っていない値は `null` で、欠落させない。詳細は下の「Pipeline record contract」。
|
|
14
15
|
- **Integrity audit contract** (`integrity.ts`): Tri-Store 整合性監査の記録の語彙 (`IntegrityStoreSchema` を含む 12 の列挙と、所見を記録する区分 `IntegrityFindingItemClassSchema`)、区分の扱いと処置の表 (`INTEGRITY_CLASS_POLICY`)、概況 (`IntegrityAuditOverviewSchema`)、所見の頁と要求 (`IntegrityFindingPageSchema` / `IntegrityFindingsQuerySchema`)、
|
|
15
16
|
`UNRECORDED` の組の一括の再同期の 1 回分の要求と答え (`IntegrityCellResyncRequestSchema` / `IntegrityCellResyncResultSchema`)、配置の所見が観測したドメイン (`IntegrityPlacementObservedSchema`)、開始・中止の命令と命令ごとの失敗の語彙 (`IntegrityCommandSchema` / `IntegrityCommandFailureSchema`) と (状態, 業務コード) の表 (`integrityCommandCodes.json` / `INTEGRITY_COMMAND_CODES` / `integrityCommandFailureCodeOf`)、ホストのストアの応答 (`IntegrityCommandReplySchema`)、契約の時刻の前後の比較 (`isStrictlyEarlier`)。
|
|
16
17
|
詳細は下の「Integrity audit contract」。
|
|
17
18
|
- **Enrichment stages** (`strategy.ts`): ドメインの戦略行が開閉できる段の唯一の表 (`ENRICHMENT_STAGES`、パイプラインの順) と段の型・キー (`EnrichmentStage` / `EnrichmentStageKey`、DB の列名と 1 対 1)、キーの判定と引き当て (`isEnrichmentStageKey` / `enrichmentStage`)。段はテナントの機能フラグと戦略行の 2 つの門を持ちうる (テナントの門の無い段は `featureFlagKey` が `null`)。ナレッジグラフのノードを閲覧するときの境界と既定値 (`GRAPH_INDEX_LIMITS`)。
|
|
18
|
-
- **Vocabularies & search modes** (`vocabulary.ts` / `search.ts`): DB が強制する閉じた語彙 (`ModelProviderSchema`・`ConfidentialityLevelSchema`、検索結果に現れない機密区分 `QUARANTINED_CONFIDENTIALITY_LEVEL`)、検索モードと各モードが走らせる層の表 (`SEARCH_MODES` / `MODE_TIERS` と、そこから導く `
|
|
19
|
-
|
|
19
|
+
- **Vocabularies & search modes** (`vocabulary.ts` / `search.ts`): DB が強制する閉じた語彙 (`ModelProviderSchema`・`ConfidentialityLevelSchema`、検索結果に現れない機密区分 `QUARANTINED_CONFIDENTIALITY_LEVEL`)、検索モードと各モードが走らせる層の表 (`SEARCH_MODES` / `MODE_TIERS` と、そこから導く `modeScoreIsSimilarity` / `modeFusesRankings`)、調整可能な引数の境界と既定値 (`SEARCH_PARAM_LIMITS`。問いと文字の絞り込みの文字数を含む)、絞り込める機密区分 (`FILTERABLE_CONFIDENTIALITY_LEVELS`)、
|
|
20
|
+
答えの閉じた語彙 (融合 `SEARCH_FUSIONS`・品質の段 `SEARCH_QUALITY_TIERS`・遮断器のストア `CIRCUIT_BREAKER_SERVICES` と状態 `CircuitBreakerStatusSchema`・縮退の理由 `SEARCH_DEGRADATION_REASONS`)。規則は Python のコア (`aiquants_enrichment_core.search.contract`) に在り、公開 API が OpenAPI に出す値を画面のために写す。
|
|
21
|
+
- **Document change history** (`documentHistory.ts` / `revisionDiff/` / `canonicalJson.ts`): 文書の差分履歴 (S1 §8.19) の契約 (語彙・版付きの定数・面ごとの正準の値・変化の計数・比較・行の頁・履歴・直近の変化の一覧と位置・手動の記録の答え・隔離の印 `Restricted*MarkSchema` と読める項目の包み `ReadableEntry`)、記録器と読み手が共有する差分エンジン v2 (`summarizeTransition` / `compareStates`、純粋な関数で入出力もハッシュも持たない)、システムの中の唯一の正準の JSON (`canonicalJson`)。詳細は下の「Document history contract」。
|
|
22
|
+
- **Child asset tree** (`childTree.ts` / `childTreeRebuild.ts`): 根の下の子アセットの木の節点の道の文法 (`TREE_PATH_PATTERN` / `TreePathSchema`)、区画・深さ・親の道 (`treePathSegments` / `treePathDepth` / `treePathParent`)、木の順 (`compareTreePaths`)、画面の名 (`treePathLabel` / `assetTypeName`)、面 `assets` の項目の道 (`treePathOf` / `AssetPlace`)、既存の文書の木をまとめて取り込み直す 1 回分の要求と答え (`ChildTreeRebuildRequestSchema` / `ChildTreeRebuildResultSchema` / `CHILD_TREE_REBUILD_CHUNK`)。詳細は下の「Child asset tree contract」。
|
|
20
23
|
- **System parameter ranges** (`systemParameterRanges.ts`): 値域を持つシステムパラメータの唯一の表 (`systemParameterRanges.json` / `SYSTEM_PARAMETER_RANGES`) と、書き手が当てる検査 (`assertSystemParameterInRange`) と読み手が当てる検査 (`assertBoundedSystemParameter`)。詳細は下の「System parameter ranges」。
|
|
21
24
|
|
|
22
25
|
## Search client contract / 検索クライアントの契約
|
|
@@ -30,8 +33,7 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
30
33
|
- `EnrichmentClient` が持つのは `search` だけである。送信先は `<baseUrl>/ai/search/hybrid` であり、`baseUrl` はエンリッチメントのルーターが載る API ルート (エンリッチメントのルーターを載せる API サーバーのホストと API 接頭辞、例 `https://api.example.com/api/v1`)。
|
|
31
34
|
- ルートは `Authorization: Bearer <apiKey>` の利用者を認可し、テナントを `X-Tenant-Id` から取る。クライアントは `X-Tenant-Id` に本文の `tenant_id` を入れる (両者が食い違えばルートが 403 で拒む)。`apiKey` には利用者のアクセストークンを渡す (無ければルートが拒む)。
|
|
32
35
|
- 2xx 以外の応答と通信失敗は `EnrichmentClientError` (`statusCode`・`responseBody`・JSON なら `parsedBody`、通信失敗は `statusCode` 0)、JSON でない 2xx は `EnrichmentClientError`、スキーマに反する要求・応答 (空本文を含む) は `ZodError` を投げる。
|
|
33
|
-
-
|
|
34
|
-
- 遠隔の検索の呼び出しが失敗したときは、何が失敗したかで 5 語のどれか 1 つを立てる (`RemoteSearchFailureReason`): `remote_tiers_unavailable` (届かない、または停止中と答えた)、`remote_tiers_timed_out` (期限内に答えが無い)、`remote_tiers_refused_caller` (問う者を拒んだ。401 / 403)、`remote_tiers_rejected_request` (問うた内容を拒んだ。その他の 4xx)、`remote_tiers_failed` (答える途中で失敗した)。語ごとに運用者に求めることが違うため、1 語に畳まない。`remote_tiers_not_executed` は、遠隔層を要るモードで遠隔層が 1 つも走らず、誰も理由を述べなかったときだけの後ろ盾である。
|
|
36
|
+
- 縮退の理由の語彙 (`SEARCH_DEGRADATION_REASONS`、`search.ts`) は API の閉じた 14 語で、戦略が要した SQL の外の層が走らなかった訳を述べる (管理者の無効化・開いた遮断器・設定の欠け・コレクションの欠け・行スコープ・層ごとの届かない / 期限切れ・後ろ盾の `tiers_not_executed`)。`degraded_reason` はそれをカンマで連ねる。
|
|
35
37
|
|
|
36
38
|
## Pipeline flow contract / 流れの契約
|
|
37
39
|
|
|
@@ -40,6 +42,10 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
40
42
|
- `classifyDocumentKind(mimeType)` は `MIME_KIND_RULES` を上から照合し、最初に一致した規則の種類を返す (`*` で終わる規則は前方一致、パラメータと大文字小文字は無視)。どの規則にも一致しない型は `other`。
|
|
41
43
|
- 種類を名指しするのは抽出が読める書式だけである。Outlook の `.msg` (`application/vnd.ms-outlook`) は RFC 822 ではなく抽出が名指しで拒むため規則を持たず、`other` の流れを取る (最初に本文を読む段がその拒否を記録する)。`email` は `message/rfc822` だけ。
|
|
42
44
|
- ベクタの図形は `image/` の型でも `image` の流れを取らない (その流れの唯一の本文は版面の OCR であり、画素の無い図形からは作れない)。`image/svg+xml` は抽出が XML の文字として読むため `text`、`image/emf`・`image/x-emf`・`image/wmf`・`image/x-wmf` は読み手が無く抽出が名指しで拒むため `other` の流れを取る。どちらの規則も `image/*` より前に置く (後ろに置けば `image/*` が先に一致する)。
|
|
45
|
+
- Markdown (`text/markdown`・`text/x-markdown`) は `text/*` より前の規則で `markdown` の流れを取る。その流れは文字層と、文書が参照する画像を子アセットとして読み (`extract_assets` → `ocr_children` → `resolve_body`)、版面の OCR (`ocr_document`) を持たない。他のテキスト (`text`) の流れは子アセットを読まない。
|
|
46
|
+
- ZIP の書庫 (`application/zip`・`application/x-zip-compressed`・`application/x-zip`) は `archive` の流れを取る。書庫自身は文字層も版面も持たないので、その流れは書庫の暗号を外した後に中身を子アセットとして展開して読み (`delete_child_assets` → `unlock_document` → `extract_assets` → `ocr_children` → `resolve_body` → `enrich_document` → `project_to_indexes`)、本文は中身の本文だけである。中身が部品を持つ容れ物 (メール・PDF・Office) なら、その部品も中身の子として取り出して読む (下の「Child asset tree contract」)。OOXML の文書も ZIP の容れ物だが、自身の型を持ち `office` の規則が名指す。他の書庫の書式 (7z・RAR・tar・gzip) は読み手が無く `other` の流れを取る。
|
|
47
|
+
|
|
48
|
+
- パスワードを持ちうる文書 (`pdf`・`office`・`archive`) の流れだけが、旧版の子アセットの削除の直後に `unlock_document` を置く (文書のパスワードを外し、解いたファイルを原本にする)。他の全ての段はその後に原本を読む。段は門を持たず (閉じると読めない守られた文書を通すだけになる)、パスワードの無い文書は `not_protected` で飛ばす。メールの添付など子のパスワードは `extract_assets` の中で外すので、`email` の流れは段を持たない。
|
|
43
49
|
|
|
44
50
|
### Gates / 門
|
|
45
51
|
|
|
@@ -50,9 +56,29 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
50
56
|
| `flowStepGates(flowStep)` | 流れの中で段が持つ門 (上書きを適用した結果、宣言順)。ワーカーが評価し、コンソールが描くのはこの値であり、`PIPELINE_STEPS[key].gates` を直に読まない |
|
|
51
57
|
|
|
52
58
|
- 子の読み取りの段 (`ocr_children`) は門を宣言しない。子の文字層 (テキスト・メール・Office・PDF) は `ENABLE_OCR` に関係なく読まなければならず、段ごと飛ばすと添付のテキストが本文から消えるためである。認識の要る子だけが API サーバーの中で `ENABLE_OCR` に従い、閉じていればワーカーはその子の行を `gate_closed:ENABLE_OCR` で `SKIPPED` と記録する (段のキーに OCR の名が残るのは、共有 DB の段の記録と集計がこのキーで引かれるためであり、運用者に見せる名前は「子アセットの読み取り」)。
|
|
53
|
-
- 出荷する上書きは
|
|
59
|
+
- 出荷する上書きは 3 つだけ: 画像の流れの `ocr_document`、メディアの流れの `analyze_media`、書庫の流れの `extract_assets`。どれも流れの唯一の本文の出所であり (書庫の本文は中身だけなので、中身を取り出す段が唯一の出所)、フラグ (`ENABLE_OCR` / `ENABLE_MEDIA_ANALYSIS` / `ENABLE_ASSET_EXTRACTION`) が閉じていれば、その門で実行を `FAILED_EXTRACT` として止める。文字層を持つ流れ (pdf / email / office / google_native) の `ocr_document` は宣言どおり飛ばす。
|
|
54
60
|
- 実行側の契約 (`orderedSteps` の docstring): ワーカーは `orderedSteps(flow)` の順に段を走らせ、各段の前に `flowStepGates(step)` を評価する。最初に閉じていた門が決める — `skip` は段を `gate_closed:<flag>` で `SKIPPED` と記録して次へ進み、`fail` は段を `FAILED` と記録してその門の `failureStatus` で実行を終える。段は全ての門が開いているときだけ走る。
|
|
55
|
-
- どの流れも、門で飛ばされうる段だけに本文を頼らない (
|
|
61
|
+
- どの流れも、門で飛ばされうる段だけに本文を頼らない (文書自身の本文を作りうる段 `extract_text` / `ocr_document` / `analyze_media` のうち少なくとも 1 つは、閉じれば実行を止めるか門を持たない。それらを 1 つも持たない流れ (`archive`) は子アセットだけが本文なので、子を取り出す段 `extract_assets` が閉じれば実行を止める)。テストが出荷する全ての流れでこれを検査する。
|
|
62
|
+
|
|
63
|
+
### Golden file / 黄金の写し
|
|
64
|
+
|
|
65
|
+
- Python のコアの登録簿 (`aiquants_enrichment_core.pipeline`) が同じ段と流れを宣言する。2 つを縛るのは、この表から書く黄金の写し (`flow-ts-golden.json`) で、書き手は `tests/flowGolden.spec.ts` (書き先を `FLOW_GOLDEN_OUT` が名指す時だけ走る)。
|
|
66
|
+
- 写しは語彙・段・MIME の事例・流れごとの宣言の並びと位相順・順序の対 (依存の推移閉包)・門・`chunkSource`・子ごとの段と、`orderedSteps` が拒む 3 例と通す壊れた 2 例を持つ。封として `src/flow.ts` の SHA-256 を持つので、ここを直したら写しを書き直す。
|
|
67
|
+
|
|
68
|
+
## Source catalog contract / 源の目録の契約
|
|
69
|
+
|
|
70
|
+
| Field / 欄 | Meaning / 意味 |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `scheme` | 源の型 (`^[a-z][a-z0-9+.-]{0,31}$`)。目録の中で重ならない |
|
|
73
|
+
| `uri_prefix` | `<scheme>://` で始まる接頭辞 (例 `daily-report://reports/`) |
|
|
74
|
+
| `input_pattern` / `input_example` | 接頭辞の後の識別子が全て一致すべき形と、それに全て一致する例 |
|
|
75
|
+
| `paste_patterns` | 貼った文 (共有の URL など) から識別子を取る形。捕まえる群はちょうど 1 つ |
|
|
76
|
+
| `credential` | 誰の資格情報で読むか (`SOURCE_CREDENTIALS`) |
|
|
77
|
+
| `capabilities` | 読み以外にできること (`SOURCE_CAPABILITIES`)。重ならない |
|
|
78
|
+
| `delivered_mime_type` | 源がどの形を求めても届ける型 (保管層の源は `null`) |
|
|
79
|
+
|
|
80
|
+
- 形は Python の `re` とブラウザの `RegExp` が同じに読む部分集合だけを使う (登録簿が組む時に拒む)。どちらも `.` を全ての字に届かせる (Python は `re.DOTALL`、ブラウザは `s` と `u` の旗)。全て一致は `^(?:<形>)$` で行い、`s` と `u` の旗でコンパイルできない形は型が拒む。
|
|
81
|
+
- `sourceOfUri` は長い接頭辞を先に見る。`identifierMatches` は全て一致だけを認める。`pastedIdentifier` は目録の順に源と形を試し、最初に当たった形の群を返す。
|
|
56
82
|
|
|
57
83
|
## Pipeline record contract / 実行記録の契約
|
|
58
84
|
|
|
@@ -60,7 +86,8 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
60
86
|
|
|
61
87
|
| Field | Writer contract / 書き手の契約 | Checked by the schema / スキーマが検査する規則 |
|
|
62
88
|
| --- | --- | --- |
|
|
63
|
-
| `stepKey` | 流れの段 (`PIPELINE_STEP_KEYS`) か終端段 `record_document_state` | `
|
|
89
|
+
| `stepKey` | 流れの段 (`PIPELINE_STEP_KEYS`) か終端段 `record_document_state` | `storedTermSchema(LEDGER_STEP_KEYS)` (`LEDGER_STEP_KEYS` の 11 語か、今の語彙が知らない鍵の `UnknownTerm`。下の「保存された語」) |
|
|
90
|
+
| `targetTreePath` | 対象が木の節点 (扇出した段の子アセット) なら根からの木の道、根 (文書自身) なら `null` | 木の道の文法 (`TreePathSchema`) か `null` (鍵の欠落は拒む)。`targetMetadataId` との一致は検査しない |
|
|
64
91
|
| `status` | `RUNNING` / `SUCCEEDED` / `SKIPPED` / `FAILED` | 語彙 |
|
|
65
92
|
| `skipReason` | `SKIPPED` のときだけ `formatSkipReason` の文字列を書き、それ以外は `null` | `SKIPPED` では非 `null`、`SUCCEEDED` と `FAILED` では `null`。`RUNNING` の値は検査しない。文法の外の文字列も DB の値 (`z.string()`) として受け入れ、解釈は読み手が `parseSkipReason` で行う |
|
|
66
93
|
| `provenance` | 段が自身について報告する値。`SUCCEEDED` では必須、`SKIPPED` では `null` (読む対象が無いと答えた段も、モデル欄が `null` の応答の報告を写さない) | `SUCCEEDED` では非 `null`、`SKIPPED` では `null`。`RUNNING` と `FAILED` の値は検査しない |
|
|
@@ -77,7 +104,8 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
77
104
|
| `{ kind: "gate_closed", featureFlagKey }` | `gate_closed:ENABLE_OCR` | 段を閉じる機能フラグ (`UPPER_SNAKE_CASE`) が無効だった |
|
|
78
105
|
| `{ kind: "no_children" }` | `no_children` | 子アセットを生む段は走ったが、子が 1 件も無かった |
|
|
79
106
|
| `{ kind: "source_skipped", stepKey }` | `source_skipped:extract_assets` | 扇出の元になる段が同じ実行で飛ばされた (子を探していない) |
|
|
80
|
-
| `{ kind: "nothing_to_read", token }` | `nothing_to_read:no_pages` | 呼ばれた読み取りの段 (`ocr_document`、子ごとの `ocr_children`) が、読む対象が無いと答えた (モデルは呼んでいない)。`token` は `NOTHING_TO_READ_TOKENS` の値 (`no_pages`: 版面を持たない形、`no_pages_rendered`: 版面を持つ形からラスタ化器が 1
|
|
107
|
+
| `{ kind: "nothing_to_read", token }` | `nothing_to_read:no_pages` | 呼ばれた読み取りの段 (`ocr_document`、子ごとの `ocr_children`) が、読む対象が無いと答えた (モデルは呼んでいない)。`token` は `NOTHING_TO_READ_TOKENS` の値 (`no_pages`: 版面を持たない形、`no_pages_rendered`: 版面を持つ形からラスタ化器が 1 枚も作らなかった、`covered_by_page_recognition`: PDF の埋め込み画像が、親の本文である親の版面の認識が既に読んだページに載る) で、enrichment-fastapi の OCR 応答の `skipped` と同じ閉じた集合 (`ocr_disabled` は閉じた `ENABLE_OCR` の門として記録する)。ワーカーは応答の値を読み替えずに写す |
|
|
108
|
+
| `{ kind: "not_protected" }` | `not_protected` | 解除の段 (`unlock_document`) が、外すパスワードが無いと答えた (文書が守られていない・保管層が変換した形を届けた)。enrichment-fastapi の解除の応答の `skipped` と同じ値で、ワーカーは読み替えずに写す |
|
|
81
109
|
| `{ kind: "superseded" }` | `superseded` | 終端段の時に、実行の版の行が文書の現在の行でなくなっていた (状態を写さない) |
|
|
82
110
|
| `{ kind: "recording_disabled" }` | `recording_disabled` | 終端段の時に、配備の文書の履歴の記録の切替が `false` だった |
|
|
83
111
|
| `{ kind: "recording_misconfigured" }` | `recording_misconfigured` | 終端段の時に、配備の切替が無いか `true` / `false` のどちらでもなかった (`false` と見分ける) |
|
|
@@ -88,10 +116,10 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
88
116
|
|
|
89
117
|
### Terminal step / 終端段
|
|
90
118
|
|
|
91
|
-
実行の流れの後に、ワーカーは文書の状態を捕捉する段を高々 1 つ記録する。鍵は `RUN_TERMINAL_STEP_KEY` (`record_document_state`) で、段の記録の鍵の語彙は `LEDGER_STEP_KEYS` (`PIPELINE_STEP_KEYS` の
|
|
119
|
+
実行の流れの後に、ワーカーは文書の状態を捕捉する段を高々 1 つ記録する。鍵は `RUN_TERMINAL_STEP_KEY` (`record_document_state`) で、段の記録の鍵の語彙は `LEDGER_STEP_KEYS` (`PIPELINE_STEP_KEYS` の 10 の後に終端段を足した 11 語) である。
|
|
92
120
|
|
|
93
121
|
- `PIPELINE_FLOWS` は終端段を名指さない。したがって流れの図と段の集計 (`PipelineStepMetricSchema.stepKey` は `PipelineStepKeySchema`) に終端段は現れない。
|
|
94
|
-
- 終端段は実行を失敗させないので、実行の `failedStepKey` (`PipelineRunRecordSchema` / `PipelineRunSummarySchema`) は流れの段 (`
|
|
122
|
+
- 終端段は実行を失敗させないので、実行の `failedStepKey` (`PipelineRunRecordSchema` / `PipelineRunSummarySchema`。`storedTermSchema(PIPELINE_STEP_KEYS)`) は流れの段 (`PIPELINE_STEP_KEYS`) だけを知る値として名指す (終端段の鍵は知る値として受けない)。
|
|
95
123
|
- `PipelineStepRecordSchema` は終端段の行に次を検め、外れる行を拒む。成功した終端段の報告は `detail` 以外の全ての鍵が `null` で、`strategyId` と `httpStatus` も `null` (API を呼ばない)、`detail` はちょうど `{ outcome }` (`RunTerminalStepDetailSchema`、`outcome` は `RUN_TERMINAL_STEP_OUTCOMES` = `RECORDED` / `UNCHANGED` / `ALREADY_RECORDED`) で、状態の ID・連番・処理時間を持たない。
|
|
96
124
|
- 失敗した終端段の `errorCode` は `RUN_TERMINAL_STEP_ERROR_CODES` (`history_no_current_row` / `history_lock_timeout` / `history_write_failed`) の 3 つのどれかで、飛ばした終端段の `skipReason` は上の表の終端段の 3 種 (`superseded` / `recording_disabled` / `recording_misconfigured`) のどれかである (`PipelineStepRecordSchema` が検める)。
|
|
97
125
|
|
|
@@ -100,8 +128,16 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
100
128
|
- `trigger` (`PipelineTriggerSchema`) は `ingest` (取り込み) / `retry` (手動の再試行) / `resync` (再同期) だけ。実行を開くのはワーカーだけであり、整合性監査の修復の実行 (パイプラインの実行を開かずに再投影する) と比較投影 (本番の状態を変えない) はきっかけではない。
|
|
101
129
|
- `attempt` は BullMQ ジョブ内の試行番号 (1 起点)。手動の再試行・再同期は新しいジョブとして 1 から数え、`trigger` で区別する。
|
|
102
130
|
- `retryScheduled` は失敗した試行の後にキューが次の試行を予定したか。`FAILED` の実行だけが `true` を持てる (`superRefine` で検査)。
|
|
131
|
+
- `documentKind` と `failedStepKey` は `storedTermSchema(DOCUMENT_KINDS)`・`storedTermSchema(PIPELINE_STEP_KEYS)` (`failedStepKey` は `null` も)。今の語彙が知らない値は `UnknownTerm`。
|
|
103
132
|
- `PipelineRunSummarySchema` は `PipelineRunRecordSchema` から `steps` を除いた形で、同じ規則に従い、`steps` キーを拒む。
|
|
104
133
|
|
|
134
|
+
### Stored terms / 保存された語
|
|
135
|
+
|
|
136
|
+
- `StoredTerm<T>` は `T | UnknownTerm` で、`UnknownTerm` は `{ known: false, raw }` (`storedTerm.ts`)。記録が DB の制約なしに保存する語彙 (段の鍵・実行の文書種と止めた段) を、別の版が書いた値でも読めるように運ぶ。
|
|
137
|
+
- `storedTermOf(vocabulary, stored)` は完全一致で照らし、知る値はそのもの、知らない値は `UnknownTerm` を返す。`isUnknownTerm`・`storedTermText` (保存された時の文字列。写像や試験の ID の鍵) で読む。
|
|
138
|
+
- `storedTermSchema(vocabulary)` は知る値をそのものとして、知らない値を `UnknownTerm` として受け、知る値を `UnknownTerm` の形で運ぶことを拒む (形は 1 つ)。
|
|
139
|
+
- 語彙は足すだけ: `DOCUMENT_KINDS` と `PIPELINE_STEP_KEYS` から語を消すことも名を変えることもしない (流れから外した段のキーも残す)。
|
|
140
|
+
|
|
105
141
|
### Step metric / 段の集計
|
|
106
142
|
|
|
107
143
|
- 集計は (`documentKind`, `stepKey`) の組ごとに 1 件。`documentKind` は段の記録が属する実行の文書種であり、複数の流れが共有する段 (`ocr_document`・`resolve_body`・`project_to_indexes` など) も種類ごとに別の集計になる。組は現在の流れの表と照合しない (記録は走った流れを持つ)。
|
|
@@ -109,6 +145,29 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
109
145
|
- `SKIPPED` の記録 (読む対象が無いと答えた段を含む) は `skipped` に数え、`sampleCount` と百分位には入らない。
|
|
110
146
|
- `sampleCount` が 0 なら両方の百分位は `null` (`superRefine` で検査)。
|
|
111
147
|
|
|
148
|
+
## Unlock contract / 解除の契約
|
|
149
|
+
|
|
150
|
+
`unlock.ts` spells what the console reads of removing the password a file carries, as `aiquants-enrichment-fastapi` answers it. A password is never part of it: a row of the passwords is read without one.
|
|
151
|
+
|
|
152
|
+
`unlock.ts` は、ファイルが持つパスワードを外すことについてコンソールが読むものを、`aiquants-enrichment-fastapi` の答えのまま綴る。パスワードはそこに含まれない (パスワードの行はパスワード無しで読む)。
|
|
153
|
+
|
|
154
|
+
| Value / 値 | Vocabulary / 語彙 | Meaning / 意味 |
|
|
155
|
+
| --- | --- | --- |
|
|
156
|
+
| `PROTECTION_FORMATS` | `zip`・`pdf`・`ooxml`・`legacy_office` | 守りの属する書式 (記録 `td_file_unlock.protection_format` の語彙) |
|
|
157
|
+
| `REMOVABLE_PROTECTION_SCHEMES` | `zipcrypto`・`aes`・`pdf_user_password`・`pdf_owner_password`・`office_encryption` | 部品が外せる守り方。外したことの記録 (`td_file_unlock.protection_scheme`) と解除の段の答えが持てる唯一の値 |
|
|
158
|
+
| `PROTECTION_SCHEMES` | `REMOVABLE_PROTECTION_SCHEMES`・`strong_encryption` | ファイルの守り方。`strong_encryption` は PKWARE の強い暗号で、どの部品も外せない |
|
|
159
|
+
| `UNLOCK_DISPOSITIONS` | `source_overwritten`・`copy_original`・`copy_promoted`・`child_decrypted` | 版の解いたファイルが原本になった方法 (記録 `td_file_unlock.disposition` の語彙) |
|
|
160
|
+
| `COPY_REASONS` | `permission_denied`・`immutable_source`・`foreign_application`・`local_source` | 源を上書きせず写しを原本にした理由。`isPromotable` が真になるのは `permission_denied` だけ (書けるようになった源へ昇格できる) |
|
|
161
|
+
| `UNLOCK_ERROR_CODES` | `passwordRequired: 4225`・`protectionUnsupported: 4226`・`sourceChanged: 4094` | 解除の段と昇格が失敗する業務コード |
|
|
162
|
+
| `FILE_PASSWORD_SOURCE_KINDS` / `FILE_PASSWORD_PATTERN_SYNTAXES` | `gmail`・`gdrive`・`gcs`・`file`・`daily-report` / `glob`・`regex` | 条件が名指せる源の種類と、型の書き方 (どちらも値の全体に、大小文字を区別せず当てる) |
|
|
163
|
+
| `FILE_PASSWORD_FIELD_WIDTHS` / `FILE_PASSWORD_MAX_BYTES` | 名 200・送り手 320・件名 400・ファイルの名 400・URI の接頭辞 2048 / 995 | 名と条件の幅 (`storedWidth`。ホストの `nvarchar(n)` の列と同じ UTF-16 の単位で、BMP の外の字は 2 つ) と、UTF-8 で数えるパスワードの最長 (`passwordByteLength`) |
|
|
164
|
+
| `FILE_PASSWORD_PRIORITY_MAX` | 2147483647 | 優先度の最大 (ホストの `int` の列が収める値。優先度は 0 から) |
|
|
165
|
+
|
|
166
|
+
- 語彙ごとに、コンソールが見せる名 (`*_LABELS`、凍結した表) を持つ。
|
|
167
|
+
- `FilePasswordConditionsSchema` は条件を検める (書いた条件は空でなく幅の中、無い条件は `null`)。`triesEveryFile` は条件を 1 つも書かない行 (全てのファイルに試す行) を見分ける。
|
|
168
|
+
- `FilePasswordViewSchema` は行の見方 (時刻は時差つき)、`FilePasswordListSchema` と `FilePasswordMatchSchema` は一覧と照らしの答え (型は `FilePasswordView`・`FilePasswordList`・`FilePasswordMatch`)。契約の外の欄は読まない。
|
|
169
|
+
- 記録の語彙 (`PROTECTION_FORMATS`・`REMOVABLE_PROTECTION_SCHEMES`・`UNLOCK_DISPOSITIONS`・`COPY_REASONS`) はホストの `td_file_unlock` の CHECK の、幅はホストの `tm_file_password` の列の写しでもあり、一致はホストの試験が確かめる。
|
|
170
|
+
|
|
112
171
|
## Integrity audit contract / 整合性監査の契約
|
|
113
172
|
|
|
114
173
|
監査は API サーバーの中で走り、`td_integrity_audit_run` / `td_integrity_audit_quantity` / `td_integrity_audit_finding` へ記録する。ホストはその行を読み、次の形でコンソールへ渡す。記録の語彙 (下の表の `IntegrityStoreSchema` から `IntegrityRepairSkipReasonSchema` までの 12 の列挙と `IntegrityFindingItemClassSchema`) と区分の方針 (`INTEGRITY_CLASS_POLICY`) は各表の CHECK 制約の写しであり、実行の行の制約が持つ削除印の保持日数の範囲は、実行の見出しを検める `SYSTEM_PARAMETER_RANGES.INTEGRITY_TOMBSTONE_RETENTION_DAYS` の写しである。写しの一致はホストの試験が DDL を読んで確かめる (本パッケージはホストの DDL の置き場所を知らない)。
|
|
@@ -127,6 +186,10 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
127
186
|
|
|
128
187
|
契約の時刻 (`readAt`・`startedAt`・`heartbeatAt` など) の前後は、`Date.parse` でなく公開する `isStrictlyEarlier(earlier, later)` で比べる (`Date.parse` はミリ秒までしか保たず、100 ns 違う 2 つの時刻を等しいと見る)。両方が契約の受ける時刻で `earlier` が `later` より厳密に前のときだけ `true` を返し、時差 (`Z`・`±HH:mm`・`±HHmm`)・秒の省略・1 秒未満の全ての桁を読んで比べる。どちらかが契約の受ける時刻でなければどちらの向きにも `false` なので、`!isStrictlyEarlier(a, b)` は「`a` が `b` の後か同時」ではない。比べる前に値を契約 (`IntegrityAuditOverviewSchema` など) で検める。契約自身も同じ関数で、`finishedAt` と `heartbeatAt` が `startedAt` より前でないことを検める。
|
|
129
188
|
|
|
189
|
+
2 つの時刻の間の長さは、同じ理由で `millisecondsBetween(from, to)` で取る。全ての桁から差を取り、最後にだけミリ秒へ切り上げるので、その値で置いたタイマーは `to` より前に鳴らない (`to` が `from` の後でなければ 0 以下、どちらかが契約の受ける時刻でなければ `null`)。コンソールが概況の `readAt` から実行中の実行の `staleAfter` までを待つのに使う。
|
|
190
|
+
|
|
191
|
+
取り込みの出来事の流しの出来事の名は `INGESTION_EVENT_NAMES` (凍結) が持つ: 整合性監査の実行の状態の変化 `integrityRun` (`integrity_run`) と、再開に欠けがあることを知らせる終わりの出来事 `resyncRequired` (`resync-required`)。出来事は合図で、ID と状態だけを運ぶ。購読者は合図で概況を読み直し、`resync-required` の後は記録を読み直してカーソル無しで開き直す。
|
|
192
|
+
|
|
130
193
|
| Vocabulary / 語彙 | Values / 値 |
|
|
131
194
|
| --- | --- |
|
|
132
195
|
| `IntegrityStoreSchema` | `QDRANT` / `NEO4J` |
|
|
@@ -164,14 +227,14 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
164
227
|
| --- | --- |
|
|
165
228
|
| `IntegrityRunHeaderSchema` | `REPAIR` ⇔ `basisRunUid` が在る。`COMPLETED` ⇔ `verdict` が在る ⇔ `reprojectDocuments` が在る。`reprojectRebuildDocuments` は `reprojectDocuments` と揃って在り、それ以下。`RUNNING` ⇔ `finishedAt` が `null`、`finishedAt` は `startedAt` より前でない (1 秒未満の全ての桁と時差を読んで比べる)。`errorClass` は `FAILED` と `ABANDONED` だけ。`storeFingerprint` は 64 桁の小文字の 16 進。`tombstoneRetentionDays` は `SYSTEM_PARAMETER_RANGES.INTEGRITY_TOMBSTONE_RETENTION_DAYS` (1〜3650) の整数 (実行の行の制約の範囲はその写しで、見出しは自分の範囲を持たない)。時刻は時差付きの ISO 8601 (時差は `Z`・`±HH:mm`・`±HHmm`。秒と 1 秒未満の端数は省け、端数は任意の桁数を持てる) |
|
|
166
229
|
| `IntegrityQuantitySchema` | 扱いと処置は区分の方針 (`INTEGRITY_CLASS_POLICY`) のとおり。`itemCount === null` ⇔ `unmeasuredReason !== null` ⇔ `measuredAt === null` (測って 0 件は未測定と別)。修復の 3 つの件数は揃って在るか揃って無く (欠けた件数を報告する)、在るのは処置 (`repairAction`) のある区分だけで、測れた量では和が `itemCount` を超えない (測れなかった量も件数を持てる) |
|
|
167
|
-
| `IntegrityActiveRunSchema` | 実行は `RUNNING`。`heartbeatAt` は `run.startedAt`
|
|
230
|
+
| `IntegrityActiveRunSchema` | 実行は `RUNNING`。`heartbeatAt` は `run.startedAt` より前でない。`staleAfter` (心拍が古くなる時刻。心拍にテナントの `INTEGRITY_RUN_HEARTBEAT_TIMEOUT_SECONDS` を足した時刻で、`isStale` と同じ秒の値で DB が計算する) は `heartbeatAt` より厳密に後。段が `null` なら範囲・進行・総数も `null`。`DOCUMENTS` の段は範囲 (`phaseScope`) を持たない。進行は見積もりの総数を超えうる |
|
|
168
231
|
| `IntegrityAuditOverviewSchema` | `lastCompleted.run` は `COMPLETED` で、量は (店, 範囲, 区分) の組ごとに 1 つ、`SCAN` の量は修復の件数を持たない。`newerUnsuccessful.run` は `FAILED` / `CANCELLED` / `ABANDONED`。不成功の `SCAN` は `repairAppliedItems` を持たず、不成功の `REPAIR` の `hasNewerRepair` は真 (それ自身がより新しい修復)。入れ子の見出し・量・実行中の実行もそれぞれの規則で検める |
|
|
169
232
|
| `IntegrityFindingSchema` | `repairErrorClass` は `FAILED` だけ、`repairSkipReason` は `SKIPPED` だけ。`sequence` と `metadataId` (SoT の行の ID) は 1 以上の整数。`fileUri` と `revision` は派生ストアの項目が名乗る値の写しなので、空の URI と 0 以下の版もそのまま運ぶ (`revision` は整数) |
|
|
170
233
|
| `IntegrityPlacementObservedSchema` | `UNPLACED` と `OUT_OF_TIER` の所見の `observed` を読む形。`sotDomain` (SoT が項目の現行の文書に与えるドメイン) は必須で文字列か `null`、他の観測値の鍵はそのまま通す。`null` は文書がドメインを持たないこと (再同期が導き直す)、`UNPLACED` の文字列は本番の戦略の無いドメイン、`OUT_OF_TIER` の文字列は戦略がその店の段を閉じたドメイン (`OUT_OF_TIER` は必ず文字列を持つ)。組はドメインを混ぜるので、ドメインは行ごとの値で組の値ではない。SoT が書いた値の写しなので空の文字列も拒まない |
|
|
171
234
|
| `IntegrityFindingPageSchema` | 行は `sequence` の昇順で重複しない。`nextAfter` は `null` か、この頁の最後の行の `sequence`。`recordedCount` は `totalCount` と突き合わせない (書き手は鍵の無いグラフのノードを数えた後に標本を取るので、その間に作られたノードで標本が全数を超えうる) |
|
|
172
235
|
| `IntegrityFindingsQuerySchema` | `itemClass` は所見を記録する区分 (`IntegrityFindingItemClassSchema`) だけ。`limit` は必須で 1〜`INTEGRITY_FINDINGS_PAGE_LIMIT_MAX` (100) の整数 (0・負・`NaN`・文字列を拒む)。`after` は 1 以上の整数で、最初の頁では省く |
|
|
173
236
|
| `IntegrityCellResyncRequestSchema` | 一括の再同期の 1 回分の要求 (`runUid`・`store`・`scopeKey`・`itemClass`・`after`)。`itemClass` は `UNRECORDED` だけ (再同期が片付ける唯一の区分。店は文書の生きた項目を持つがその店の投影の記録が無い)。`after` は 1 以上の整数で、最初の回では省く。1 回の件数は要求が選ばず、`INTEGRITY_FINDINGS_PAGE_LIMIT_MAX` (100) に固定する。ホストはテナントの直近の完了した実行にだけ答え、組の所見を記録順に読む |
|
|
174
|
-
| `IntegrityCellResyncResultSchema` | 1 回分の答え (`requeued`・`skipped: { metadataId, reason }[]`・`nextAfter`)。再投入の数と据え置いた文書の数の和 (読んだ文書の数) は 100 以下で、`nextAfter` はちょうど 100 を読んだときだけ在る (最後に読んだ記録順。100 に満たない回は組の終わり)
|
|
237
|
+
| `IntegrityCellResyncResultSchema` | 1 回分の答え (`requeued`・`skipped: { metadataId, reason }[]`・`nextAfter`)。再投入の数と据え置いた文書の数の和 (読んだ文書の数) は 100 以下で、`nextAfter` はちょうど 100 を読んだときだけ在る (最後に読んだ記録順。100 に満たない回は組の終わり)。据え置いた文書は重複しない。規則は子の木のまとめての取り込み直しの答え (`ChildTreeRebuildResultSchema`) と共有する 1 つの検査が検める |
|
|
175
238
|
|
|
176
239
|
- コンソールが監査の実行について送る命令は `IntegrityCommandSchema` (`start` / `cancel`)。命令と失敗の語彙はコンソールの契約の持ち物で、DDL に写しを持たない。
|
|
177
240
|
- 開始・中止の失敗は `IntegrityCommandFailure` (`{command, code, status: 300〜599 の整数 | null}`、`command` で分かれる和の型) で運ぶ。`code` はコンソールが示す文ごとに 1 つ (`IntegrityCommandFailureCodeSchema`) で、各命令はその部分集合だけを持つ (もう一方の命令だけの語彙は `code` の問題として拒み、型でも持てない):
|
|
@@ -192,6 +255,24 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
192
255
|
|
|
193
256
|
- ホストのストアが開始・中止に答える形は `IntegrityCommandReply` (`{ok: true, runUid}` か `{ok: false, status, errorCode: int | null}`) だけで、上流の本文の文面を運ばない。失敗の `status` は転送を辿った応答の成功でない状態 (300〜599)。
|
|
194
257
|
|
|
258
|
+
## Child asset tree contract / 子アセットの木の契約
|
|
259
|
+
|
|
260
|
+
部品を持つ文書 (メール・PDF・Office、源が子を名指す文書の根、参照する画像を持つ Markdown の根) は部品を子アセットとして取り出し、部品を持つ子も自身の子を作る。子は根の下の木を成し、各節点は根からの木の道 (`td_file_metadata.tree_path`) を持つ。書庫は節点にならない: 書庫の中身 (入れ子の書庫の中身も) は、書庫に最も近い書庫でない祖先 (書庫を運んだ節点。文書そのものが書庫なら根) の子 (`archive_member`) で、名は書庫を通る道 (`資料.zip/単価.pdf`) である。中身が容れ物なら、その中身が自身の子を持つ。木の深さに上限は無く、木を止めるのは根 1 つの 1 回の走りが引く 2 つの予算 (`CHILD_TREE_MAX_NODES`・`CHILD_TREE_MAX_TOTAL_BYTES`、下の「System parameter ranges」) と循環の検査だけである。
|
|
261
|
+
|
|
262
|
+
- `TREE_PATH_PATTERN` / `TreePathSchema` は木の道の文法 (Python のコアの `TREE_PATH_PATTERN` と同じ文法) で、`<asset_type>-<asset_index>` の区画を根から `/` で繋ぎ、区画の数が深さ (根の子が 1) である。種類 (`[a-z_]+`) は `-` を持たないので区画は最後の `-` で割れ、位置は頭に 0 を持たない 10 進の整数なので、1 つの節点の綴りは 1 つ。道の長さに上限は無い (列は `nvarchar(max)`)。
|
|
263
|
+
- `treePathSegments(path)` は区画 (`TreePathSegment`)、`treePathDepth(path)` は深さ、`treePathParent(path)` は親の道 (深さ 1 は親が根なので `null`) を返す。文法の外の文はどれも `RangeError` で拒む。
|
|
264
|
+
- `compareTreePaths(a, b)` は木の順で比べる (区画ごとに種類を符号単位で、続いて位置を数で。祖先が子孫の前)。深さ 1 では `(assetType, assetIndex)` の順と同じ。位置は全ての桁で比べるので、等しいと比べるのは同じ道だけである。
|
|
265
|
+
- `treePathLabel(path)` は画面が節点を示す名 (`添付 0 > 書庫の中身 3 > 埋め込み画像 2`。段ごとの種類の名と位置で、節点の名を持たない)、`assetTypeName(assetType)` は種類の名を返す。名の表 (`assetTypeNames.json`) は表の CHECK が許す 8 つの種類を API サーバーと同じ名で持ち、名の無い種類は代わりの名を作らずに `RangeError` で拒む。
|
|
266
|
+
- `treePathOf(item)` は面 `assets` の項目の場所 (`AssetPlace`) から道を導く (親の道 `parentPath` と自身の区画。深さ 1 の項目は親の道を持たず、区画だけ)。道を検めないので、外から届いた値は `TreePathSchema` か面の契約で読む。
|
|
267
|
+
- この道を、段の記録の `targetTreePath` (`PipelineStepRecordSchema`) と面 `assets` (`AssetFacetItemSchema`) が使う。
|
|
268
|
+
|
|
269
|
+
### Bulk rebuild of the trees / 木のまとめての取り込み直し
|
|
270
|
+
|
|
271
|
+
- 既存の文書の木に深い節点を作るため、テナントの候補 (現行で削除されていない派生でない根のうち、部品を持つ種類の生きた節点を 1 つ以上持つもの) をまとめて取り込み直す。他の根は取り込み直しても木が変わらない。コンソールはホストに 1 回分ずつ求め、ホストは候補を API サーバーから識別子の昇順の keyset で 1 頁読み、各候補を再同期の唯一の再投入の規則に通す。
|
|
272
|
+
- `ChildTreeRebuildRequestSchema` は 1 回分の要求で、`after` (根の識別子。1 以上の整数で、最初の回では省く) だけを持つ。1 回の件数は要求が選ばず、`CHILD_TREE_REBUILD_CHUNK` (100) に固定する。
|
|
273
|
+
- `ChildTreeRebuildResultSchema` は 1 回分の答え (`requeued`・`skipped: { metadataId, reason }[]`・`nextAfter`)。再投入の数と据え置いた根の数の和 (読んだ候補の数) は 100 以下で、`nextAfter` はちょうど 100 を読んだときだけ在り (最後に読んだ根の識別子)、据え置いた根は重複しない。規則は `IntegrityCellResyncResultSchema` と同じで、両方を 1 回分の大きさを引数に取る 1 つの検査から作る。
|
|
274
|
+
- 再投入した根は流れの全ての段をもう 1 度走らせ、2 度求めれば 2 度取り込み直す。処理中・旧版・削除済みの根と、トークンや読み取りの規則が拒む根は、理由と共に据え置く。
|
|
275
|
+
|
|
195
276
|
## Document history contract / 文書の差分履歴の契約
|
|
196
277
|
|
|
197
278
|
文書の再同期・再取り込み・新しい版のたびに、ホストの記録器が文書の不変の状態の鎖を書き、読み手が履歴と比較を返す (S1 §8.19)。本パッケージはその契約と、記録器と読み手が共有する差分エンジンを持つ。記録器の結果 (`DocumentStateRecordOutcome`) はホストの型で、ここに無い (どの答えも運べない状態の識別子を持つ)。
|
|
@@ -200,7 +281,7 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
200
281
|
|
|
201
282
|
| Constant | Value | Meaning |
|
|
202
283
|
| --- | --- | --- |
|
|
203
|
-
| `DIFF_ENGINE_VERSION` |
|
|
284
|
+
| `DIFF_ENGINE_VERSION` | 2 | エンジンの版。捕捉の時の計数と共に凍結する (保存済みの状態の版は、その時のエンジンの値として残る) |
|
|
204
285
|
| `DIFF_CONTEXT_LINES` | 3 | 塊の文脈の行の数 |
|
|
205
286
|
| `HISTOGRAM_MAX_OCCURRENCES` | 64 | 錨にできる行の、区間の古い側の出現の上限 |
|
|
206
287
|
| `DIFF_REGION_CELL_BOUND` | 1,000,000 | 錨の無い区間を Myers で比べる升目の上限 (超えれば区間ごと置き換える) |
|
|
@@ -229,30 +310,32 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
229
310
|
|
|
230
311
|
### Facet values and counts / 面の値と計数
|
|
231
312
|
|
|
232
|
-
- `DocumentFacetValuesSchema` は 1 つの状態の全ての面の正準の値で、鍵は面の綴りそのもの (`structured_data` を含む)。集合の面は正準の順 (ラベルは `labelKey
|
|
313
|
+
- `DocumentFacetValuesSchema` は 1 つの状態の全ての面の正準の値で、鍵は面の綴りそのもの (`structured_data` を含む)。集合の面は正準の順 (ラベルは `labelKey`、タグは文字列で、どちらも UTF-16 の符号単位の順で `compareCodeUnits` が比べる。面 `assets` は導いた木の道の木の順で `compareAssetKeys` が比べる) で鍵を重ねない。タグの `null` (列が `NULL`) と空の配列、本文の `null` (抽出本文が無い) と空の本文は別の値である。
|
|
314
|
+
- 面 `assets` は根の木の生きた節点の全てを持つ。項目 (`AssetFacetItemSchema`) は 5 つの欄 (`assetType`・`assetIndex`・`mimeType`・`fileSize`・`textSha256`) を持ち、深さ 2 からの項目だけが親の道 `parentPath` を持つ (深さ 1 の項目は欄を持たず、`null` も値が `undefined` の鍵も拒む)。項目の道は導き (`treePathOf`)、`treePath`・`depth` は保存しない。種類は木の道の区画の種類 (`[a-z_]+`)、位置は安全な整数なので、導いた道は 1 つの節点だけを名指す。各 `parentPath` は先の項目の道に等しい (並びは生きた親の下の部分木だけを持つ)。深さ 1 だけの木は同じ 5 つの欄・同じ順・同じ正準の JSON になるので、保存済みの状態はそのまま読め、digest も変わらない。
|
|
233
315
|
- `ChunkManifestSchema` (`CHUNK_MANIFEST_VERSION`) は子チャンクを `index` の昇順に、親を子から初めて辿った順の序数で持ち、行と版に依る値 (親とチャンクの uid・`metadata_id`) を持たない。同じ本文を同じ実装でチャンク化すれば、どの行・版でも目録のバイト列が等しい。チャンクを持たない状態の目録は `null` で、空の目録は無い。
|
|
234
316
|
- `FacetChangeCountsSchema` は変わった 1 つの面の計数で、当てはまる計数 (`FACET_APPLICABLE_COUNTS`) は 0 以上の整数、他は `null` である (`CK_td_file_state_facet_change_counts` の写し)。
|
|
235
317
|
|
|
236
318
|
### Comparison and line pages / 比較と行の頁
|
|
237
319
|
|
|
238
|
-
- `DocumentComparisonSchema` は全ての面を表示の順に `UNCHANGED` か面ごとの差分 (`FacetDiffSchema`) で持ち、計算したエンジンの版 (`diffEngineVersion`) を持つ。分類とメタデータは項目の変化 (`FieldChange`)
|
|
320
|
+
- `DocumentComparisonSchema` は全ての面を表示の順に `UNCHANGED` か面ごとの差分 (`FacetDiffSchema`) で持ち、計算したエンジンの版 (`diffEngineVersion`) を持つ。分類とメタデータは項目の変化 (`FieldChange`)、ラベルと木の節点は鍵付き集合 (`KeyedItem` の追加・削除と `KeyedItemChange` の変更。節点の鍵は導いた道 `attachment-0/embedded_image-2` で、親の道は鍵の一部なので比べる欄でなく、親の変わった節点は削除と追加になる)、タグは集合、構造化データは RFC 6902 の操作 (`JsonPatchOperationSchema`: `add` / `remove` / `replace` だけで、取り除く値を `previous` に持つ)、本文と要約は索引 (`TextDiffIndexSchema`: 属性の変化・統計・塊の索引)、チャンクは対応付け (`ChunkChangeSchema`、片側ごとに読み手が確かめた忠実度) と `textUnchangedChunkingChanged` である。
|
|
239
321
|
- 本文・要約・チャンクの本文の行は比較に含めず、`DiffLinePageSchema` (`{ lines, next }`、`next` は塊の次の行の位置か `null`) で頁ごとに読む。チャンクの対の本文は両方の全体を 1 つの塊 (塊 `0`) にする。
|
|
240
322
|
|
|
241
323
|
### History, change feed and restricted marks / 履歴・直近の変化・隔離の印
|
|
242
324
|
|
|
243
325
|
- `DocumentHistorySchema` は現在の行 (隔離でない)、読める版の行 (新しい順、現在の版はちょうど 1 つ)、状態の一覧 (`DocumentStateEntrySchema`: `ReadableEntry<DocumentStateSummary>` か `RestrictedStateMark`、確定の時刻の新しい順) と実行の一覧 (`DocumentRunEntrySchema`: `ReadableEntry<PipelineRunRecord>` か `RestrictedRunMark`) を持つ。
|
|
244
326
|
- `DocumentStateSummarySchema` は連番を持たない。`previousStateId`・計数・エンジンの版・`modelOnlyChange` は直前の状態が読める時だけ値を持ち、最初の状態と直前を読めない状態はどちらも `previousStateId: null` である。`RUN` の状態だけが `runId` と `runOutcome` を持つ。
|
|
245
|
-
- 隔離の印 (`RestrictedRunMarkSchema` / `RestrictedIngestMarkSchema` / `RestrictedFailureMarkSchema` / `RestrictedStateMarkSchema` / `RestrictedChangeMarkSchema`) は種類・項目自身の時刻・結果か状態だけを持ち (取り込みの印の `syncStatus` は `EnrichmentSyncStatusSchema` の値か、エンリッチメントの行の無い文書 (取り込みがメタデータの行の後に止まった) では `null`、失敗の印の `syncStatus` はその失敗の状態 `PipelineFailureStatusSchema`)、どれも `.strict()` で識別に使える鍵を 1 つでも持てば拒む。一覧の要素は `kind` で分かれる判別和 (`z.discriminatedUnion("kind", [readableEntrySchema(<項目>), <一覧の印>])`)
|
|
327
|
+
- 隔離の印 (`RestrictedRunMarkSchema` / `RestrictedIngestMarkSchema` / `RestrictedFailureMarkSchema` / `RestrictedStateMarkSchema` / `RestrictedChangeMarkSchema`) は種類・項目自身の時刻・結果か状態だけを持ち (取り込みの印の `syncStatus` は `EnrichmentSyncStatusSchema` の値か、エンリッチメントの行の無い文書 (取り込みがメタデータの行の後に止まった) では `null`、失敗の印の `syncStatus` はその失敗の状態 `PipelineFailureStatusSchema`)、どれも `.strict()` で識別に使える鍵を 1 つでも持てば拒む。一覧の要素は `kind` で分かれる判別和 (`z.discriminatedUnion("kind", [readableEntrySchema(<項目>), <一覧の印>])`) で、
|
|
328
|
+
印は一覧と合う `subject` だけを許す。ホストの一覧 (取り込み・失敗) は `readableEntrySchema` と印の schema から同じ形の和を作り、直近の実行の表は `RecentPipelineRunEntrySchema` を使う。
|
|
246
329
|
- `DocumentChangeFeedPageSchema` は `{ rows, next }` で保存量を持たない。行は `ReadableEntry<DocumentChangeFeedEntry>` か `RestrictedChangeMark` (到着の状態の時刻の新しい順)。`next` は頁の最後の行 (印を含む) の到着の状態の位置で (位置の時刻は最後の行の時刻と同じ時点でなければならない)、`encodeChangeFeedCursor({ settledAt, id })` が `{ id, settledAt }` の正準の JSON の base64url に書き、`decodeChangeFeedCursor` は自分が書く文字列そのものだけを読み戻す (壊れた base64url・UTF-8 でない・JSON でない・形の外・別の綴りは `null`)。
|
|
247
330
|
- 手動の記録の答え `DocumentCaptureAnswerSchema` は `{ outcome: "RECORDED" | "UNCHANGED" }` だけである。
|
|
248
331
|
|
|
249
|
-
### Diff engine
|
|
332
|
+
### Diff engine v2 / 差分エンジン v2
|
|
250
333
|
|
|
251
334
|
- `summarizeTransition(transitions)` は記録器の入口で、変わった面ごとの古い値と新しい値 (`FacetTransition`) から、変わった面ごとの計数の行を表示の順に返す。面が無い・同じ面が 2 度・値の等しい面は `RangeError`。
|
|
252
335
|
- `compareStates(from, to)` は読み手の入口で、両側の面の値と、目録の子ごとに読み手が確かめた忠実度 (`ComparedState`) から比較を返す。行の頁は `textFacetDiff` / `summaryFacetDiff` / `diffChunkBodies` の差分 (`TextDiff`) を `diffLinePage` で読み、索引は `textDiffIndex` で読む (比較と同じ差分なので塊の番号が一致する)。
|
|
253
336
|
- 本文: 行は `\r\n`・`\r`・`\n` で分け (改行は内容でなく属性で、改行だけの変換は 1 つの属性の変化)、共通の前後を除いて histogram 差分 (古い側で出現の最も少ない行を錨にし、連なりはその中で最も稀な行の出現で競い、同点は長い連なり、次に区間の中央に近い連なり、次に新しい側で前から始まる連なり、次に古い側で前から始まる連なりを選ぶ) で区間に分け、錨の無い区間は両側が共有する行の上の Myers で対応付ける (升目が上限を超えれば区間ごと置き換え)。手順は常に正しく、最小は約束せず、同点は削除を先にする。間の等しい行が文脈の 2 倍以下の塊は繋ぐ。
|
|
254
337
|
- 行の中: 変化の塊の i 番目の削除の行と i 番目の追加の行を書記素 (`Intl.Segmenter`) で比べ、両方が上限以下で、編集の間の 1 書記素以下の等しい部分を編集へ繋いだ後の類似度が下限以上なら区切る。最長共通部分列の長さ (ビット並列で測る) が下限に届かない対は Myers を走らせずに外す (結果は変わらない)。類似度は `2 × 等しい書記素 / (古い書記素 + 新しい書記素)` で、両方が空なら `null`。
|
|
255
|
-
- 精緻化の手間の上限 (
|
|
338
|
+
- 精緻化の手間の上限 (エンジンの一部): 対の編集距離 (最長共通部分列から Myers の前に決まる) が `INLINE_REFINE_MAX_EDIT_DISTANCE` を超える対は精緻化しない。1 つの本文の差分 (面の古い値と新しい値の 1 組。本文・要約・チャンクの本文の差分はそれぞれ満ちた予算で始まる) は `INLINE_REFINE_CELL_BUDGET` 升の予算を持ち、対を決まった順 (変化の塊の順、その中は i 番目の削除と i 番目の追加) に見て、Myers を走らせる対は自分の升目のうち Myers が探る帯 (`(N + M) × 編集距離`) を消費する。残りに収まらない対が現れた時に予算は尽き、その対から後ろの対は精緻化しない。精緻化しない対は、類似度が下限に届かない対と同じく行全体の削除と追加として数える (出力の形は変わらない)。どちらの上限も入力だけで決まるので、同じ入力は常に同じ計数になる。上限 1,024 は 731 書記素以下の行の対に決して掛からず (精緻化できる対の距離は両側の書記素の和の 0.7 倍以下)、予算は通常の編集 (数行の編集・1 行の編集・短い行の OCR の読み直し・長い段落の誤字の修正) では尽きない。
|
|
256
339
|
- 頁: 状態の頁の区切り (`[{ start, end, page_number }]`、符号位置) の上で各行の始まりを二分探索し、削除の行は古い側、他は新しい側の頁を付ける。頁を名指さない区間 (シート・スライド) と配列でない区切りは頁を持たない。
|
|
257
340
|
- チャンク: (1) ハッシュの列の最長共通部分列が錨 (変わらない。番号のずれは移動でない)、(2) 錨の外の同じハッシュを出現ごとに順に `MOVED`、(3) 残りのうち各側にちょうど 1 度だけ現れる非 NULL の条項を `MODIFIED` (`clause`)、(4) 錨の間の隙間ごとに見出しの等しい残りを位置の順に `MODIFIED` (`breadcrumbs`)、(5) 残りは `REMOVED` / `ADDED`。項目は新しいチャンクの位置の順で、削除は削除された隙間の始まりに置く。
|
|
258
341
|
- 構造化データ: オブジェクトは鍵の順に再帰し、配列は要素の正準の JSON の最長共通部分列で対にし (1 回の差分は配列を辿る順 (鍵の順の深さ優先、要素の順) に `STRUCTURED_DATA_ARRAY_CELL_BOUND` 升の予算から各配列の中ほどの升目を払い、払えない配列は要素ごとに比べず、配列全体を 1 つの `replace` にする)、隙間の同じ位置の要素はどちらもオブジェクトかどちらも配列なら再帰し、それ以外は削除して追加する。操作を順に古い値へ当てると新しい値になる。
|
|
@@ -271,8 +354,13 @@ Transport- and DB-agnostic storage metadata AI enrichment core: canonical types,
|
|
|
271
354
|
| `INTEGRITY_RUN_HEARTBEAT_TIMEOUT_SECONDS` | 30〜3600 |
|
|
272
355
|
| `INTEGRITY_RUN_RETENTION_COUNT` | 2〜100 |
|
|
273
356
|
| `POLICY_CONFLICT_MAX_TIE_GROUP_SIZE` | 2〜60 |
|
|
357
|
+
| `CHILD_TREE_MAX_NODES` | 1〜100000 |
|
|
358
|
+
| `CHILD_TREE_MAX_TOTAL_BYTES` | 1048576〜4294967296 |
|
|
359
|
+
| `ARCHIVE_MAX_MEMBER_BYTES` | 65536〜1073741824 |
|
|
360
|
+
| `ARCHIVE_MAX_COMPRESSION_RATIO` | 10〜10000 |
|
|
274
361
|
|
|
275
|
-
- 表の正本は `src/systemParameterRanges.json` の 1 つ。他の言語のホストは自分の写しを持ち、このリポジトリの中ではその試験がこのファイルを読んで一致を確かめる (API サーバーの `PARAMETER_RANGES`)。公開する成果物は表を埋め込む。
|
|
362
|
+
- 表の正本は `src/systemParameterRanges.json` の 1 つ。他の言語のホストは自分の写しを持ち、このリポジトリの中ではその試験がこのファイルを読んで一致を確かめる (API サーバーの `PARAMETER_RANGES`・`ARCHIVE_LIMIT_RANGES`・`CHILD_TREE_LIMIT_RANGES`)。公開する成果物は表を埋め込む。
|
|
363
|
+
- `CHILD_TREE_MAX_NODES` と `CHILD_TREE_MAX_TOTAL_BYTES` は根 1 つの 1 回の走りが引く子の木の予算 (どの種類・どの深さの節点も 1 つ数え、抽出した全てのバイトを数える)。`ARCHIVE_MAX_MEMBER_BYTES` と `ARCHIVE_MAX_COMPRESSION_RATIO` は書庫の中身 1 つの上限である。木の深さと書庫全体の中身の数・総量の鍵は無い (木の予算が縛る)。
|
|
276
364
|
- `SYSTEM_PARAMETER_RANGES` は表と各値域を凍結してあり、型も値域まで読み取り専用である (プロセスの中の読み手の 1 つが値域を広げ、他の書き手と読み手の拒否を外すことができない)。
|
|
277
365
|
- `INTEGRITY_TOMBSTONE_RETENTION_DAYS` の値域は、実行の行の制約 (保持日数の範囲) と実行の見出しの契約 (`IntegrityRunHeaderSchema.tombstoneRetentionDays`) の範囲でもある。制約はこの表の写しなので、値域を変えるときは制約も同じ変更で改める (ホストの試験が一致を検める)。
|
|
278
366
|
- 表が抑えるパラメータは全て整数である。整数でないパラメータは、項目が型を宣言するまで表に加えられない。
|