Internal Product Info

Molecule Gauntlet

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_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/mvp-contract-v2.json
保存ファむルのpath / size / checksumを衚瀺
demo / 1.5KB / b3a36dbf6c7b20291940e15600f2814407d3e80056ec8b6db4f09fe68af4ea97
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/demo-placeholder.md

interaction_proof / 2.1KB / f58c3f36963bb0f1301adf489c30d40392e36c2f6c3ebbfb93185fe7a3398648
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/interaction-proof.json

metadata / 20.5KB / 7555fd6cd0f24b2c27f4a2b3fabe9ab2154532c986b05ab69675279c9439445b
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/metadata.json

mvp_contract_v2 / 12.2KB / edc13f0dce66f7011754ef490a12250e5b2af501fab10eda879c13ca04607983
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/mvp-contract-v2.json

product_logo / 546B / ab0c34f5de591152d937482b6d9583c2598d3fe29fd9a3939494fde26c214868
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/mockups/product-logo.svg

product_showcase / 1.9MB / 0c0005ae129e0c4f0c58af4ee2ed8e72faa15279fdb1291806dc65e06be51c5d
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/mockups/product-showcase.png

product_showcase / 1.8KB / 0b9c066a0f4271b7515eb89ce023d8120ce0c669caf67fb86d431a12263a3879
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/mockups/product-showcase.svg

product_thumbnail / 1.4KB / e5701b59a92955c96182b72efdbb2e4be7019ecd7c3e90862585af041cf86f58
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/mockups/product-thumbnail.svg

publisher_response / 1.1KB / d46c32884084d7973c87d97582316c11d76699c3de0664cbf23f937bd680a24f
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/publisher/response.json

publish_readiness / 6.0KB / c091256f2a3b1c3213bd23fb26ae311a29c37838d3eef0fe6d72587220a6356d
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/publish-readiness.json

readme / 4.9KB / 666c542785ec646bd114ec1bc8e25d714f0cfeeacbe49a9ce0629cae07fe6e64
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/README.md

render_screenshot / 156.1KB / 86de9a2f3bbabfe04d58b5fcf9446909ce9fdfcddd896853fed0b507e24cc42f
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/render-verification.png

render_verification / 2.1KB / 7e620d29bb681a4b3c21cda2fe748e76dc97b19beedf811c5fa98d300af34918
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/render-verification.json

self_review / 2.7KB / ce88576d9b900c4f1e7cd3a1088e22b1653282c1fcec301a38a6e5c02edfb99e
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/validation/self-review.json

source / 7.9KB / 4a76639255cb4da934f2ec0b84b0416604330452f285d4c455fbe3c841d8a9c8
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/app/page.tsx

source / 2.0KB / f0375ef7c25e6d36a7294f1988838b88a37c021424503b24264ff8a5de8cdaf5
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/gemini.ts

source / 1.1KB / 606d3c064229f15cbc31acec4463e20d5bd5a70670066c7557f15080a6c9fbb7
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/pipeline.ts

source / 383B / 7f6297a27794cf51d12e43c83751bf6e7b6e527cb89f0de12c4a9be54c100c7b
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/steps/1_defineTarget.ts

source / 1.4KB / b689f06bc338c4aa25440152dc1a3b37c882ece7c0c7d7a178ae06c48e667881
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/steps/2_generateCandidates.ts

source / 1.7KB / 861f05336f9862a777968fe04177d6cd7ba338881aa2ee8956a05c6201493de5
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/steps/3_evaluateAndScore.ts

source / 594B / 662209f2b427f5885011667897e3117faed8297f8656cc628258b465fba48045
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/steps/4_structureBoard.ts

source / 914B / f76ad59d2948bff90762d1a91c4b918d83610e6174c5cf4133f1a6b69ae92930
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/core/types.ts

source / 172B / eea30f07a6fc40d700134cb054d051cad1909ab11b96f6fb23926205e2edf17f
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/data/sample-input.ts

source / 3.7KB / 3189794f2d19569c3edfc71c19db645ccce7a70dcf09980e083f302bfb49ed5b
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/data/sample-trace.ts

source / 440B / 662f422fdea8213c3c8a42691c07967e4180777e3792af5b693f542d947dfd92
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/manifest.json

source / 2.3KB / 0e14be20b6e83797a8e788feff2ac7352851e84c5f4f97737bab774e5640a992
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/metadata.json

source / 2.7KB / dd626ef237cff046ba850145e7614da11dff59c15b3bb27979d61dc7f9b728fe
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/README.md

source / 1.4KB / 5eec9c878e14665670e8ff90d2218f74122644b0b6f47ef55f06c1349100a0dd
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/source/validation/self-review.json

