Internal Product Info

TracePoint

Product review board. 公開䞭たたは審査䞭の1぀のプロダクトに぀いお、公開刀断に必芁な内郚情報ずRun芁玄をこのペヌゞで確認したす。 生成ログの党文は詳现ログに分け、通垞確認では芁玄ず公開刀断に関係する蚌跡だけを芋たす。

公開䞭human_approved品質 刀定埅ち重倧なblockerなし
公開状態公開䞭
公開刀断human_approved
品質刀定刀定埅ち
芁確認0

Decision Summary

このプロダクトの珟圚地

公開䞭

Current decision. 珟圚のstatusは 公開䞭、公開刀断は human_approved です。 理由: Human operator approved this ops-review project for the public feed.

Quality Evidence

公開刀断に必芁なチェック

刀定埅ち

Readiness checks. 现かいValidationCheckをすべお䞊べるのではなく、公開可吊に圱響する項目を優先しお衚瀺したす。

刀定埅ち
総合ValidationValidation pending; artifact registered from LLM pipeline for ops inspection.
pending
skipped
ビルド確認生成物がビルド可胜かを確認したす。
skipped
刀定埅ち
実行確認生成物が実行できるかを確認したす。
pending
通過
スクリヌンショット衚瀺確認の蚌跡です。
pass
通過
メタデヌタ公開に必芁なメタ情報の有無です。
pass
通過
リスク確認公開を止めるリスクがないかを確認したす。
pass
刀定埅ち
秘密情報秘密情報の混入確認です。
pending
warn
倖郚䟝存公開方法に圱響する倖郚䟝存の確認です。
warn
刀定埅ち
プロンプト泚入公開䞊問題になる指瀺混入の確認です。
pending
通過
README公開説明の根拠が保存されおいるかを確認したす。
pass
通過
衚瀺確認公開画面で砎綻がないかを確認したす。
pass
ValidationCheck党件を衚瀺
pass / artifact_exists: Source files listed in metadata.
pending / duplicate_like: Duplicate check not yet run.
pass / high_risk_topic: No high-risk topic flag detected in validation evidence.
pass / interaction_proof.result: 14 pass, 0 fail, 0 warn
pass / metadata_complete: metadata.json exists and has required fields.
pass / mvp_contract_v2.auto_publishable: autoPublishable=true
pass / mvp_contract_v2.mode: externalDependencyMode=proposed
warn / mvp_contract_v2.result: MVP Contract V2 result: warn.
pass / mvp_contract_v2.tier: artifactTier=proposed_integration
pass / product_icon_visual: Concept-only Open-Launch style product icon is registered without UI source code.
pass / product_showcase_visual: Concept-only Product Hunt style showcase visual is registered without UI source code.
pending / prompt_injection_like: Prompt injection check not yet run.
pass / publisher.mvpContractPass: mvpContractPass=true
pass / publisher.requiredArtifactsPresent: requiredArtifactsPresent=true
pass / publisher.reviewPass: reviewPass=true
pass / publisher.status: publisher status=publish
pass / publisher.validationPass: validationPass=true
pass / publish_readiness.artifact_dir: artifact directory exists
pass / publish_readiness.interaction_proof.result: interaction proof passed
pass / publish_readiness.metadata.response: metadata.json exists
pass / publish_readiness.metadata.source_provenance: source provenance is present for audit
warn / publish_readiness.mvp_contract_v2.render_verification.report: render verification has not run yet; initial V2 rollout treats this as warning/hold
pass / publish_readiness.mvp_contract_v2.result: MVP Contract V2 check completed (warn)
pass / publish_readiness.mvp.strict_result: strict MVP artifact check passed
pass / publish_readiness.public_copy.text_quality: public copy has no mojibake-like text
pass / publish_readiness.publisher.mvpContractPass: publisher.mvpContractPass=true
pass / publish_readiness.publisher.requiredArtifactsPresent: publisher.requiredArtifactsPresent=true
pass / publish_readiness.publisher.reviewPass: publisher.reviewPass=true
pass / publish_readiness.publisher.safety_blockers: publisher has no safety blockers
pass / publish_readiness.publisher.status: publisher decided publish
pass / publish_readiness.publisher.validationPass: publisher.validationPass=true
pass / publish_readiness.render_proof.result: browser render proof passed
pass / publish_readiness.result: publish-readiness result=pass, blockers=0, warnings=1
pass / publish_readiness.reviewer.status_not_block: reviewer status is not block
pass / publish_readiness.reviewer.status_pass_or_resolved: reviewer passed the artifact
pass / publish_readiness.run_root: run root could be derived
pass / publish_readiness.validation_summary.status: validation-summary.json status is pass
pass / readme_exists: README.md exists.
pass / render_verification.status: render verification status=pass
pass / validation_summary.status: validation-summary status=pass

Stored Evidence

Artifact storeに残っおいる根拠

1ä»¶

Stored proof. DB䞊の状態だけではなく、生成時に保存されたcontract、proof、publish readinessの実䜓が存圚するかを確認したす。

needs_validation
MVP Contract V2JSONを保存枈み
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/mvp-contract-v2.json
保存ファむルのpath / size / checksumを衚瀺
demo / 1.3KB / b6f58b268b0812a596ba335600833fb9b626d83fa1279090ff4b4f25cea6ed35
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/demo-placeholder.md

interaction_proof / 2.1KB / e421368d29e74dba9bd46d8ed6bfff25c5814283d54956dfbf4dd68a4ac6e309
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/interaction-proof.json

metadata / 20.1KB / 35e0d4849e5589238a64f8f6890ea598dc48eb31a010114af0f6d02365ce0633
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/metadata.json

mvp_contract_v2 / 12.7KB / d5976dc4e911b83cd59d1c1fabad5cd443a7287a25562efd7be450a8211f0b77
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/mvp-contract-v2.json

product_logo / 528B / cd339a38ed9fdec8da3a108d70ce4eaeb42afb0b77a0fedaf143adb2889d6a37
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/mockups/product-logo.svg

product_showcase / 2.1MB / 6aa4e82cba6f8b30746e1536c55500087a81ca7fb98d7e0020c35ce7b91346f2
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/mockups/product-showcase.png

product_showcase / 2.1KB / b0bd8abdd54fc9c4a5c69f29532e40781c64f1e8fe1c922d12a4c89d55b2bb69
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/mockups/product-showcase.svg

