データと状態
assets/example-trip.json は架空のテスト用。実旅行に流用する際はbrief.demoをfalseにし、fixture根拠を全て実際の調査へ置換する。ここにあるサンプルの承認は実ユーザー承認ではない。
コマンド
python scripts/trip.py init CASE
python scripts/trip.py check CASE --stage candidates
python scripts/trip.py select CASE --candidate lake --user-note "会話で実際に受け取った選定"
python scripts/trip.py check CASE --stage plan
python scripts/trip.py approve CASE --user-note "実際に受け取った計画承認"
python scripts/trip.py export CASE --out OUTPUT-V1
python scripts/trip.py export CASE --out PUBLIC-V1 --audience public
python scripts/trip.py verify-export CASE --out OUTPUT-V1
python scripts/trip.py status CASE
実行時のscriptsはスキルフォルダを基準にする。CASEと出力は任意のプロジェクト内の絶対/相対パス。出力先が既存なら拒否する。caseへの変更は正本JSONを編集し、status/checkで失効範囲を確認。
主なデータ
- brief: id,title,origin_region,start,end,mode(car/rail),time_scope(door_to_door/ride_only),max_one_way_minutes,budget_yen,rest_minutes_per_day,return_by,family_label,members,hard_conditions,meal_windows。日付はYYYY-MM-DD、日時は国内ローカルYYYY-MM-DDTHH:MM。hopesは任意の[{member,want,avoid,basis}]。basisはstated(本人の発言)/inferred(推測)を必須とし、推測は画面にも明記する。
- sources: id,claim,url,source_type(operator/transport/government/tourism/route_provider),status,checked_on,recheck_on,applies_on[]。verified以外の根拠は確定選定/承認には使えない。
- candidates: id,title,mode,nights,available,source_ids,conditions{hardId:{met,source_ids}},outbound,return,costs,why,tradeoff。候補と個別conditionにはapplies_on[]を指定できる。候補の既定は旅行全日、conditionの既定は候補の適用日。実際に訪れる日を指定し、旅行期間外の日は許可しない。
- route: mode,status(verified/estimated/unverified),depart_at,from_id,to_id,source_ids,parts{ride,walk,wait,transfer,buffer,rest}。全部整数分・0可、ride>0。合計は計算し、別の総時間フィールドを正本にしない。
- costs: id,category,label,min_yen,max_yen,basis(estimated/quoted/confirmed),note,source_ids。categoryはtransport/food/activity/contingencyを必須、1泊ならlodgingも必須(無料なら0)。家族全体の税込/税別や範囲をnoteへ。高速・燃料・駐車など内訳の不足は調査者が確認。
- plan: title,promise,activities,tasks,costs,rain_plan,exit_plan,decisions[{at,if,then}]。
- activity: id,kind(visit/meal/rest/travel/stay/buffer/free),title,start,end,note,location_label,source_ids。非travelはplace_id。visit/meal/stayはwindow{start,end}、travelはroute、stayはreservation_status(unbooked/confirmed)。map_urlは任意のhttpsリンク。往復移動は候補のrouteと同じものを参照し、場所が変わるなら移動枠を入れる。毎日少なくとも食事1枠、必要な食事時刻はmeal_windowsで追加制約する。
- tasks: id,kind(packing/discussion/booking/recheck),phase(before/morning/onsite),owner(メンバー記号/未定),title,reason,quantity,status(todo/done/not_needed)。物以外はquantityに「1回」「出発前に」など必要量を記す。未予約のstayごとにactivity_idが一致するbooking/before/todoの手配タスクが必要。
- media: id,kind(photo/generated/official_link),slot(hero/place/food/rest),caption,alt。画像の場合asset(case内相対パス),rights(owned/licensed/permission/generated),rights_note。photoはsource_url,checked_on,captured_on(null可)。official_linkはsource_urlのみ。public版の画像はpersonal=falseが明示されたものだけ。place_idでactivityと結び付けられる。rights_noteは証拠管理用で出力しない。
失効範囲
| 変更 | 選定 | 詳細承認 | 出力 |
|---|---|---|---|
| brief/選んだ候補/その候補が参照する根拠の主張・適用日 | 再選定 | 失効 | 新版 |
| 詳細行程・予算・担当・準備 | 維持 | 失効 | 新版 |
| 根拠の確認日/再確認日だけ、事実変更なし | 維持 | 維持 | 更新推奨 |
| 画像のみ | 維持 | 維持 | 利用条件を再検査して新版 |
| 不採用候補のみ | 維持 | 維持 | 必要時のみ |
選定ハッシュは選定候補から参照する出典だけ、詳細承認は選定候補とplanが参照する出典だけを含む。無関係な出典の追加で再選定を要求しない。verify-exportは出力ファイル、媒体情報、埋め込んだ画像の内容も検査する。
v1ではbriefを承認の単位にするため、hopesやfamily_labelの変更も再選定・再承認になる。希望を変更した後の候補妥当性を見落とさない保守的な扱い。media.place_idはactivity.idへの対応キーで、activity.place_id(場所を表すキー)とは異なる。
端末内のチェックはtrip idとtask idで継続し、タイトル・数量・種別・時期・担当・理由・計画上の状態が同じタスクだけ引き継ぐ。内容が変わったタスクは再確認のためリセットする。別端末とは同期しない。
期限が切れた根拠は新規承認・出力を止める。出力済みのローカルHTMLは消さず、期限切れを画面に表示して閲覧可能にする。実際の確認なしにチェック日だけ更新しない。
保存と公開
既定audience=familyはローカル/認証付き共有向けで旅行日が含まれる。publicは日付・出発地域・家族ラベル/担当記号・希望・人物写真を除くが、自由文から個人情報を完全に検出できるわけではない。private.jsonの4文字以上の値と一致する公開文は出力を拒否する。公開前に自由文も目視確認する。予約番号・正確な住所はそもそもtrip.jsonに入れない。
publicは匿名化した紹介・作例向け。再確認日も伏せるため、HTML単独の期限切れ警告はない。実旅行の当日利用にはfamily版を使い、出発前にハーネスで再検査する。どちらもライブ情報を自動取得・更新するページではない。
ハッシュは意図しない変更の検出。ローカルファイルを自由に書ける相手の改ざん防止/本人認証ではない。user-noteは会話から記録し、エージェントが承認を作らない。