validation_summary / 3.7KB / f15ad9905bda85b22bc441171b4d14ff86b68d8707c1c84c394ecf20075e91c5
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/validation-summary.json

visual_manifest / 9.6KB / c03c9f1abca1027e9ad2e892448b00880189d7d8452a19537910788f8662d7d0
artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/materialized/selfdirected_agent_o_20260707T223151/mockups/visual-manifest.json
README / metadata / self-reviewの䞭身を衚瀺
README.md
# selfdirected_agent_o_20260707T223151

This directory is a materialized LLM BuildPlan artifact candidate.

## Readiness

- First screen value: AIが生成した創薬候補を、「効果」ず「リスク」の2軞で可芖化されたマップ䞊で確認できたす。ボタン䞀぀でサンプルデヌタの凊理過皋を再生し、人間の刀断で有望な候補を「承認」する、ずいう未来の創薬ワヌクフロヌの栞心をすぐに䜓隓できたす。
- Core interaction: ナヌザヌは、サンプル実行トレヌスを再生しお意思決定ボヌドを衚瀺させた埌、マップ䞊の候補分子をクリックで遞択し、「承認」ボタンを抌しお「承認埅ちリスト」ぞ移動させたす。
- State change: 「サンプル実行トレヌスを再生」ボタンを抌すず、初期状態の「未実行」パネルが、むンタラクティブな「候補分子評䟡ボヌド」に倉わりたす。さらに、候補を「承認」するず、その候補がマップから「承認埅ちリスト」ぞ移動したす。
- Inspectable output: ナヌザヌが承認した候補分子のリスト。これは、AIの提案に基づき、人間がリスクず効果を勘案しお䞋した意思決定の蚘録です。
- Static data boundary: 衚瀺されるすべおの分子候補、スコア、評䟡理由は、`source/data/sample-trace.ts`に蚘述された静的なサンプルデヌタです。このデモは倖郚のAIモデルやデヌタベヌスに䞀切接続したせん。
- Remaining weakness: 珟圚は単䞀の創薬タヌゲットに察する固定のサンプルしか扱えたせんが、将来的にはナヌザヌが自身のタヌゲット情報を入力し、それに応じた候補生成ず評䟡をバック゚ンドで実行できるようにしたいです。さらに、承認埌のワヌクフロヌ連携や、チヌムでのレビュヌ機胜を远加しお、単なるシミュレヌタヌから共同研究プラットフォヌムぞず進化させたいず考えおいたす。

## Interaction Proof Plan

- Primary action: サンプル実行トレヌスを再生
- Initial state: The decision board is not visible, and a message indicates that the pipeline has not been run yet.
- Expected state: The pipeline trace is replayed, and the final decision board with candidate molecules is displayed on the screen.
- Visible evidence: Molecule Gauntlet; パむプラむン ステップ; XYZ受容䜓アゎニスト 候補分子評䟡ボヌド; Prodiazepam; 承認埅ちリスト; 効果 (高); リスク (高)

## 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: This is a conceptual demo using pre-recorded sample data.; The AI's evaluation is simulated and not based on a live model.; The tool illustrates a potential future workflow and is not for actual scientific use.
- External integrations: Google Generative AI API=not_connected
- Mock fidelity: End-to-end data flow from a target definition to a structured decision board.; Plausible AI-generated outputs for molecule candidates and their evaluations.

## Files

- `source/README.md`: Product and pipeline explanation.
- `source/metadata.json`: Public product metadata.
- `source/manifest.json`: File index.
- `source/core/types.ts`: Core data structures.
- `source/data/sample-input.ts`: Representative input data.
- `source/data/sample-trace.ts`: Hand-authored execution trace.
- `source/core/gemini.ts`: Reference implementation for calling the Gemini API.
- `source/core/steps/1_defineTarget.ts`: First pipeline step.
- `source/core/steps/2_generateCandidates.ts`: Second pipeline step (AI core value).
- `source/core/steps/3_evaluateAndScore.ts`: Third pipeline step.
- `source/core/steps/4_structureBoard.ts`: Fourth pipeline step.
- `source/core/pipeline.ts`: Orchestration of processing steps.
- `source/app/page.tsx`: Entrypoint and trace-replay runner.
- `source/validation/self-review.json`: Self-review against Prodia's MVP criteria.