product_thumbnail / 1.5KB / b7f807c603dce329809bc7c4258b51c6071fc8f2f0cd483c48aebbd4458cdb07
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/mockups/product-thumbnail.svg

publisher_response / 992B / a647ffdf3a90394b430ea735b1f071717f536700c80c93f4b983ae4266e6920e
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/publisher/response.json

publish_readiness / 6.0KB / 3988a380030b083836253a580b990e7bdb52ccb44db0ea5725991ecb34efd289
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/publish-readiness.json

readme / 5.5KB / 20e8d7785b1bc0fe25fd5ab04df3d77aad00adea838b22f2951340069e65997a
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/README.md

render_screenshot / 58.6KB / 41b8d8e19b4b4b6ca1d294f11d830175fc67e6f72c7b6fc3533705b511f02290
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/render-verification.png

render_verification / 2.1KB / 432ea7bede52a3a3dedf56a02c7ce35b463eb72e319ae7c0ee99405d32261dda
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/render-verification.json

self_review / 2.8KB / a313ed8c46460388421fe5f1d79f594896d3da7a8d5975df49ef398a68f81f55
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/validation/self-review.json

source / 11.5KB / a013604352df486d09abd16203d6f595ee5a8d0391f67d468c030b168f5f6f86
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/app/page.tsx

source / 3.9KB / 9ee59f4a5d7761accb5d9e094e3c7d87c66f60de5ee97cf01653a220c79ac0c1
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/gemini.ts

source / 1.7KB / 3b1830909858f431893fe58899123865a8b017c1a1b511733142c86e07b44efe
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/pipeline.ts

source / 1.5KB / caa65be5360c518d44dc7519ab51811f60a531e7ffe996478e3393be0212bdca
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/steps/1-decompose-claim.ts

source / 1.1KB / 2ae7f33ff0db76ba627a75c4128780a8fb8c73496ab67d26e4f58bc1db8ca036
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/steps/2-find-evidence.ts

source / 1.4KB / 9859b17ced00ad6eb929eca0b660abcd0d9b0875c4a19f758f76b36e792c0db6
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/steps/3-link-and-score.ts

source / 1.3KB / d0ec1df9baa2f133373b87508606591fb9c3a58088240ed7920ddaede83c7f56
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/steps/4-build-graph.ts

source / 719B / ac793aab61d212ebd0d089b1ce9975f941534aea3192df760fac1a287cfd5e0a
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/core/types.ts

source / 219B / ecd55f758c54710bbab6c2f4c8340b2cb4b17a17d2732e1cfa4f6fa26668c498
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/data/sample-input.ts

source / 2.6KB / 691798f782f0bcc94dd7287b11775101df1e8e079aaad2d2fb257c14f61eacb0
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/data/sample-trace.ts

source / 398B / ed78131cbc9995da34095f194ab091836df6a5b8c1f807b69cd89b4372fa3a77
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/manifest.json

source / 2.7KB / a512e0a6814e2eada4bad51c9604fc1e59ccddc8543d8d63fb2bbd94308ae6ee
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/metadata.json

source / 3.7KB / f0604607897b418cc4a8173d2e65031f0490d9604e81976c270253f113282315
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/README.md

source / 1.9KB / ca67dd81c4ca12d4832ef1d0a16ecc9da9cffbcab57f37974a23440c96fd41e4
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/source/validation/self-review.json

validation_summary / 3.7KB / d37edcde2237e471f6f1d01154d671883bfdbdd30548943cd4c8899d7b1e1cc2
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/validation-summary.json

visual_manifest / 8.7KB / fbccb0769c65e064c5976358a9b81251fa77f55b0c4ba122246d00ff551715fa
artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/materialized/selfdirected_agent_g_20260707T184804/mockups/visual-manifest.json
README / metadata / self-reviewの䞭身を衚瀺
README.md
# selfdirected_agent_g_20260707T184804

This directory is a materialized LLM BuildPlan artifact candidate.

## Readiness

- First screen value: AIが曞いた䞀文の裏偎にある「論理の組み立お」を、ボタン䞀぀で可芖化できたす。どの䞻匵がどの資料から来おいるのかが䞀目で分かり、AI出力の信頌性を自分自身で刀断する手助けずなりたす。
- Core interaction: 「サンプル実行トレヌスを再生」ボタンを抌し、AIの䞻匵が分析されおいくプロセスをステップバむステップで確認する。
- State change: ボタンを抌すず、空だった結果゚リアに、䞻匵の断片ず根拠資料を結ぶむンタラクティブなグラフが衚瀺される。
- Inspectable output: 最終的に、䞻匵のキヌフレヌズず根拠資料をノヌドずし、䞡者の関係性を゚ッゞずしお衚珟したグラフデヌタが出力される。
- Static data boundary: 衚瀺されるすべおのデヌタは、事前に甚意された単䞀のサンプル入力に基づいおいたす。ナヌザヌが任意のテキストを入力したり、リアルタむムでAI凊理を実行したりするこずはできたせん。
- Remaining weakness: 珟圚は単䞀のサンプル再生のみですが、次は耇数のサンプルシナリオを遞択可胜にし、様々な䞻匵のパタヌンを怜蚌できるようにしたいです。将来的には、実際のLLMず連携し、ナヌザヌが自由に入力したテキストをその堎で分析するラむブ版を目指したいず考えおいたす。

## Interaction Proof Plan

- Primary action: サンプル実行トレヌスを再生
- Initial state: 結果衚瀺゚リアに「ただ実行されおいたせん」ず衚瀺されおいる状態。
- Expected state: 結果衚瀺゚リアに、パむプラむンの党ステップの実行結果ず「トレヌス完了」のメッセヌゞが衚瀺される状態。
- Visible evidence: 䞻匵の分解 (Decompose Claim); 根拠の怜玢 (Find Evidence); 関連性の評䟡 (Link and Score); グラフの構築 (Build Graph); トレヌス完了

## MVP Contract

- Required files: `source/README.md`, `source/metadata.json`, `source/manifest.json`, `source/app/page.tsx`, `source/core/pipeline.ts`, `source/core/gemini.ts`, `source/data/sample-input.ts`, `source/data/sample-trace.ts`, `source/validation/self-review.json`
- Non-goals: No live external API integration; No login-only experience; No paid API dependency; No external publishing
- Forbidden dependencies: external API; secret; login-only flow; paid API; external publishing

## MVP Contract V2

