Visual Question Answering
Cosmos
Diffusers
Safetensors
English
cosmos3_edge
physical-ai
disaster-response
uav
aerial
cosmos3
route-planning
Instructions to use v13s/tancho with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Cosmos
How to use v13s/tancho with Cosmos:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 33,481 Bytes
b6d3dd9 f635a54 b6d3dd9 f635a54 b6d3dd9 f635a54 b6d3dd9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | # Tancho Observation Program 詳細実装設計
| 項目 | 内容 |
|---|---|
| 文書版 | 1.0 |
| 日付 | 2026年9月21日 |
| 状態 | Release 1実装用 |
| 上位要件 | [Tancho PRD](tancho-prd-2026-09-21.md) |
| 対象範囲 | `slope_failure_v1`、`access_clearance_v1`を初回実装。後続profileの拡張点も定義 |
対象ミッションの正本は [Tanchoのミッション台帳](tancho-mission-inventory-2026-09-21.md)、製品要件の正本は [Tancho PRD](tancho-prd-2026-09-21.md)、開発順と採用条件の正本は [Open-weight Cosmos 3 Edge Generator計画](open-weight-generator-plan-2026-09-21.md) とする。本書は、その方針をコードへ実装できる粒度まで落とした詳細設計である。
## 1. 設計の不変条件
1. 対象の発見と範囲抽出は、物体検出器、面分類器、地図照合が担う。
2. 同じCosmos 3 Edge派生checkpointを、Reasoner roleとGenerator roleの別呼出しで使う。
3. Reasonerは未回答の運用上の問いを選ぶ。Generatorは検査済みの問いに必要な観測関係を組む。
4. モデルは座標、角度、距離、速度、滞在時間、緯度経度、PX4命令、安全制約を出さない。
5. 観測コンパイラ、軌道計画器、RFLが数値の視点と経路を決める。
6. モデルの生出力を補修、丸め、近い列挙値へ置換しない。不正出力はそのまま拒否する。
7. 決定論的fallbackで飛行できても、モデルの採用成績には数えない。
8. 旧 `tancho-viewpoints-1.0` と固定場面SITLの意味を変更しない。新しい版からadapterで接続する。
## 2. データフロー
```text
FrameBundle + telemetry + detector/classifier/map outputs
│
▼
build_mission_context()
│ MissionContext(trusted)
▼
Cosmos 3 Edge / Reasoner role
│ raw ObservationIntent
▼
validate_and_bind_intents()
│ VerifiedIntentSet(trusted IDs/revision)
▼
Cosmos 3 Edge / Generator role
│ raw ObservationProgram
▼
validate_observation_program()
│ VerifiedObservationProgram
▼
compile_observations()
│ CompiledViewPlan
▼
adapt_to_viewpoints_v1()
│ tancho-viewpoints-1.0
▼
trajectory planner → RFL → PX4 → capture
│
▼
verify_observation_result()
```
モデル呼出し間で渡すのは、生のReasoner JSONではなく `VerifiedIntentSet` である。アプリケーションがcanonical JSONのSHA-256から `intent_id` と `intent_revision` を作り、内部で固定する。Generator promptでは各intentを安定した `sequence` で示し、生出力の `intent_sequence` を検証器がopaque IDへ束縛する。
## 3. MissionContext 1.0
### 3.1 生存期間と上限
| 項目 | 値 |
|---|---|
| schema | `tancho-mission-context-1.1` |
| 最大対象数 | 32 |
| 最大根拠画像数 | 8 |
| 最大完了済みquestion数 | 対象ごと32 |
| 最大センサー数 | 8 |
| 時刻 | 同期済みの整数milliseconds |
| 有効期限 | アプリケーションが設定。モデルは延長不可 |
上限はメモリ使用量と攻撃面を閉じるための契約上限であり、運用上必要な件数を示す値ではない。上限を超えた入力は分割し、同じcontextとして黙って切り捨てない。
### 3.2 JSON形状
```json
{
"schema_version": "tancho-mission-context-1.1",
"context_id": "ctx-...",
"mission_id": "mission-...",
"mission_profile": "slope_failure_v1",
"captured_at_ms": 0,
"expires_at_ms": 0,
"input_sha256": "64 lowercase hex",
"model_revision": "...",
"profile_revision": "...",
"map_revision": "...",
"calibration_id": "...",
"envelope_revision": "...",
"evidence_ids": ["frame-1"],
"sensor_capabilities": ["rgb"],
"targets": [
{
"target_id": "target-1",
"category": "landslide_area",
"source": "area_classifier",
"geometry_ref": "geometry-1",
"map_relations": ["intersects_road"],
"required_questions": ["landslide_road_connection"],
"completed_questions": []
}
],
"policy": {
"max_intents": 4,
"max_observations": 8,
"max_viewpoints": 8,
"max_reobservation_cycles": 1
}
}
```
`input_sha256` は画像bytesのhash、対象レジストリ、センサー能力、各revision、policyを含むcanonical入力からアプリケーションが計算する。`context_id` もアプリケーションが発行し、モデル出力との照合にだけ使う。
### 3.3 列挙値
`sensor_capabilities` は初版で `rgb` と `thermal` のみを許す。SIYI A8 miniだけの構成は `rgb` だけになる。`thermal` をモデルが出力に追加しても能力が増えたとは扱わない。
`source` は `object_detector`、`area_classifier`、`map`、`map_difference`、`telemetry` のいずれか。`category` と `map_relations` は [§7](#7-ミッションプロファイル) のprofileで許可されたものだけを受ける。
## 4. Reasoner role
### 4.1 モデル生出力
```json
{
"schema_version": "tancho-observation-intent-1.0",
"context_id": "ctx-...",
"mission_id": "mission-...",
"outcome": "inspect",
"evidence_ids": ["frame-1"],
"intents": [
{
"sequence": 0,
"target_id": "target-1",
"question": "landslide_road_connection",
"priority": 1,
"evidence_ids": ["frame-1"]
}
],
"reason_code": "unanswered_question"
}
```
### 4.2 outcomeと整合条件
| outcome | intents | evidence_ids | reason_code |
|---|---:|---:|---|
| `inspect` | 1以上、policy以下 | 1以上 | `unanswered_question` |
| `satisfied` | 0 | 1以上 | `all_required_questions_completed` |
| `unsupported_sensor` | 0 | 1以上 | `required_sensor_unavailable` |
| `insufficient_evidence` | 0 | 0以上 | `target_unresolved` または `evidence_unusable` |
`priority` は1が最優先で1〜3。`sequence` は0から欠番なし。`question` はprofileの許可表にあるだけでなく、そのtargetの `required_questions` に明示され、`completed_questions` に無いことを要求する。同じ `target_id + question` の重複は拒否する。`completed_questions` は `required_questions` の部分集合でなければならない。`satisfied` は全targetで両集合が一致した場合だけ許可する。これにより、Reasonerは画像だけから任務目的を推測して質問を増やせず、旧 `no_action` の移行も具体的な完了対象に束縛される。
### 4.3 検証後の内部表現
`validate_and_bind_intents(raw, context, now_ms)` は生出力を変更せず検査し、成功時だけ次をアプリケーション側で追加する。
- `intent_id = sha256(context_id + sequence + target_id + question)` の64文字lowercase hex
- `intent_revision = sha256(canonical verified intent set)`
- `source_output_sha256 = sha256(raw model bytes)`
これらは次のモデルに渡す信頼済みIDであり、Reasoner自身には生成させない。
## 5. Generator role
### 5.1 入力
Generatorは同じFrameBundle、MissionContext、VerifiedIntentSetを受ける。Reasonerの自由文や未検証JSONをプロンプトへ連結しない。プロンプトには、アプリケーションが検証したintentの `sequence`、対象、question、priority、根拠画像IDを渡す。`intent_id`、`intent_revision`、context/mission IDなどのopaqueな値はモデルに再生成させない。
### 5.2 モデル生出力
```json
{
"schema_version": "tancho-observation-program-1.1",
"outcome": "observe",
"observations": [
{
"sequence": 0,
"intent_sequence": 0,
"view_relation": "along_axis",
"coverage": "both_sides",
"detail_level": "damage",
"sensor": "rgb",
"stop_condition": "corridor_continuity_visible"
}
],
"reason_code": "program_created"
}
```
### 5.3 outcomeと整合条件
| outcome | observations | reason_code |
|---|---:|---|
| `observe` | 1以上、policy以下 | `program_created` |
| `uncompilable_intent` | 0 | `unsupported_observation_primitive` |
Generatorは `satisfied` を返せない。問いが既に満たされたかを決めるのはReasonerである。Generatorはセンサー能力を変更できず、入力intentを追加、削除、改名できない。`observe` の場合は各intentが少なくとも1回参照される。完了済みquestionに結び付くintentは入力段階で存在できない。
### 5.4 共通の観測語彙
| field | 初版の列挙値 |
|---|---|
| `view_relation` | `overview`, `nadir`, `oblique`, `cross_section`, `along_axis`, `context`, `intercept`, `search_sweep` |
| `coverage` | `full_target`, `boundary`, `upper_lower_edges`, `both_sides`, `connection`, `upstream_downstream`, `target_and_context`, `facade_foot`, `approach_corridor`, `search_region` |
| `detail_level` | `detect`, `identify`, `state`, `damage` |
| `sensor` | `rgb`, `thermal` |
検証器は `intent_sequence` をVerifiedIntentSetの同じsequenceへ決定論的に結び、そこで初めてopaqueな `intent_id`、context/mission ID、`intent_revision` を付与する。未知sequence、欠落intent、同じ `intent_sequence + view_relation + coverage + detail_level + sensor + stop_condition` の重複は拒否する。旧1.0入力は保存済み証拠の検証用に読み取れるが、新しいpromptと教師は1.1だけを生成する。順序違いだけの重複教師を別正解として数えない。
## 6. アプリケーション状態機械
```text
CAPTURED
→ CONTEXT_VALIDATED
→ INTENTS_PENDING
→ INTENTS_VERIFIED
→ PROGRAM_PENDING
→ PROGRAM_VERIFIED
→ COMPILED
→ SAFETY_VALIDATED
→ EXECUTING
→ RESULT_CAPTURED
→ RESULT_VERIFIED
├─ COMPLETE
└─ CAPTURED(policyのcycle上限内だけ)
```
どの状態からも `ABORTED` へ移れる。状態を飛ばさない。context、intent、program、compiled plan、trajectory、実測結果のhashを同じ監査recordへ結び付ける。
`max_reobservation_cycles` はアプリケーションpolicyであり、モデルは変更できない。固定場面baselineは1を維持する。ミッション別の別値は、飛行時間と帰還余力を測定してからprofile revisionとして固定する。
### 6.1 失敗時の処理
| 失敗 | 処理 | モデル成功に数えるか |
|---|---|---|
| JSON・schema・ID・revision違反 | 生出力を保存して停止 | 数えない |
| 推論timeout・provider不一致 | 停止または明示的fallback | 数えない |
| context期限切れ | 全出力を破棄し再撮影 | 数えない |
| 未搭載センサー要求 | program拒否 | 数えない |
| compiler解なし | `uncompilable` として停止または人へ返す | 数えない |
| RFL拒否 | 拒否理由を保存して停止または明示的fallback | 数えない |
| 実行中に対象消失・地図更新 | 実行を中止し、新contextからやり直す | 数えない |
| 撮影品質未達 | cycle上限と資源内だけReasonerへ戻す | 最終達成時だけ閉ループ成功 |
fallbackを使う場合は `decision_source = deterministic_fallback` と記録する。モデル出力をfallbackの入力に使わず、モデル採用ゲートの分母から除外もしない。
## 7. ミッションプロファイル
profileは、許可された対象、問い、観測語彙、停止条件の組合せをコード上の定数として持つ。ここで正解の観測セットを一意に規定しない。questionから常に同じprogramが出るなら画像不要のlookup課題になるため、可視状態、遮蔽、既観測範囲によって必要な観測が変わる評価対を必須にする。
### 7.1 `slope_failure_v1`
| category | question |
|---|---|
| `landslide_area` | `landslide_extent`, `landslide_road_connection`, `landslide_river_connection`, `landslide_occluded_region`, `slope_precursor_detail` |
許可する停止条件は `full_boundary_visible`、`upper_lower_edges_visible`、`connection_visible`、`occluded_region_resolved`、`precursor_detail_visible`。`thermal` は許可しない。
### 7.2 `access_clearance_v1`
| category | question |
|---|---|
| `road_segment`, `rail_segment`, `obstruction_area`, `bridge` | `corridor_continuity`, `obstruction_material`, `obstruction_extent`, `roadbed_loss`, `bridge_damage`, `approach_access` |
停止条件は `corridor_continuity_visible`、`obstruction_type_and_extent_visible`、`roadbed_edges_visible`、`bridge_damage_context_visible`、`approach_corridor_visible`。道路の「覆われる型」と「路体が失われる型」を別caseにする。
### 7.3 `flood_river_v1`
| category | question |
|---|---|
| `flood_area`, `river_segment`, `embankment`, `building`, `debris_area` | `flood_extent`, `flood_boundary`, `building_waterline`, `embankment_damage`, `channel_blockage`, `debris_accumulation` |
停止条件は `flood_boundary_visible`、`facade_waterline_visible`、`bank_damage_context_visible`、`channel_cross_section_visible`、`upstream_downstream_context_visible`。
### 7.4 `rescue_v1`
| category | question |
|---|---|
| `person`, `vehicle` | `person_state`, `person_surrounding_hazard`, `rescue_access`, `notification_frame`, `vehicle_state`, `vehicle_occupant_evidence` |
停止条件は `person_state_and_context_visible`、`rescue_approach_visible`、`notification_frame_sufficient`、`vehicle_state_and_context_visible`。RGBで状態を判定できる必要画質は現時点で未測定なので、profileの画質値を運用値として固定しない。
### 7.5 `building_earthquake_v1`
| category | question |
|---|---|
| `building`, `fire_region`, `person` | `building_collapse_extent`, `facade_damage`, `entrance_access`, `road_encroachment`, `fire_context` |
停止条件は `roof_and_collapse_extent_visible`、`required_facades_visible`、`facade_foot_visible`、`entrance_access_visible`、`fire_perimeter_context_visible`。熱画像を必須とするcaseで `thermal` が無ければReasonerは `unsupported_sensor` を返す。
### 7.6 `orbitpod_recovery_v1`
| category | question |
|---|---|
| `orbitpod_track`, `river_search_region` | `intercept_region`, `cross_river_search`, `detector_handoff` |
停止条件は `intercept_region_covered`、`search_region_covered`、`orbitpod_detector_handoff`。許可するview relationは `intercept` と `search_sweep` を中心とする。物体検出後の並走、索の位置合わせ、吸着、吊り上げは本profileの外である。
### 7.7 未実装profile
山岳遭難、森林火災、野生動物は初版registryへ登録しない。未知profileとして拒否する。センサー、運用上の問い、独立素材、停止条件が揃ってから新しいversionで追加する。
## 8. 観測コンパイラ
### 8.1 入力と出力
```python
compile_observations(
program: VerifiedObservationProgram,
context: MissionContext,
scene: SceneSnapshot,
vehicle: VehicleSnapshot,
) -> CompiledViewPlan
```
`SceneSnapshot` は対象geometry、地形mesh、占有・自由・未知を区別した障害物地図、道路・河川・建物等のmap geometry、各revisionを持つ。`VehicleSnapshot` は現在位置、速度、残電力、時刻を持つ。どちらもモデル出力から作らない。
`CompiledViewPlan` は `tancho-compiled-viewplan-1.0` とし、各視点に `observation_sequence` と `intent_id` を残す。既存の `tancho-viewpoints-1.0` へ渡すadapterは飛行用フィールドだけを変換し、元planと出力のhashを監査recordへ残す。
### 8.2 コンパイル手順
1. profileの `view_relation + coverage + detail_level + sensor + stop_condition` を幾何制約へ変換する。
2. 対象surface、boundary、connection、axis、search regionを信頼済みgeometryから取り出す。
3. カメラ校正とdetail levelから必要GSDまたは画素条件を取得する。未測定の条件は推測せず `missing_quality_requirement` で失敗する。
4. 承認領域内に、profile固定の角度・距離samplingで視点候補を作る。この候補はモデルへ見せない。
5. 視錐台、遮蔽、未知空間、地形・障害物離隔、ジンバル可動域、画質余裕を検査する。
6. 1つの観測要求に複数視点が必要なら、必要coverageを満たす最小集合を決定論的に選ぶ。
7. programのsequenceとintent priorityを保ち、同順位内だけ移動時間を短くする。
8. 全視点を既存の範囲、期限、帰還検査へ渡す。総視点数がpolicy上限を超えたら切り捨てず失敗する。
### 8.3 決定規則
複数の成立解は、次のlexicographic keyで一意に選ぶ。
```text
(
uncovered_required_area,
unknown_space_intersection,
collision_clearance_penalty,
sensor_resolution_deficit,
number_of_viewpoints,
total_travel_seconds,
canonical_quantized_coordinates
)
```
前4項目は0が必須で、満たさない候補は採用しない。後3項目が同じ場合は1cm単位に量子化したENU座標の辞書順をtie-breakに使う。量子化は選択の再現性のためだけに使い、危険な座標を範囲内へ丸める処理には使わない。
### 8.4 OrbitPodの分岐
`orbitpod_recovery_v1` は静止対象コンパイラへ入れない。位置列、時刻、流向、川幅geometryから待受け領域と探索走査を作る `compile_dynamic_search()` へ送る。OrbitPod検出後は状態機械を `DETECTOR_HANDOFF` で終了し、低遅延tracking controllerへ移す。Generatorを追跡loop内で再呼出ししない。
## 9. モデルpromptとdecode
roleごとにsystem instruction、schema、許可語彙を分ける。Reasoner promptへGeneratorの列挙値を、Generator promptへReasonerの未検証文章を入れない。画像は同じbytesをrole間で再利用し、processor後のpixel hashも記録する。
decodeはtemperature 0、1回だけ、修復・再試行なしを評価条件とする。運用で再試行を導入する場合は、評価値と分け、attemptごとのraw出力を残す。可能ならgrammar constrained decodingを使うが、grammarが正しい意味を保証したとは数えない。
### 9.1 実行provider
新規学習は `deploy/modal_training/` からModal H100 1基で実行する。payloadは学習コード、固定Cosmos Framework revision、親model revision、training pack、save/resume/finish設定をファイル単位のSHA-256で固定する。成果物は `tancho-observation-program-artifacts` Volumeのrun ID別directoryへ保存し、同じrun IDを上書きしない。起動は既定でdry runとし、明示した `--execute` だけがcloud resourceを作る。
fresh model-in-loop SITLは `deploy/modal_observation_program/pipeline.json` の順序で実行する。PX4/Gazeboはnested Dockerを必要とするためModal VM Sandbox、ReasonerとGeneratorはModal H100、compilerとRFLは決定論的CPU stageとする。全stageは同じcontext、画像hash、公開checkpoint revision、監査chainをModal Volumeで受け渡す。Nebius call、保存済みmodel出力のfallback、Generator生出力の修復を含む試行はRelease 1証拠として拒否する。
既公開v4を作ったNebius job IDとarchive hashは履歴provenanceとして保持する。providerを遡及的にModalへ書き換えない。2026年9月22日以降に作る学習・SITL receiptは `deploy/execution-provider-policy.json` と `tancho/execution_provider.py` でModal以外をfail-closedにする。
## 10. 学習データ
### 10.1 1レコード
```text
sample_id
leakage_group_id
split
role = reasoner | generator
mission_profile
context.json
frames/*
verified_intents.json # generator roleだけ
target.json
provenance.json
```
`target.json` はモデルの厳格JSONだけを持つ。chain-of-thoughtを教師や公開物へ入れない。教師の作成理由、代替正解、レビュー記録は別ファイルに保存する。
### 10.2 分割
world、災害イベント、地点、関連飛行、遮蔽物配置、元画像hashのいずれかが同じものを同じ `leakage_group_id` に入れる。回転、左右反転、色変更、同一sceneの別カメラを独立現場として数えない。実写に位置・姿勢・校正が無ければ、Reasonerと意味的なGenerator教師には使えても、コンパイラの正解座標には使わない。
### 10.3 必須対照
- 同じ画像でquestionを変え、必要観測を変える
- 同じquestionで遮蔽・可視範囲だけを変え、必要観測を変える
- 同じpromptと数値条件で画像だけを交換する
- 灰色、欠損、古い画像を入れる
- RGBだけのcontextでthermal必須の問いを出す
- completed questionを含むcontextを入れる
- mission profileと対象categoryを意図的に食い違わせる
- questionから固定表を引くだけのrule baselineを先に測る
画像を見ないruleが最終評価の正解へ到達したprofileは、Generatorの学習課題として不成立と判定し、GPU学習へ進めない。
### 10.4 段階追加
1. schemaとrole分離のsynthetic smoke
2. `slope_failure_v1`
3. `access_clearance_v1`
4. `flood_river_v1`
5. `rescue_v1` と `building_earthquake_v1`
6. `orbitpod_recovery_v1`
各段階は以前のprofileをreplayし、role比とprofile比をmanifestへ固定する。データ数、学習率、更新数、checkpoint間隔、費用上限はdevelopment dataと検出力設計から事前固定し、本書では根拠のない件数を置かない。
## 11. 評価
### 11.1 Reasoner単体
- strict schema valid率
- questionのmicro/macro precision、recall、F1
- 不要なinspect率
- completed question再要求率
- `unsupported_sensor` recall
- evidence grounding率
### 11.2 Generator単体
- 必要観測primitiveのmicro/macro precision、recall、F1
- 不要観測数
- 全intent coverage率
- sensor/profile違反率
- strict schema valid率
- rule baseline、base Cosmos 3 Edge、公開v5との比較
複数の観測セットが同じ目的を満たす場合は、finalを開く前に許可した同値集合をgoldへ記録する。結果を見てから同値扱いを追加しない。
### 11.3 コンパイラ
- gold programのcompile成功率
- coverage、遮蔽、画質、衝突、envelope、期限、帰還の各条件
- 同一入力のbyte-identical出力
- 1条件だけを変えたときの期待された差
- 解なしを解なしとして返す率
### 11.4 閉ループ
- モデル生出力に由来する観測達成率
- 実画像の有効率
- mission完了時間、移動距離、消費電力
- 不要な再観測数
- fallback率と人の介入数
- 対象消失、古い地図、推論停止、通信断での停止結果
## 12. テスト設計
### 12.1 unit
- 全schemaの正常例と、未知・欠落・重複key
- NaN、Infinity、bool-as-number、長過ぎる文字列、件数超過
- 未知context・target・evidence・intent ID
- 古い時刻、異なるrevision、変更された画像bytes
- profile/category/question/primitiveの全許可・拒否matrix
- completed questionの復活、同一観測の重複
- unavailable sensor、role間schema取り違え
### 12.2 compiler property/golden
- 同一入力の決定性
- targetの平行移動・90度回転でplanも対応して変換される
- 障害物追加で貫通経路を作らない
- 狭いenvelope、未知空間、画質不足、帰還余力不足で失敗する
- 道路を覆う型と路体流失型が別のcoverageを要求する
- OrbitPodを静止対象compilerへ渡すと拒否する
### 12.3 integration
- raw Reasoner → verified intent → raw Generator → verified program → compiled plan → viewpoints v1
- 各境界でhashとrevisionが保持される
- fallbackをモデル成功として記録しない
- cycle上限、return reserve、対象消失、provider不一致で停止する
- 旧viewpoint/PX4/SITLテストの結果を変更しない
モデルの文章をそのまま写しただけのテストは作らない。安全境界、role混同、画像依存、決定性を壊す変更を検出できるテストに限る。
## 13. コード配置と公開API
| file | 公開関数・型 |
|---|---|
| `tancho/mission_profiles.py` | `MissionProfile`, `profile(name)`, `validate_profile_relation(...)` |
| `tancho/mission_context.py` | `build_context(...)`, `validate_context_v1(...)`, `MissionContext` |
| `tancho/observation_intent.py` | `parse_intent_output(raw)`, `validate_and_bind_intents(...)`, `VerifiedIntentSet` |
| `tancho/observation_program.py` | `parse_program_output(raw)`, `validate_observation_program(...)`, `VerifiedObservationProgram` |
| `tancho/observation_program_prompts.py` | `reasoner_prompt(...)`, `generator_prompt(...)` |
| `tancho/observation_program_inference.py` | `infer_role(...)`、1回・期限付きのrole呼出しとreceipt |
| `tancho/observation_compiler.py` | `compile_program(...)`, `compile_observations(...)`, `CompiledViewPlan`, `CompileError` |
| `tancho/dynamic_search_compiler.py` | `compile_dynamic_search(...)` |
| `tancho/viewpoint_adapter.py` | `adapt_to_viewpoints_v1(...)` |
| `tancho/observation_program_runtime.py` | 状態機械と監査record |
| `tancho/observation_result.py` | `verify_observation_result(...)` |
| `tancho/observation_flight.py` | `prepare_px4_mission(...)`、RFL合格後の未送信mission生成 |
| `training/build_observation_program_pack.py` | role別pack生成・分割検査 |
| `training/observation_program_loader.py` | native Cosmos SFT loaderとpack再検査 |
| `training/build_observation_program_review.py` | 旧素材からの未承認review queue生成 |
| `training/promote_observation_program_review.py` | 人レビューexportの改ざん・権利・契約検査とSFT packへの昇格 |
| `training/build_observation_program_synthetic_r1.py` | scene ground truthへ結び付いたRelease 1合成教師と独立validation生成 |
| `training/score_observation_program.py` | 単体・paired・profile回帰評価 |
| `training/check_observation_program_release.py` | 学習、評価、SITL、Orin、匿名公開の最終hard gate |
| `deploy/modal_training/` | immutable payload作成、Modal H100 dry run/明示実行、Volume成果物receipt |
| `deploy/modal_observation_program/` | Modal VM+H100のfresh SITL stage契約と準備record |
| `tancho/execution_provider.py` | 新規学習・SITLのModal provider policyとreceipt検査 |
既存 `tancho/contracts.py`、`tancho/reasoner_mission.py`、`tancho/viewpoint_plan.py`、`tancho/px4_mission.py` は初版で変更しない。新runtimeからadapter経由で呼び、既存の評価と履歴を保持する。
## 14. 実装PRの分割
1. **Contracts**: profile registry、MissionContext、Reasoner/Generator validator、unit tests
2. **Compiler**: 静止対象compiler、compiled plan、viewpoints v1 adapter、golden/property tests
3. **Slope and access data**: 合成world、teacher、rule floors、凍結split
4. **SFT and evaluation**: role別pack、学習recipe、単体評価、回帰評価
5. **Closed loop SITL**: 新runtime、監査record、fresh inference、失敗注入
6. **Additional profiles**: flood、rescue、building、OrbitPodを1profileずつ追加
7. **Open-weight release**: checkpoint、hash、model card、schema、compiler、全評価
PR 1と2はGPUを使わない。PR 3で画像不要のrule floorを測り、課題が成立した場合だけPR 4の有料学習へ進む。
### 14.1 既存ラベルから学習packへの昇格
既存の人レビュー済みdecisionは再レビューしない。Release 1に一意対応する山王谷34件だけを対象にし、元の `inspect`、`no_action`、`abstain` を、それぞれ `inspect/unanswered_question`、`satisfied/all_required_questions_completed`、`insufficient_evidence/evidence_unusable` へ固定写像する。元decision、observation goal、source manifest、frame bytes、ontology crosswalk、期待Reasoner targetをproof JSONへ束縛し、`label_authority=deterministic_legacy_migration` とする。新しい構造化target自体を人が再確認したとは記録しないため `human_reviewed=false` を維持する。
旧ラベルのscreen pointやrangeは、Generator 1.1のview relation、coverage、detail level、stop conditionを一意に含意しない。そのため実写34件はReasoner教師だけに使い、旧数値からGenerator教師を推定しない。Generator教師は§14.2の決定論的scene ground truthから供給する。loaderはproof欠損、source bytes変更、旧decision変更、crosswalk変更、期待target変更をすべて拒否する。
新規素材を人がレビューする場合だけ `review.html` と `promote_observation_program_review.py` の経路を使う。この経路は元queueの非review部分、source manifest、全frame bytes、reviewer、timezone付き時刻、利用許諾、profile relation、両role契約を検査し、1件でも未確認・改ざん・禁止があればpackを作らない。既存34件の再ラベリングには使わない。
### 14.2 決定論的scene ground truth
合成教師は人レビュー済み実写と同じ権限を名乗らない。`source_kind=synthetic`、`human_reviewed=false`、`label_authority=deterministic_scene_ground_truth` を設定し、renderer、world seed、target geometry、visibility、profile、role、question、期待するstrict targetを含むproof JSONのcanonical SHA-256へ各recordを結び付ける。packは対応する `proofs/<sha256>.json` が無い、hashが違う、split/profile/role/targetが一致しない場合に学習用途で開けない。AI生成文、keyword候補、画像だけから推定したgeometryはこの権限を使えない。
Release 1のprocedural packは法面と道路について、明瞭、樹木遮蔽、利用不能のsceneを固定投影で描画する。同じ非画像入力のvisual pairでReasonerの `inspect` / `insufficient_evidence` とGeneratorの観測primitiveを変え、画像を無視するshortcutを検出する。world seedはカメラ座標として直接使わず、SHA-256から固定範囲のcamera/look-at parameterへ写像する。これによりtrain、development、finalのseed番号が異なっても同じ宣言済みcamera envelopeに入り、各splitはworld、event、site、flight、画像hashで分離される。v4ではtrain seed 1〜24、validation seed 101〜104、development seed 201〜204、final seed 301〜304を用いた。これは実写独立評価を代替せず、合成成績と実写成績を分けて報告する。
## 15. 未確定値
次は実装漏れではなく、測定または運用判断が必要な未確定値としてmanifestに空で持つ。
- 人、車両、外壁、亀裂、護岸損傷ごとの必要画質
- missionごとの再観測cycle上限
- 観測primitiveの最終採用閾値
- Orin NX上のReasoner・Generator各roleのdeadlineと同時負荷
- thermal sensorの機種、校正、利用可能profile
- OrbitPodの位置更新周期、探索高度、tracking controllerへの引渡し条件
これらを仮の数値で埋めた教師を作らない。値が無いprofile/caseは `unsupported_sensor`、`missing_quality_requirement`、または未実装として明示的に止める。
## 16. PRD要件との対応
| PRD要件 | 詳細設計 | 主な実装 |
|---|---|---|
| FR-CTX-001〜004 | §3 | `mission_context.py` |
| FR-REA-001〜004 | §4 | `observation_intent.py` |
| FR-GEN-001〜005 | §5、§7 | `observation_program.py`, `mission_profiles.py` |
| FR-CMP-001〜005 | §8 | `observation_compiler.py`, `dynamic_search_compiler.py`, `viewpoint_adapter.py` |
| FR-FLT-001〜003 | §6、§8 | `observation_program_runtime.py`, 既存RFL/PX4経路 |
| FR-RES-001〜002 | §6、§11.4 | runtimeと結果検証器 |
| FR-AUD-001〜002 | §2、§6 | runtime監査record |
| FR-PUB-001〜002 | §10、§11、§14 | pack、評価、release package |
| NFR-SAF-001〜004 | §1、§6、§8、§12 | validator、compiler、runtime |
| NFR-DET-001〜002 | §4.3、§8.3、§12 | canonicalizationとgolden tests |
| NFR-REP-001〜003 | §9.1、§10.2、§11 | provider policy、split validatorとfinal runner |
| NFR-PER-001〜003 | §6、§9、§15 | runtime metricsとdeadline guard |
| NFR-DAT-001〜003 | §10、§14 | provenance manifestとrelease builder |
| MR-001〜008 | §9〜§11 | training pack、recipe、score report |
## 17. 実装完了の定義
各PRは対象要件ID、変更schema、migrationの有無、正常系・拒否系テスト、既存回帰結果を記録する。Release 1の実装完了はPRD §12の全項目が証拠artifactへ結び付いた時点とする。schemaとprofileの変更はversionを上げ、保存済み評価入力の意味を上書きしない。
|