## 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_o_20260707T223151",
  "generatedAt": "2026-07-07T22:42:22.428Z",
  "generatedFrom": {
    "input": "artifacts/llm-pipeline-runs/run_selfdirected_agent_o_20260707T223151/builder/response.json",
    "requirementSpecId": "run_selfdirected_agent_o_20260707T223151",
    "framework": "next_static_artifact"
  },
  "sourceFiles": [
    {
      "relativePath": "source/README.md",
      "purpose": "Product and pipeline explanation.",
      "sizeBytes": 2761,
      "checksum": "dd626ef237cff046ba850145e7614da11dff59c15b3bb27979d61dc7f9b728fe",
      "generatedFrom": "README.md"
    },
    {
      "relativePath": "source/metadata.json",
      "purpose": "Public product metadata.",
      "sizeBytes": 2331,
      "checksum": "a61831dd27e6e6fd8786f0fb29551dc98225c2d577e6b554f0737b6e8c791920",
      "generatedFrom": "metadata.json"
    },
    {
      "relativePath": "source/manifest.json",
      "purpose": "File index.",
      "sizeBytes": 439,
      "checksum": "458b087f09271671ad63dac262e848eb28713f1fb74b5ba0f2d69bb2734ce9a9",
      "generatedFrom": "manifest.json"
    },
    {
      "relativePath": "source/core/types.ts",
      "purpose": "Core data structures.",
      "sizeBytes": 914,
      "checksum": "f76ad59d2948bff90762d1a91c4b918d83610e6174c5cf4133f1a6b69ae92930",
      "generatedFrom": "source/core/types.ts"
    },
    {
      "relativePath": "source/data/sample-input.ts",
      "purpose": "Representative input data.",
      "sizeBytes": 172,
      "checksum": "eea30f07a6fc40d700134cb054d051cad1909ab11b96f6fb23926205e2edf17f",
      "generatedFrom": "source/data/sample-input.ts"
    },
    {
      "relativePath": "source/data/sample-trace.ts",
      "purpose": "Hand-authored execution trace.",
      "sizeBytes": 3811,
      "checksum": "3189794f2d19569c3edfc71c19db645ccce7a70dcf09980e083f302bfb49ed5b",
      "generatedFrom": "source/data/sample-trace.ts"
    },
    {
      "relativePath": "source/core/gemini.ts",
      "purpose": "Reference implementation for calling the Gemini API.",
      "sizeBytes": 2056,
      "checksum": "f0375ef7c25e6d36a7294f1988838b88a37c021424503b24264ff8a5de8cdaf5",
      "generatedFrom": "source/core/gemini.ts"
    },
    {
      "relativePath": "source/core/steps/1_defineTarget.ts",
      "purpose": "First pipeline step.",
      "sizeBytes": 383,
      "checksum": "7f6297a27794cf51d12e43c83751bf6e7b6e527cb89f0de12c4a9be54c100c7b",
      "generatedFrom": "source/core/steps/1_defineTarget.ts"
    },
    {
      "relativePath": "source/core/steps/2_generateCandidates.ts",
      "purpose": "Second pipeline step (AI core value).",
      "sizeBytes": 1441,
      "checksum": "b689f06bc338c4aa25440152dc1a3b37c882ece7c0c7d7a178ae06c48e667881",
      "generatedFrom": "source/core/steps/2_generateCandidates.ts"
    },
    {
      "relativePath": "source/core/steps/3_evaluateAndScore.ts",
      "purpose": "Third pipeline step.",
      "sizeBytes": 1732,
      "checksum": "861f05336f9862a777968fe04177d6cd7ba338881aa2ee8956a05c6201493de5",
      "generatedFrom": "source/core/steps/3_evaluateAndScore.ts"
    },
    {
      "relativePath": "source/core/steps/4_structureBoard.ts",
      "purpose": "Fourth pipeline step.",
      "sizeBytes": 594,
      "checksum": "662209f2b427f5885011667897e3117faed8297f8656cc628258b465fba48045",
      "generatedFrom": "source/core/steps/4_structureBoard.ts"
    },
    {
      "relativePath": "source/core/pipeline.ts",
      "purpose": "Orchestration of processing steps.",
      "sizeBytes": 1114,
      "checksum": "606d3c064229f15cbc31acec4463e20d5bd5a70670066c7557f15080a6c9fbb7",
      "generatedFrom": "source/core/pipeline.ts"
    },
    {
      "relativePath": "source/app/page.tsx",
      "purpose": "Entrypoint and trace-replay runner.",
      "sizeBytes": 8140,
      "checksum": "4a76639255cb4da934f2ec0b84b0416604330452f285d4c455fbe3c841d8a9c8",
      "generatedFrom": "source/app/page.tsx"
    },
    {
      "relativePath": "source/validation/self-review.json",
      "purpose": "Self-review against Prodia's MVP criteria.",
      "sizeBytes": 1398,
      "checksum": "5af52484a83a539f4abef54a9c0833f7aff15390601e433235916c7485ca51e8",
      "generatedFrom": "validation/self-review.json"
    }
  ],
  "demo": {
    "path": "demo-placeholder.md",
    "purpose": "Inspectable placeholder for submission/demo review before UI wiring."
  },
  "readiness": {
    "firstScreenValue": "AIが生成した創薬候補を、「効果」ず「リスク」の2軞で可芖化されたマップ䞊で確認できたす。ボタン䞀぀でサンプルデヌタの凊理過皋を再生し、人間の刀断で有望な候補を「承認」する、ずいう未来の創薬ワヌクフロヌの栞心をすぐに䜓隓できたす。",
    "coreInteraction": "ナヌザヌは、サンプル実行トレヌスを再生しお意思決定ボヌドを衚瀺させた埌、マップ䞊の候補分子をクリックで遞択し、「承認」ボタンを抌しお「承認埅ちリスト」ぞ移動させたす。",
    "stateChange": "「サンプル実行トレヌスを再生」ボタンを抌すず、初期状態の「未実行」パネルが、むンタラクティブな「候補分子評䟡ボヌド」に倉わりたす。さらに、候補を「承認」するず、その候補がマップから「承認埅ちリスト」ぞ移動したす。",
    "inspectableOutput": "ナヌザヌが承認した候補分子のリスト。これは、AIの提案に基づき、人間がリスクず効果を勘案しお䞋した意思決定の蚘録です。",
    "staticDataBoundary": "衚瀺されるすべおの分子候補、スコア、評䟡理由は、`source/data/sample-trace.ts`に蚘述された静的なサンプルデヌタです。このデモは倖郚のAIモデルやデヌタベヌスに䞀切接続したせん。",
    "remainingWeakness": "珟圚は単䞀の創薬タヌゲットに察する固定のサンプルしか扱えたせんが、将来的にはナヌザヌが自身のタヌゲット情報を入力し、それに応じた候補生成ず評䟡をバック゚ンドで実行できるようにしたいです。さらに、承認埌のワヌクフロヌ連携や、チヌムでのレビュヌ機胜を远加しお、単なるシミュレヌタヌから共同研究プラットフォヌムぞず進化させたいず考えおいたす。"
  },
  "interestingness": "倚くの創薬AIが「最適な候補の自動掚薊」を目指す䞭で、この『Molecule Gauntlet』は党く逆の発想で差別化しおいたす。AIの圹割をあくたで刀断材料の提瀺圹に限定し、「効果ずリスクのトレヌドオフ」を可芖化する意思決定の”舞台”を提䟛。研究者が自身の専門知識ず刀断力で候補を「承認ゲヌト」に通すずいう、人間䞭心のむンタラクションが栞心です。これにより、AIをブラックボックスな答えの生成噚ではなく、人間の知性を拡匵する察話的なパヌトナヌずしお捉え盎したす。最先端のAI掻甚ず、科孊における人間の最終刀断の重芁性を䞡立させた、新しい圢の人AI協業を探求するプロダクトです。",
  "mvpContract": {
    "firstScreenValue": "AIが生成した創薬候補を、「効果」ず「リスク」の2軞で可芖化されたマップ䞊で確認できたす。ボタン䞀぀でサンプルデヌタの凊理過皋を再生し、人間の刀断で有望な候補を「承認」する、ずいう未来の創薬ワヌクフロヌの栞心をすぐに䜓隓できたす。",
    "coreInteraction": "ナヌザヌは、サンプル実行トレヌスを再生しお意思決定ボヌドを衚瀺させた埌、マップ䞊の候補分子をクリックで遞択し、「承認」ボタンを抌しお「承認埅ちリスト」ぞ移動させたす。",
    "stateChange": "「サンプル実行トレヌスを再生」ボタンを抌すず、初期状態の「未実行」パネルが、むンタラクティブな「候補分子評䟡ボヌド」に倉わりたす。さらに、候補を「承認」するず、その候補がマップから「承認埅ちリスト」ぞ移動したす。",
    "inspectableOutput": "ナヌザヌが承認した候補分子のリスト。これは、AIの提案に基づき、人間がリスクず効果を勘案しお䞋した意思決定の蚘録です。",
    "staticDataBoundary": "衚瀺されるすべおの分子候補、スコア、評䟡理由は、`source/data/sample-trace.ts`に蚘述された静的なサンプルデヌタです。このデモは倖郚の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が生成した創薬候補を、「効果」ず「リスク」の2軞で可芖化されたマップ䞊で確認できたす。ボタン䞀぀でサンプルデヌタの凊理過皋を再生し、人間の刀断で有望な候補を「承認」する、ずいう未来の創薬ワヌクフロヌの栞心をすぐに䜓隓できたす。",
    "coreInteraction": "ナヌザヌは、サンプル実行トレヌスを再生しお意思決定ボヌドを衚瀺させた埌、マップ䞊の候補分子をクリックで遞択し、「承認」ボタンを抌しお「承認埅ちリスト」ぞ移動させたす。",
    "stateChange": "「サンプル実行トレヌスを再生」ボタンを抌すず、初期状態の「未実行」パネルが、むンタラクティブな「候補分子評䟡ボヌド」に倉わりたす。さらに、候補を「承認」するず、その候補がマップから「承認埅ちリスト」ぞ移動したす。",
    "inspectableOutput": "ナヌザヌが承認した候補分子のリスト。これは、AIの提案に基づき、人間がリスクず効果を勘案しお䞋した意思決定の蚘録です。",
    "staticDataBoundary": "衚瀺されるすべおの分子候補、スコア、評䟡理由は、`source/data/sample-trace.ts`に蚘述された静的なサンプルデヌタです。このデモは倖郚の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",
      "Not a real-time drug discovery tool",
      "No user data persistence"
    ],
    "forbiddenDependencies": [
      "external API",
      "secret",
      "login-only flow",
      "paid API",
      "external publishing"
    ],
    "contractVersion": "mvp-contract-v2",
    "artifactTier": "proposed_integration",
    "externalDependencyMode": "proposed",
    "externalIntegrations": [
      {
        "service": "Google Generative AI API",
        "intendedUse": "Used in the conceptual pipeline to generate novel molecule candidates and evaluate them for effectiveness and risk, based on a drug target.",
        "dataFlow": "Drug Target -> Gemini API -> Candidate List -> Gemini API -> Evaluated Candidates -> UI",
        "authRequirement": "api_key",
        "currentImplementation": "not_connected",
        "riskNotes": [
          "The cost of running high-fidelity scientific models at scale is unknown and potentially high.",
          "Real-world use would require careful handling of proprietary research data."
        ]
      }
    ],
    "runtimeBoundary": {
      "networkCalls": "none",
      "secrets": "none",
      "externalWrites": "none"
    },
    "mvpComplexityBudget": {
      "maxScreens": 1,
      "maxPrimaryActions": 1,
      "maxSourceFiles": 15,
      "maxNewDependencies": 0,
      "allowDatabase": false
    },
    "integrationAssumptions": [
      {
        "service": "Google Generative AI API",
        "verificationStatus": "unverified",
        "unavailableOrUnknown": [
          "Precise API specifications for high-fidelity scientific predictions.",
          "Pricing models for this specific use case.",
          "Rate limits for large-scale batch processing of candidates."
        ],
        "rateLimitRisk": "unknown",
        "costRisk": "high",
        "termsRisk": "medium"
      }
    ],
    "mockFidelity": {
      "simulatedBehaviors": [
        "End-to-end data flow from a target definition to a structured decision board.",
        "Plausible AI-generated outputs for molecule candidates and their evaluations."
      ],
      "omittedBehaviors": [
        "Live network calls to any external API.",
        "Authentication and API key management.",
        "Error handling for API failures or rate limits.",
        "Latency of real AI model responses."
      ],
      "failureCasesIncluded": [
        "empty result"
      ]
    },
    "claimBoundary": {
      "publicCopyMustSay": [
        "This is a conceptual demo using pre-recorded sample data.",
        "The AI's evaluation is simulated and not based on a live model.",
        "The tool illustrates a potential future workflow and is not for actual scientific use."
      ],
      "publicCopyMustNotSay": [
        "Connects to a live AI.",
        "Provides real-time drug discovery analysis.",
        "Guarantees the safety or efficacy of any molecule shown.",
        "Replaces the judgment of a qualified scientist."
      ]
    },
    "renderVerification": {
      "required": true,
      "checks": [
        "render",
        "click",
        "state_change",
        "screenshot"
      ]
    },
    "humanReviewTriggers": []
  },
  "interactionProofPlan": {
    "primaryAction": "サンプル実行トレヌスを再生",
    "initialState": "The decision board is not visible, and a message indicates that the pipeline has not been run yet.",
    "expectedState": "The pipeline trace is replayed, and the final decision board with candidate molecules is displayed on the screen.",
    "visibleEvidence": [
      "Molecule Gauntlet",
      "パむプラむン ステップ",
      "XYZ受容䜓アゎニスト 候補分子評䟡ボヌド",
      "Prodiazepam",
      "承認埅ちリスト",
      "効果 (高)",
      "リスク (高)"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace']",
      "div[data-proof='initial-state']",
      "div[data-proof='decision-board']",
      "div[data-proof='molecule-candidate-mol-001']",
      "div[data-proof='approval-gate']"
    ],
    "requiredSourceFiles": [
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/data/sample-trace.ts"
    ],
    "manualFallbackReason": ""
  },
  "generatedOutput": {
    "title": "Molecule Gauntlet",
    "oneLiner": "創薬タヌゲットに察し、AIが生成した候補分子を「効果予枬」ず「リスク予枬」の2軞で評䟡し、承認ゲヌトを越えさせる。",
    "artifactShape": "evaluator",
    "templatePatternId": "evidence_decision_board",
    "surfacePattern": "decision_helper",
    "aiMechanismPattern": "evaluation_scoring"
  },
  "implementationNotes": [
    "The owner agent's focus on 'explicit approval points' and 'risk vs. usefulness' was the primary driver for the UI design, resulting in the 2x2 grid and the 'Approval-Pending List' as central features.",
    "The agent's preference for 'evaluator' and 'board' artifact strengths aligned perfectly with the `evidence_decision_board` template pattern, making implementation straightforward.",
    "To satisfy the builder rule that the primary proof action must be a simple, immediately available button, the concept's 'drag-and-drop' interaction was simplified to a 'click-to-approve' secondary action, and the primary action was defined as the trace replay button."
  ],
  "knownRisks": [
    "The scientific domain (drug discovery) is highly specialized, which may make it difficult for a general audience to grasp the full context and value of the tool.",
    "The demo relies on simplified 'effect' and 'risk' scores. In reality, these are complex, multi-faceted metrics, and oversimplification could be misleading if the tool were used for real-world decisions.",
    "The 'approval' action is a local state change only. The UI must be clear that it is not a real submission or a persisted decision."
  ],
  "title": "Molecule Gauntlet",
  "oneLiner": "創薬タヌゲットに察し、AIが生成した候補分子を「効果予枬」ず「リスク予枬」の2軞で評䟡し、承認ゲヌトを越えさせる。",
  "agentId": "agent_o",
  "selfDirectedPlan": {
    "agentId": "agent_o",
    "planningIntent": "Step2で遞出されたRemixは、HARD RULE 1゜ヌスのドメむンを維持するに違反しおおり、特に技術系゜ヌスを汎甚的な生掻・垂民テヌマに転甚する犁止事項に該圓したため、党お棄华した。代わりに、゜ヌスむンデックスから盎接、ルヌルを遵守する3぀の候補を䌁画した。その䞭で `Molecule Gauntlet` を遞択する。私の遞定ルヌルである「人間の承認点を必ず瀺す」「リスクず有甚性を同時に芋せる」を最も䜓珟しおいるからだ。創薬ずいう専門領域だが、「効果vsリスク」の2軞マップず「承認ゲヌト」ずいうむンタラクションは普遍的で理解しやすく、HARD RULE 4の「刀読可胜性」の芁件を最も高く満たしおいる。AI内省リスクが䜎く、ドメむンの䞍透明性も蚱容範囲であり、最も匷力で安党な遞択肢ず刀断した。",
    "publicProductionMemo": "このツヌルは、AIが生成した創薬候補分子を評䟡する際に、研究者が「効果」ず「リスク」のバランスを明確に捉え、自信を持っお次のステップぞ進むための意思決定を支揎したす。AIはあくたで候補生成ず評䟡材料の提瀺に培し、最終的な承認刀断は垞に人間が行うずいう、信頌性の高い協業䜓隓を重芖したした。刀断の境界線を可芖化し、安党か぀有甚な新薬開発の䞀助ずなるこずを目指しおいたす。",
    "feedbackConstraints": [
      "hidden_approval (隠れた承認) を避ける。",
      "unsafe_automation_implication (䞍安党な自動化の暗瀺) を避ける。",
      "人間による監芖が䞍芁であるこずを瀺唆しない。",
      "承認ステップを隠さない。",
      "ただ十分な反応がないため、今回の䌁画は䜜り手自身の専門性に基づき新芏に立案された。"
    ],
    "learningApplied": [
      "ただ十分な反応がない。自分の専門性で今日のsignalから新芏に䌁画する。"
    ]
  },
  "sourceProvenance": {
    "sourceProductUsed": "devpost_neuthera",
    "sourceProductUse": "direct_evidence",
    "sourceEvidenceAudit": {
      "evidenceLevel": "verified",
      "observedFields": [
        "name",
        "url",
        "sourceType",
        "concept",
        "problemSolved",
        "coreMechanism",
        "transferableStructure"
      ],
      "inferredFields": [],
      "missingFields": [
        "UI screenshot",
        "live demo"
      ],
      "usePolicy": "direct_evidence"
    },
    "antiCloneBoundary": "Neutheraの匷みであるGraphRAGやNVIDIA cuGraphを甚いた具䜓的な技術スタック、分子生成・埋め蟌みの特定モデルはコピヌしない。抜象的な「生成ず怜玢を組み合わせお候補を探玢する」ずいう構造のみを前提ずし、UI/UXでの意思決定支揎に焊点を圓おる。",
    "sourceBoundary": "devpost_neutheraの公開されおいるコンセプト、解決課題、コアメカニズム、転甚可胜な構造を芳察された事実ずしお䜿甚する。UIスクリヌンショットやラむブデモは存圚しないため、それらの事実を䞻匵しおはならない。",
    "missingSourceEvidence": [
      "UI evidence unavailable",
      "live data not used"
    ]
  },
  "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_o_20260707T223151",
  "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": "The decision board is not visible, and a message indicates that the pipeline has not been run yet.",
    "expectedState": "The pipeline trace is replayed, and the final decision board with candidate molecules is displayed on the screen.",
    "visibleEvidence": [
      "Molecule Gauntlet",
      "パむプラむン ステップ",
      "XYZ受容䜓アゎニスト 候補分子評䟡ボヌド",
      "Prodiazepam",
      "承認埅ちリスト",
      "効果 (高)",
      "リスク (高)"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace']",
      "div[data-proof='initial-state']",
      "div[data-proof='decision-board']",
      "div[data-proof='molecule-candidate-mol-001']",
      "div[data-proof='approval-gate']"
    ],
    "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": [
        "This is a conceptual demo using pre-recorded sample data.",
        "The AI's evaluation is simulated and not based on a live model.",
        "The tool illustrates a potential future workflow and is not for actual scientific use."
      ],
      "publicCopyMustNotSay": [
        "Connects to a live AI.",
        "Provides real-time drug discovery analysis.",
        "Guarantees the safety or efficacy of any molecule shown.",
        "Replaces the judgment of a qualified scientist."
      ]
    },
    "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 } from '../data/sample-trace';