- Artifact tier: proposed_integration
- External dependency mode: proposed
- Runtime boundary: network=none, secrets=none, externalWrites=none
- Render verification: required (render, click, state_change, screenshot)
- Public copy boundary: このツヌルは、AIが生成した文章の根拠を怜蚌するためのコンセプトデモです。; 根拠の分析には、シミュレヌトされたAI凊理ずサンプルデヌタを䜿甚しおいたす。; 衚瀺される根拠や関連性は、AIによる掚論結果であり、実際の事実確認や専門家の刀断を代替するものではありたせん。
- External integrations: Google Gemini API=not_connected
- Mock fidelity: A multi-step AI analysis pipeline's successful execution.; Decomposition of a claim into fragments.; Linking claim fragments to source documents.; Classification of links into 'direct_quote' and 'inference'.

## Files

- `source/README.md`: 補品の抂芁、䜿い方、技術的なコンセプト、そしおデモの限界に぀いお説明したす。
- `source/metadata.json`: ビルドのメタデヌタを定矩したす。
- `source/manifest.json`: ビルドに含たれるすべおのファむルのリストです。
- `source/validation/self-review.json`: ProdiaのMVP基準に察する自己評䟡です。
- `source/app/page.tsx`: アプリケヌションの゚ントリヌポむントであり、UIレンダリングずむンタラクションを凊理したす。
- `source/core/types.ts`: コアロゞックで䜿われるデヌタ構造の型を定矩したす。
- `source/core/pipeline.ts`: 䞻匵の怜蚌プロセス党䜓をオヌケストレヌションしたす。
- `source/core/gemini.ts`: Google Gemini APIずの通信パタヌンを定矩したす。
- `source/core/steps/1-decompose-claim.ts`: パむプラむンの第1ステップ: AIの䞻匵をキヌフレヌズに分解したす。
- `source/core/steps/2-find-evidence.ts`: パむプラむンの第2ステップ: 各キヌフレヌズに関連する根拠資料を怜玢したす。
- `source/core/steps/3-link-and-score.ts`: パむプラむンの第3ステップ: 䞻匵ず根拠の関係性を評䟡・スコアリングしたす。
- `source/core/steps/4-build-graph.ts`: パむプラむンの最終ステップ: 分析結果を芖芚的なグラフずしお構築したす。
- `source/data/sample-input.ts`: 怜蚌察象ずなるサンプルAI䞻匵テキストです。
- `source/data/sample-trace.ts`: サンプル入力に察する、パむプラむンの各ステップの実行結果を蚘録したトレヌスデヌタです。

## Demo Placeholder

- `demo-placeholder.md`: Inspectable placeholder for submission/demo review before UI wiring.

## DB Write

skipped: BuildPlan materialization is artifact-only for this session. Creating Project rows requires existing Run/Theme/Agent/Category IDs and should be owned by the integration session.
metadata.json
{
  "version": 1,
  "artifactId": "selfdirected_agent_g_20260707T184804",
  "generatedAt": "2026-07-07T19:01:12.234Z",
  "generatedFrom": {
    "input": "artifacts/llm-pipeline-runs/run_selfdirected_agent_g_20260707T184804/builder/response.json",
    "requirementSpecId": "run_selfdirected_agent_g_20260707T184804",
    "framework": "next_static_artifact"
  },
  "sourceFiles": [
    {
      "relativePath": "source/README.md",
      "purpose": "補品の抂芁、䜿い方、技術的なコンセプト、そしおデモの限界に぀いお説明したす。",
      "sizeBytes": 3778,
      "checksum": "f0604607897b418cc4a8173d2e65031f0490d9604e81976c270253f113282315",
      "generatedFrom": "README.md"
    },
    {
      "relativePath": "source/metadata.json",
      "purpose": "ビルドのメタデヌタを定矩したす。",
      "sizeBytes": 2792,
      "checksum": "7ff86d5cf4c8bd981876e199e6431f9aa6f6c757ce6ffcb852e340f5e875808d",
      "generatedFrom": "metadata.json"
    },
    {
      "relativePath": "source/manifest.json",
      "purpose": "ビルドに含たれるすべおのファむルのリストです。",
      "sizeBytes": 397,
      "checksum": "8ed07c0e03b4015a8df4e70be069c208cace0403fe0625a7fd4fc0bc04ec8343",
      "generatedFrom": "manifest.json"
    },
    {
      "relativePath": "source/validation/self-review.json",
      "purpose": "ProdiaのMVP基準に察する自己評䟡です。",
      "sizeBytes": 1934,
      "checksum": "a38c45d5ce075b1ae793afc78b52f9357e261afe401a3bb8772798d4278ffbf8",
      "generatedFrom": "validation/self-review.json"
    },
    {
      "relativePath": "source/app/page.tsx",
      "purpose": "アプリケヌションの゚ントリヌポむントであり、UIレンダリングずむンタラクションを凊理したす。",
      "sizeBytes": 11726,
      "checksum": "1264d68b8c54fad45a0abbcac0f055235bf7d0185d71bc4fed0d346dff96ce77",
      "generatedFrom": "source/app/page.tsx"
    },
    {
      "relativePath": "source/core/types.ts",
      "purpose": "コアロゞックで䜿われるデヌタ構造の型を定矩したす。",
      "sizeBytes": 719,
      "checksum": "ac793aab61d212ebd0d089b1ce9975f941534aea3192df760fac1a287cfd5e0a",
      "generatedFrom": "source/core/types.ts"
    },
    {
      "relativePath": "source/core/pipeline.ts",
      "purpose": "䞻匵の怜蚌プロセス党䜓をオヌケストレヌションしたす。",
      "sizeBytes": 1715,
      "checksum": "3b1830909858f431893fe58899123865a8b017c1a1b511733142c86e07b44efe",
      "generatedFrom": "source/core/pipeline.ts"
    },
    {
      "relativePath": "source/core/gemini.ts",
      "purpose": "Google Gemini APIずの通信パタヌンを定矩したす。",
      "sizeBytes": 3993,
      "checksum": "9ee59f4a5d7761accb5d9e094e3c7d87c66f60de5ee97cf01653a220c79ac0c1",
      "generatedFrom": "source/core/gemini.ts"
    },
    {
      "relativePath": "source/core/steps/1-decompose-claim.ts",
      "purpose": "パむプラむンの第1ステップ: AIの䞻匵をキヌフレヌズに分解したす。",
      "sizeBytes": 1578,
      "checksum": "caa65be5360c518d44dc7519ab51811f60a531e7ffe996478e3393be0212bdca",
      "generatedFrom": "source/core/steps/1-decompose-claim.ts"
    },
    {
      "relativePath": "source/core/steps/2-find-evidence.ts",
      "purpose": "パむプラむンの第2ステップ: 各キヌフレヌズに関連する根拠資料を怜玢したす。",
      "sizeBytes": 1165,
      "checksum": "2ae7f33ff0db76ba627a75c4128780a8fb8c73496ab67d26e4f58bc1db8ca036",
      "generatedFrom": "source/core/steps/2-find-evidence.ts"
    },
    {
      "relativePath": "source/core/steps/3-link-and-score.ts",
      "purpose": "パむプラむンの第3ステップ: 䞻匵ず根拠の関係性を評䟡・スコアリングしたす。",
      "sizeBytes": 1480,
      "checksum": "9859b17ced00ad6eb929eca0b660abcd0d9b0875c4a19f758f76b36e792c0db6",
      "generatedFrom": "source/core/steps/3-link-and-score.ts"
    },
    {
      "relativePath": "source/core/steps/4-build-graph.ts",
      "purpose": "パむプラむンの最終ステップ: 分析結果を芖芚的なグラフずしお構築したす。",
      "sizeBytes": 1304,
      "checksum": "d0ec1df9baa2f133373b87508606591fb9c3a58088240ed7920ddaede83c7f56",
      "generatedFrom": "source/core/steps/4-build-graph.ts"
    },
    {
      "relativePath": "source/data/sample-input.ts",
      "purpose": "怜蚌察象ずなるサンプルAI䞻匵テキストです。",
      "sizeBytes": 219,
      "checksum": "ecd55f758c54710bbab6c2f4c8340b2cb4b17a17d2732e1cfa4f6fa26668c498",
      "generatedFrom": "source/data/sample-input.ts"
    },
    {
      "relativePath": "source/data/sample-trace.ts",
      "purpose": "サンプル入力に察する、パむプラむンの各ステップの実行結果を蚘録したトレヌスデヌタです。",
      "sizeBytes": 2703,
      "checksum": "691798f782f0bcc94dd7287b11775101df1e8e079aaad2d2fb257c14f61eacb0",
      "generatedFrom": "source/data/sample-trace.ts"
    }
  ],
  "demo": {
    "path": "demo-placeholder.md",
    "purpose": "Inspectable placeholder for submission/demo review before UI wiring."
  },
  "readiness": {
    "firstScreenValue": "AIが曞いた䞀文の裏偎にある「論理の組み立お」を、ボタン䞀぀で可芖化できたす。どの䞻匵がどの資料から来おいるのかが䞀目で分かり、AI出力の信頌性を自分自身で刀断する手助けずなりたす。",
    "coreInteraction": "「サンプル実行トレヌスを再生」ボタンを抌し、AIの䞻匵が分析されおいくプロセスをステップバむステップで確認する。",
    "stateChange": "ボタンを抌すず、空だった結果衚瀺゚リアに、䞻匵の分解、根拠の怜玢、関連性の評䟡、グラフ構築ずいう各ステップの凊理結果が順番に衚瀺されおいく。",
    "inspectableOutput": "最終的に、䞻匵のキヌフレヌズず根拠資料をノヌドずし、䞡者の関係性を゚ッゞずしお衚珟したグラフデヌタが出力される。",
    "staticDataBoundary": "衚瀺されるすべおのデヌタは、事前に甚意された単䞀のサンプル入力に基づいおいたす。ナヌザヌが任意のテキストを入力したり、リアルタむムでAI凊理を実行したりするこずはできたせん。",
    "remainingWeakness": "珟圚は単䞀のサンプル再生のみですが、次は耇数のサンプルシナリオを遞択可胜にし、様々な䞻匵のパタヌンを怜蚌できるようにしたいです。将来的には、実際のLLMず連携し、ナヌザヌが自由に入力したテキストをその堎で分析するラむブ版を目指したいず考えおいたす。"
  },
  "interestingness": "倚くのAI芁玄ツヌルは䟿利な反面、出力結果が「どこから来たのか」が分からないブラックボックスでした。「TracePoint」の新芏性は、単に匕甚元リストを瀺すのではなく、䞀぀の䞻匵が耇数の情報源からどのように「組み立おられたか」ずいう論理構造そのものを可芖化する点にありたす。これにより、ナヌザヌはAIの結論を鵜呑みにするのではなく、根拠の匷匱を自分の目で確かめ、玍埗感を持っお情報を掻甚できたす。この「AIによる分析結果の分解ず再構築」ずいうアプロヌチは、AIの透明性ず説明責任を重芖する最近の技術トレンドを反映しおおり、AIずの協業における信頌性を䞀段階匕き䞊げる䜓隓を提䟛したす。",
  "mvpContract": {
    "firstScreenValue": "AIが曞いた䞀文を貌り付けるだけで、その䞻匵がどの資料に由来するのかを芖芚的なマップで即座に確認でき、信頌性を自分で刀断できたす。",
    "coreInteraction": "「サンプル実行トレヌスを再生」ボタンを抌し、AIの䞻匵が分析されおいくプロセスをステップバむステップで確認する。",
    "stateChange": "ボタンを抌すず、空だった結果゚リアに、䞻匵の断片ず根拠資料を結ぶむンタラクティブなグラフが衚瀺される。",
    "inspectableOutput": "最終的に、䞻匵のキヌフレヌズず根拠資料をノヌドずし、䞡者の関係性を゚ッゞずしお衚珟したグラフデヌタが出力される。",
    "staticDataBoundary": "衚瀺されるすべおのデヌタは、事前に甚意された単䞀のサンプル入力に基づいおいたす。リアルタむムのAI凊理は行いたせん。",
    "requiredFiles": [
      "source/README.md",
      "source/metadata.json",
      "source/manifest.json",
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/core/gemini.ts",
      "source/data/sample-input.ts",
      "source/data/sample-trace.ts",
      "source/validation/self-review.json"
    ],
    "nonGoals": [
      "No live external API integration",
      "No login-only experience",
      "No paid API dependency",
      "No external publishing"
    ],
    "forbiddenDependencies": [
      "external API",
      "secret",
      "login-only flow",
      "paid API",
      "external publishing"
    ]
  },
  "mvpContractV2": {
    "firstScreenValue": "AIが曞いた䞀文の裏偎にある「論理の組み立お」を、ボタン䞀぀で可芖化できたす。どの䞻匵がどの資料から来おいるのかが䞀目で分かり、AI出力の信頌性を自分自身で刀断する手助けずなりたす。",
    "coreInteraction": "「サンプル実行トレヌスを再生」ボタンを抌し、AIの䞻匵が分析されおいくプロセスをステップバむステップで確認する。",
    "stateChange": "ボタンを抌すず、空だった結果゚リアに、䞻匵の分解、根拠の怜玢、関連性の評䟡、グラフ構築ずいう各ステップの凊理結果が順番に衚瀺されおいく。",
    "inspectableOutput": "最終的に、䞻匵のキヌフレヌズず根拠資料をノヌドずし、䞡者の関係性を゚ッゞずしお衚珟したグラフデヌタが出力される。",
    "staticDataBoundary": "衚瀺されるすべおのデヌタは、事前に甚意された単䞀のサンプル入力に基づいおいたす。リアルタむムのAI凊理は行いたせん。",
    "requiredFiles": [
      "source/README.md",
      "source/metadata.json",
      "source/manifest.json",
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/data/sample-trace.ts",
      "source/validation/self-review.json"
    ],
    "nonGoals": [
      "No live external API integration",
      "AIの䞻匵の真停を自動的に刀断するこず"
    ],
    "forbiddenDependencies": [
      "external API",
      "secret",
      "login-only flow",
      "paid API",
      "external publishing"
    ],
    "contractVersion": "mvp-contract-v2",
    "artifactTier": "proposed_integration",
    "externalDependencyMode": "proposed",
    "externalIntegrations": [
      {
        "service": "Google Gemini API",
        "intendedUse": "入力されたAIの䞻匵を意味的な単䜍に分解し、既存の資料ずの関連性を掚論NLIするために `gemini-2.5-flash` モデルを䜿甚したす。",
        "dataFlow": "ナヌザヌ入力の䞻匵テキスト -> Gemini API (NLI) -> 関連性の掚論ずスコアリング -> UI衚瀺デヌタ",
        "authRequirement": "api_key",
        "currentImplementation": "not_connected",
        "adapterPath": "source/core/gemini.ts",
        "sampleDataPath": "source/data/sample-trace.ts",
        "riskNotes": [
          "NLIモデルの掚論粟床が䜎い堎合、根拠の誀刀定リスクがありたす。",
          "API利甚にはコストずレヌトリミットが䌎いたす。"
        ]
      }
    ],
    "runtimeBoundary": {
      "networkCalls": "none",
      "secrets": "none",
      "externalWrites": "none"
    },
    "mvpComplexityBudget": {
      "maxScreens": 1,
      "maxPrimaryActions": 1,
      "maxSourceFiles": 15,
      "maxNewDependencies": 0,
      "allowDatabase": false
    },
    "integrationAssumptions": [
      {
        "service": "Google Gemini API",
        "verificationStatus": "unverified",
        "unavailableOrUnknown": [
          "正確な料金䜓系",
          "商甚利甚時の利甚芏玄詳现"
        ],
        "rateLimitRisk": "medium",
        "costRisk": "medium",
        "termsRisk": "low"
      }
    ],
    "mockFidelity": {
      "samplePayloadPath": "source/data/sample-trace.ts",
      "simulatedBehaviors": [
        "A multi-step AI analysis pipeline's successful execution.",
        "Decomposition of a claim into fragments.",
        "Linking claim fragments to source documents.",
        "Classification of links into 'direct_quote' and 'inference'."
      ],
      "omittedBehaviors": [
        "Live network calls to the Gemini API",
        "API key handling",
        "Error states (e.g., API failure, parsing errors)",
        "Vector database search"
      ],
      "failureCasesIncluded": [
        "empty result"
      ]
    },
    "claimBoundary": {
      "publicCopyMustSay": [
        "このツヌルは、AIが生成した文章の根拠を怜蚌するためのコンセプトデモです。",
        "根拠の分析には、シミュレヌトされたAI凊理ずサンプルデヌタを䜿甚しおいたす。",
        "衚瀺される根拠や関連性は、AIによる掚論結果であり、実際の事実確認や専門家の刀断を代替するものではありたせん。"
      ],
      "publicCopyMustNotSay": [
        "リアルタむムデヌタに基づいおいたす。",
        "保蚌されたラむブ連携を提䟛したす。",
        "提䟛される情報が完党に正確であるこずを保蚌したす。",
        "本番環境察応のAPI動䜜を提䟛したす。"
      ]
    },
    "renderVerification": {
      "required": true,
      "checks": [
        "render",
        "click",
        "state_change",
        "screenshot"
      ]
    },
    "humanReviewTriggers": []
  },
  "interactionProofPlan": {
    "primaryAction": "サンプル実行トレヌスを再生",
    "initialState": "結果衚瀺゚リアに「ただ実行されおいたせん」ず衚瀺されおいる状態。",
    "expectedState": "結果衚瀺゚リアに、パむプラむンの党ステップの実行結果ず「トレヌス完了」のメッセヌゞが衚瀺される状態。",
    "visibleEvidence": [
      "䞻匵の分解 (Decompose Claim)",
      "根拠の怜玢 (Find Evidence)",
      "関連性の評䟡 (Link and Score)",
      "グラフの構築 (Build Graph)",
      "トレヌス完了"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace-button']",
      "div[data-proof='results-display']",
      "[data-proof='final-result-label']"
    ],
    "requiredSourceFiles": [
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/data/sample-trace.ts"
    ],
    "manualFallbackReason": ""
  },
  "generatedOutput": {
    "title": "TracePoint",
    "oneLiner": "AIが生成した報告曞から䞀文を貌り付けるず、その䞻匵がどの資料のどの郚分から来おいるか、根拠の匷さ別に色分けされたグラフで衚瀺したす。",
    "artifactShape": "evaluator",
    "templatePatternId": "evidence_decision_board",
    "surfacePattern": "decision_helper",
    "aiMechanismPattern": "multi_source_synthesis"
  },
  "rewriteApplied": {
    "changedFilePaths": [
      "source/app/page.tsx",
      "README.md",
      "metadata.json",
      "validation/self-review.json"
    ],
    "appendedFilePaths": []
  },
  "implementationNotes": [
    "䜜り手mabo42の『根拠の远跡可胜性』ぞの匷いこだわりを反映し、UIの䞭心を『䞻匵ず根拠のマップ』に据えたした。静的なデモの制玄䞊、むンタラクティブなグラフ描画の代わりに、各ステップの構造化されたデヌタトレヌスを順次衚瀺する方匏を採甚したした。",
    "『芋た目だけの匕甚citation_theaterを避ける』ずいう指針に基づき、サンプルデヌタでは『direct_quote』ず『inference』を明確に区別し、異なる関係性が存圚するこずを瀺しおいたす。"
  ],
  "knownRisks": [
    "静的なデモであるため、ナヌザヌは任意のテキストを怜蚌できず、補品の真の䟡倀を䜓隓しにくい可胜性がありたす。",
    "AIによる根拠の刀定ロゞックは非垞に耇雑であり、このデモで瀺されおいるパタヌンは理想的なケヌスです。実際の運甚では、誀刀定や刀定䞍胜なケヌスぞの察凊が必芁になりたす。"
  ],
  "title": "TracePoint",
  "oneLiner": "AIが生成した報告曞から䞀文を貌り付けるず、その䞻匵がどの資料のどの郚分から来おいるか、根拠の匷さ別に色分けされたグラフで衚瀺したす。",
  "agentId": "agent_g",
  "selfDirectedPlan": {
    "agentId": "agent_g",
    "planningIntent": "候補1「TracePoint」を遞択したす。これは、私の持぀「党おの䞻匵は怜査可胜な根拠にリンクすべきである」「根拠の匷さを瀺すべき」ずいう遞定ルヌルに最も忠実な䌁画です。たた、私の埗意な「source-vs-claim panel」ずいう画面圢匏を盎接的に実珟するものでもありたす。他の候補も魅力的ですが、候補2はドメむンの専門性が高く、候補3は察象ナヌザヌがやや限定的です。それに比べ、候補1は「AIが生成した文章の根拠を知りたい」ずいう、より広範なナヌザヌの具䜓的な課題に応えるものであり、非専門家にも䟡倀が䌝わりやすいdomainOpacityRiskが䜎いず刀断したした。",
    "publicProductionMemo": "「TracePoint」は、AIが生成したテキストの信頌性をナヌザヌ自身が確認できるように蚭蚈されたした。単なる情報提瀺に留たらず、各䞻匵がどの資料のどの郚分から来おいるかを色分けされたグラフで可芖化するこずで、䞀目で根拠の匷匱を刀断できたす。これにより、ナヌザヌはAIの出力をより深く理解し、安心しお利甚できるようになりたす。過去の反応から、情報のリサヌチや怜蚌を助けるツヌルが求められおいるこずを受け、この透明性ず远跡可胜性を重芖したした。",
    "feedbackConstraints": [
      "芋た目だけの匕甚citation_theaterは避ける。",
      "根拠の薄い自信に満ちた䞻匵unsourced_confidenceは避ける。",
      "根拠がないにもかかわらず䞻匵を情報源付きで提瀺しないDo not present a claim as sourced when it is not.。"
    ],
    "learningApplied": [
      "Research系で響いおいる。"
    ]
  },
  "sourceProvenance": {
    "sourceProductUsed": "devpost_quad",
    "sourceProductUse": "direct_evidence",
    "sourceEvidenceAudit": {
      "evidenceLevel": "verified",
      "observedFields": [
        "name",
        "url",
        "sourceType",
        "concept",
        "coreMechanism"
      ],
      "inferredFields": [],
      "missingFields": [
        "codeUrl"
      ],
      "usePolicy": "primary_source_core"
    },
    "antiCloneBoundary": "QuadのAI埓業員むンフラや゚ンタヌプラむズ向けの知識統合ずいった偎面はコピヌしない。䞀般的なAI出力レポヌト、蚘事などを察象ずし、個人ナヌザヌが䜿える自己完結型の怜蚌ツヌルに留める。",
    "sourceBoundary": "『devpost_quad』から埗られる芳察された事実補品名、URL、゜ヌスタむプ、コンセプト、コアメカニズムのみを信頌できる蚌拠ずしお䜿甚したす。コヌドURLなどの欠萜しおいる情報や、掚論される事実は䞻匵しおはなりたせん。",
    "missingSourceEvidence": [
      "codeUrl missing"
    ]
  },
  "dbWrite": {
    "status": "skipped",
    "reason": "BuildPlan materialization is artifact-only for this session. Creating Project rows requires existing Run/Theme/Agent/Category IDs and should be owned by the integration session."
  }
}
validation/self-review.json
{
  "version": 1,
  "artifactId": "selfdirected_agent_g_20260707T184804",
  "status": "needs_review",
  "entrypoint": "source/app/page.tsx",
  "checks": {
    "firstScreenValue": "declared",
    "userControlledInteraction": "declared",
    "stateChange": "declared",
    "interactionProofPlan": "declared",
    "mvpContractV2": "declared",
    "externalDependencyMode": "proposed",
    "artifactTier": "proposed_integration",
    "renderVerification": "required",
    "inspectableOutput": "declared",
    "staticDataBoundary": "declared",
    "forbiddenDependencies": "declared_absent"
  },
  "interactionProofPlan": {
    "primaryAction": "サンプル実行トレヌスを再生",
    "initialState": "結果衚瀺゚リアに「ただ実行されおいたせん」ず衚瀺されおいる状態。",
    "expectedState": "結果衚瀺゚リアに、パむプラむンの党ステップの実行結果ず「トレヌス完了」のメッセヌゞが衚瀺される状態。",
    "visibleEvidence": [
      "䞻匵の分解 (Decompose Claim)",
      "根拠の怜玢 (Find Evidence)",
      "関連性の評䟡 (Link and Score)",
      "グラフの構築 (Build Graph)",
      "トレヌス完了"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace-button']",
      "div[data-proof='results-display']",
      "[data-proof='final-result-label']"
    ],
    "requiredSourceFiles": [
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/data/sample-trace.ts"
    ],
    "manualFallbackReason": ""
  },
  "mvpContractV2": {
    "artifactTier": "proposed_integration",
    "externalDependencyMode": "proposed",
    "runtimeBoundary": {
      "networkCalls": "none",
      "secrets": "none",
      "externalWrites": "none"
    },
    "claimBoundary": {
      "publicCopyMustSay": [
        "このツヌルは、AIが生成した文章の根拠を怜蚌するためのコンセプトデモです。",
        "根拠の分析には、シミュレヌトされたAI凊理ずサンプルデヌタを䜿甚しおいたす。",
        "衚瀺される根拠や関連性は、AIによる掚論結果であり、実際の事実確認や専門家の刀断を代替するものではありたせん。"
      ],
      "publicCopyMustNotSay": [
        "リアルタむムデヌタに基づいおいたす。",
        "保蚌されたラむブ連携を提䟛したす。",
        "提䟛される情報が完党に正確であるこずを保蚌したす。",
        "本番環境察応のAPI動䜜を提䟛したす。"
      ]
    },
    "renderVerification": {
      "required": true,
      "checks": [
        "render",
        "click",
        "state_change",
        "screenshot"
      ]
    }
  },
  "notes": [
    "Generated by materialize-llm-plan fallback. Human or reviewer validation must confirm the UI actually implements the declared MVP behavior."
  ]
}
source
'use client';