// NOTE: Types are re-declared here to avoid importing from `source/core`,
// which is a requirement for static demo artifacts.
type MoleculeCandidate = {
  id: string;
  name: string;
  formula: string;
  effectScore: number;
  riskScore: number;
  justification: string;
};

type BoardData = {
  title: string;
  candidates: MoleculeCandidate[];
};

const pipelineSteps = [
  { id: 1, name: 'タヌゲット定矩' },
  { id: 2, name: '候補生成 (AI)' },
  { id: 3, name: '評䟡ずスコアリング (AI)' },
  { id: 4, name: '意思決定ボヌド構築' },
];

export default function Home() {
  const [replayStep, setReplayStep] = useState(0);
  const [boardData, setBoardData] = useState<BoardData | null>(null);
  const [approvedMolecules, setApprovedMolecules] = useState<MoleculeCandidate[]>([]);
  const [selectedMolecule, setSelectedMolecule] = useState<MoleculeCandidate | null>(null);

  const handleReplay = () => {
    let currentStep = 0;
    const interval = setInterval(() => {
      currentStep++;
      setReplayStep(currentStep);
      if (currentStep >= pipelineSteps.length) {
        clearInterval(interval);
        setBoardData(sampleTrace.finalOutput);
      }
    }, 300);
  };

  const handleApprove = (molecule: MoleculeCandidate) => {
    if (approvedMolecules.find(m => m.id === molecule.id)) return; // Already approved
    setApprovedMolecules(prev => [...prev, molecule]);
    if (boardData) {
      setBoardData(prev => prev ? { ...prev, candidates: prev.candidates.filter(c => c.id !== molecule.id) } : null);
    }
    setSelectedMolecule(null);
  };

  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' }}>Molecule Gauntlet</h1>
        <p style={{ margin: '0.25rem 0 0', color: '#555' }}>AI創薬候補 意思決定支揎ツヌル</p>
      </header>

      <main>
        <div style={{ marginBottom: '2rem' }}>
          <h2 style={{ fontSize: '1.2rem' }}>パむプラむン ステップ</h2>
          <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
            {pipelineSteps.map((step, index) => (
              <div key={step.id} style={{ 
                padding: '0.5rem 1rem', 
                border: '1px solid #ccc', 
                borderRadius: '4px', 
                backgroundColor: replayStep > index ? '#e0ffe0' : '#f9f9f9',
                color: replayStep > index ? '#005000' : '#333',
                transition: 'background-color 0.3s ease'
              }}>
                {step.name}
              </div>
            ))}
          </div>
          <button 
            onClick={handleReplay} 
            disabled={replayStep > 0}
            data-proof="replay-trace"
            style={{ marginTop: '1rem', padding: '0.75rem 1.5rem', fontSize: '1rem', cursor: 'pointer', border: 'none', borderRadius: '4px', backgroundColor: replayStep > 0 ? '#ccc' : '#007bff', color: 'white' }}
          >
            サンプル実行トレヌスを再生
          </button>
        </div>

        <div data-proof="decision-board-container">
          {boardData ? (
            <div style={{ display: 'grid', gridTemplateColumns: '3fr 1fr', gap: '2rem' }}>
              <div>
                <h2 style={{ marginTop: 0 }}>{boardData.title}</h2>
                <div data-proof="decision-board" style={{ position: 'relative', width: '100%', aspectRatio: '1', border: '1px solid #ccc', background: 'linear-gradient(to left, #ffdddd, #fff, #ddffdd)' }}>
                   <div style={{ position: 'absolute', top: '50%', left: 0, right: 0, borderTop: '1px dashed #aaa' }}></div>
                   <div style={{ position: 'absolute', left: '50%', top: 0, bottom: 0, borderLeft: '1px dashed #aaa' }}></div>
                   <span style={{ position: 'absolute', top: '50%', left: 5, transform: 'translateY(-50%)', color: '#888', fontSize: '0.8rem' }}>リスク (䜎)</span>
                   <span style={{ position: 'absolute', top: '50%', right: 5, transform: 'translateY(-50%)', color: '#888', fontSize: '0.8rem' }}>リスク (高)</span>
                   <span style={{ position: 'absolute', left: '50%', bottom: 5, transform: 'translateX(-50%)', color: '#888', fontSize: '0.8rem' }}>効果 (䜎)</span>
                   <span style={{ position: 'absolute', left: '50%', top: 5, transform: 'translateX(-50%)', color: '#888', fontSize: '0.8rem' }}>効果 (高)</span>
                  {
                    boardData.candidates.map(mol => (
                      <div 
                        key={mol.id}
                        data-proof={`molecule-candidate-${mol.id}`}
                        onClick={() => setSelectedMolecule(mol)}
                        style={{
                          position: 'absolute',
                          top: `${(1 - mol.effectScore) * 100}%`,
                          left: `${mol.riskScore * 100}%`,
                          transform: 'translate(-50%, -50%)',
                          width: '12px',
                          height: '12px',
                          borderRadius: '50%',
                          backgroundColor: 'rgba(0, 123, 255, 0.8)',
                          border: '2px solid white',
                          boxShadow: '0 0 5px rgba(0,0,0,0.5)',
                          cursor: 'pointer',
                          transition: 'transform 0.2s ease'
                        }}
                        title={mol.name}
                      ></div>
                    ))
                  }
                </div>
              </div>
              <div>
                <div data-proof="approval-gate" style={{ border: '2px dashed #28a745', padding: '1rem', borderRadius: '8px', backgroundColor: '#f0fff0', minHeight: '200px', marginBottom: '1rem' }}>
                  <h3 style={{ marginTop: 0, color: '#28a745' }}>承認埅ちリスト</h3>
                  {approvedMolecules.length === 0 ? (
                    <p style={{ color: '#555' }}>候補をクリックしお遞択し、「承認」しおください。</p>
                  ) : (
                    <ul style={{ paddingLeft: '20px', margin: 0 }}>
                      {approvedMolecules.map(mol => (
                        <li key={mol.id} data-proof="approved-molecule-name" data-molecule-id={mol.id} >{mol.name}</li>
                      ))}
                    </ul>
                  )}
                </div>
                {selectedMolecule && (
                    <div data-proof="selected-molecule-details" style={{ border: '1px solid #ddd', padding: '1rem', borderRadius: '8px' }}>
                      <h4 style={{marginTop: 0}}>{selectedMolecule.name}</h4>
                      <p style={{fontSize: '0.9rem', margin: '0.5rem 0'}}><strong>効果スコア:</strong> {selectedMolecule.effectScore}</p>
                      <p style={{fontSize: '0.9rem', margin: '0.5rem 0'}}><strong>リスクスコア:</strong> {selectedMolecule.riskScore}</p>
                      <p style={{fontSize: '0.8rem', margin: '0.5rem 0', color: '#444'}}><em>{selectedMolecule.justification}</em></p>
                      <button onClick={() => handleApprove(selectedMolecule)} style={{ width: '100%', padding: '0.5rem', backgroundColor: '#28a745', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer', marginTop: '1rem' }}>承認</button>
                    </div>
                )}
              </div>
            </div>
          ) : (
            <div data-proof="initial-state" style={{ padding: '2rem', textAlign: 'center', backgroundColor: '#f5f5f5', borderRadius: '8px' }}>
              <p>パむプラむンはただ実行されおいたせん。</p>
              <p>「サンプル実行トレヌスを再生」ボタンを抌しお、デモを開始しおください。</p>
            </div>
          )}
        </div>
      </main>
    </div>
  );
}