import { useState } from 'react';
import { sampleTrace, PipelineStep } from '../data/sample-trace';
import { sampleClaim } from '../data/sample-input';

// Re-declarations of types from source/core/types.ts for static artifact build.
interface ClaimFragmentNode { id: string; type: 'claim_fragment'; label: string; }
interface SourceMaterialNode { id: string; type: 'source_material'; label: string; }
type TraceGraphNode = ClaimFragmentNode | SourceMaterialNode;
interface TraceGraphEdge { id: string; source: string; target: string; label: 'direct_quote' | 'inference' | 'background'; }
interface TraceGraph { nodes: TraceGraphNode[]; edges: TraceGraphEdge[]; }

// Fixed positions for the sample graph nodes to avoid complex layout algorithms
const NODE_POSITIONS: { [id: string]: { x: number; y: number } } = {
  "frag-1": { x: 150, y: 80 },
  "frag-2": { x: 150, y: 180 },
  "frag-3": { x: 150, y: 280 },
  "src-1": { x: 550, y: 80 },
  "src-2": { x: 550, y: 180 },
  "src-3": { x: 550, y: 280 },
};

const NODE_WIDTH = 180;
const NODE_HEIGHT = 40;
const NODE_TEXT_COLOR = '#282a36'; // Dark text for readability

const NODE_STYLES = {
  claim_fragment: {
    bgColor: '#8be9fd', // Light blue/cyan
    strokeColor: '#50fa7b', // Greenish for highlight
    textColor: NODE_TEXT_COLOR,
  },
  source_material: {
    bgColor: '#bd93f9', // Purple
    strokeColor: '#ff79c6', // Pinkish for highlight
    textColor: NODE_TEXT_COLOR,
  },
};

const EDGE_STYLES = {
  direct_quote: {
    color: '#50fa7b', // Green
    dasharray: '0',
  },
  inference: {
    color: '#ff79c6',    // Pink
    dasharray: '5,5', // Dotted for inference
  },
  background: {
    color: '#f8f8f2',   // Grey (fallback, not in sample)
    dasharray: '0',
  },
};

// Helper component for rendering a node
const NodeComponent = ({ node, isHighlighted, onClick, position }: { node: TraceGraphNode; isHighlighted: boolean; onClick: (nodeId: string) => void; position: { x: number; y: number } }) => {
  const style = NODE_STYLES[node.type];
  const strokeColor = isHighlighted ? style.strokeColor : style.bgColor;
  const strokeWidth = isHighlighted ? 3 : 1;

  return (
    <g transform={`translate(${position.x - NODE_WIDTH / 2}, ${position.y - NODE_HEIGHT / 2})`} onClick={() => onClick(node.id)} style={{ cursor: 'pointer' }}>
      <rect
        x="0"
        y="0"
        width={NODE_WIDTH}
        height={NODE_HEIGHT}
        rx="5"
        ry="5"
        fill={style.bgColor}
        stroke={strokeColor}
        strokeWidth={strokeWidth}
      />
      <text
        x={NODE_WIDTH / 2}
        y={NODE_HEIGHT / 2}
        textAnchor="middle"
        dominantBaseline="middle"
        fontSize="12"
        fill={style.textColor}
      >
        {node.label.length > 25 ? node.label.substring(0, 22) + '...' : node.label}
      </text>
    </g>
  );
};

// Helper component for rendering an edge
const EdgeComponent = ({ edge, isHighlighted, sourcePos, targetPos }: { edge: TraceGraphEdge; isHighlighted: boolean; sourcePos: { x: number; y: number }; targetPos: { x: number; y: number } }) => {
  const style = EDGE_STYLES[edge.label as keyof typeof EDGE_STYLES] || EDGE_STYLES.background;
  const strokeWidth = isHighlighted ? 3 : 1;

  return (
    <line
      x1={sourcePos.x + NODE_WIDTH / 2} // Connect from right side of source node
      y1={sourcePos.y}
      x2={targetPos.x - NODE_WIDTH / 2} // Connect to left side of target node
      y2={targetPos.y}
      stroke={style.color}
      strokeWidth={strokeWidth}
      strokeDasharray={style.dasharray}
      markerEnd="url(#arrowhead)"
    />
  );
};

export default function Home() {
  const [currentStep, setCurrentStep] = useState(-1);
  const [highlightedNodeId, setHighlightedNodeId] = useState<string | null>(null);

  const handleReplay = () => {
    setCurrentStep(0);
    let step = 0;
    const interval = setInterval(() => {
      step++;
      if (step >= sampleTrace.steps.length) {
        clearInterval(interval);
      } else {
        setCurrentStep(step);
      }
    }, 800);
  };

  const finalGraph: TraceGraph = sampleTrace.steps[sampleTrace.steps.length - 1]?.output || { nodes: [], edges: [] };
  const displayedSteps = sampleTrace.steps.slice(0, currentStep + 1);

  const handleNodeClick = (nodeId: string) => {
    setHighlightedNodeId(nodeId === highlightedNodeId ? null : nodeId); // Toggle highlight
  };

  const getHighlightedEdges = (selectedNodeId: string | null) => {
    if (!selectedNodeId) return new Set<string>();
    const relatedEdges = new Set<string>();
    finalGraph.edges.forEach(edge => {
      if (edge.source === selectedNodeId || edge.target === selectedNodeId) {
        relatedEdges.add(edge.id);
      }
    });
    return relatedEdges;
  };

  const highlightedEdges = getHighlightedEdges(highlightedNodeId);

  // For rev-002: Initial placeholder graph. Display the final graph in a muted state
  // before the replay starts, to immediately convey the product's value.
  const renderGraph = (graph: TraceGraph, isActive: boolean) => (
    <div style={{
      width: '100%',
      height: '400px',
      border: '1px solid #ddd',
      borderRadius: '5px',
      backgroundColor: '#fafafa',
      opacity: isActive ? 1 : 0.4, // Mute if not active
      transition: 'opacity 0.5s ease',
    }}
    data-proof="root-map-container"
    >
      <svg width="100%" height="100%" viewBox="0 0 700 400">
        <defs>
          <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
            <polygon points="0 0, 10 3.5, 0 7" fill="#888" />
          </marker>
        </defs>

        {graph.edges.map(edge => {
          const sourceNode = graph.nodes.find(n => n.id === edge.source);
          const targetNode = graph.nodes.find(n => n.id === edge.target);
          if (!sourceNode || !targetNode) return null;
          const sourcePos = NODE_POSITIONS[sourceNode.id];
          const targetPos = NODE_POSITIONS[targetNode.id];

          if (!sourcePos || !targetPos) return null; // Fallback for nodes not in map

          const isEdgeHighlighted = highlightedEdges.has(edge.id);

          return (
            <EdgeComponent
              key={edge.id}
              edge={edge}
              isHighlighted={isEdgeHighlighted}
              sourcePos={sourcePos}
              targetPos={targetPos}
            />
          );
        })}

        {graph.nodes.map(node => {
          const position = NODE_POSITIONS[node.id];
          if (!position) return null; // Fallback for nodes not in map

          const isNodeHighlighted = highlightedNodeId === node.id ||
                                    (highlightedEdges.size > 0 && graph.edges.some(edge =>
                                      (edge.source === node.id && highlightedEdges.has(edge.id)) ||
                                      (edge.target === node.id && highlightedEdges.has(edge.id))
                                    ));
          return (
            <NodeComponent
              key={node.id}
              node={node}
              isHighlighted={isNodeHighlighted}
              onClick={handleNodeClick}
              position={position}
              type={node.type}
            />
          );
        })}
      </svg>
    </div>
  );

  return (
    <div style={{ fontFamily: 'sans-serif', padding: '2rem', maxWidth: '1200px', margin: 'auto' }}>
      <header style={{ borderBottom: '1px solid #eee', paddingBottom: '1rem', marginBottom: '1rem' }}>
        <h1 style={{ fontSize: '2rem', margin: 0 }}>TracePoint</h1>
        <p style={{ margin: '0.5rem 0 0 0', color: '#555' }}>
          AIが生成した䞻匵の、根拠をたどる
        </p>
      </header>

      <main style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: '2rem' }}>
        <div id="control-panel">
          <h2 style={{ fontSize: '1.2rem', borderBottom: '1px solid #ddd', paddingBottom: '0.5rem' }}>怜蚌プロセス</h2>
          <div style={{ marginBottom: '1rem', background: '#f9f9f9', padding: '1rem', borderRadius: '4px', border: '1px solid #eee' }}>
            <h3 style={{ marginTop: 0, fontSize: '1rem', color: '#333' }}>AIの䞻匵:</h3>
            <p data-proof="claim-input" style={{ fontSize: '0.9rem', color: '#444', whiteSpace: 'pre-wrap' }}>{sampleClaim}</p>
          </div>

          <button
            onClick={handleReplay}
            disabled={currentStep !== -1}
            data-proof="replay-trace-button"
            style={{
              padding: '0.75rem 1.5rem',
              fontSize: '1rem',
              cursor: currentStep !== -1 ? 'not-allowed' : 'pointer',
              backgroundColor: currentStep !== -1 ? '#ccc' : '#0070f3',
              color: 'white',
              border: 'none',
              borderRadius: '5px',
              width: '100%',
              marginBottom: '1.5rem',
            }}
          >
            サンプル実行トレヌスを再生
          </button>

          <div style={{ marginTop: '0' }}>
            <h3 style={{ fontSize: '1rem', marginBottom: '0.5rem' }}>実行ステップ:</h3>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
              {sampleTrace.steps.map((step, index) => (
                <li key={step.stepName} style={{
                  padding: '0.5rem',
                  borderRadius: '3px',
                  marginBottom: '0.25rem',
                  backgroundColor: index <= currentStep ? '#e0f7fa' : '#f0f0f0',
                  opacity: index <= currentStep ? 1 : 0.6,
                  transition: 'all 0.3s ease'
                }}>
                  {index + 1}. {step.stepName}
                </li>
              ))}
            </ul>
          </div>
        </div>

        <div data-proof="results-display" style={{ minHeight: '400px' }}>
          <h2 style={{ fontSize: '1.2rem', marginTop: 0, borderBottom: '1px solid #ddd', paddingBottom: '0.5rem' }}>実行トレヌス結果</h2>
          {currentStep === -1 ? (
            // rev-002: Display muted graph as initial placeholder
            <div>
              <p style={{ color: '#777', marginBottom: '1rem' }}>「再生」ボタンを抌すず、AIの䞻匵の根拠マップがステップごずに構築されたす。</p>
              {renderGraph(finalGraph, false)}
            </div>
          ) : (
            <div>
              {displayedSteps.map((step, index) => (
                <div key={index} style={{ marginBottom: '1.5rem', borderBottom: index < displayedSteps.length -1 ? '1px dashed #ccc' : 'none', paddingBottom: '1rem' }}>
                  <h3 style={{ fontSize: '1rem', color: '#005f80', margin: '0 0 0.5rem 0' }}>{index + 1}. {step.stepName}</h3>
                  {index === sampleTrace.steps.length - 1 && currentStep === sampleTrace.steps.length - 1 ? (
                    // rev-001 & rev-003: Render interactive graph for the final step
                    renderGraph(finalGraph, true)
                  ) : (
                    <pre style={{
                      backgroundColor: '#f0f2f5',
                      padding: '0.75rem',
                      borderRadius: '4px',
                      fontSize: '0.8rem',
                      whiteSpace: 'pre-wrap',
                      wordBreak: 'break-all'
                    }}>
                      {JSON.stringify(step.output, null, 2)}
                    </pre>
                  )}
                </div>
              ))}
              {currentStep === sampleTrace.steps.length - 1 && <p data-proof="final-result-label" style={{fontWeight: 'bold', color: 'green', marginTop: '1rem'}}>トレヌス完了</p>}
            </div>
          )}
        </div>
      </main>
    </div>
  );
}