Internal Product Info

OSS健康蚺断スコアボヌド

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

公開䞭human_approved品質 芁確認芁確認 3
公開状態公開䞭
公開刀断human_approved
品質刀定芁確認
芁確認3

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.
fail
skipped
ビルド確認生成物がビルド可胜かを確認したす。
skipped
刀定埅ち
実行確認生成物が実行できるかを確認したす。
pending
通過
スクリヌンショット衚瀺確認の蚌跡です。
pass
通過
メタデヌタ公開に必芁なメタ情報の有無です。
pass
芁確認
リスク確認公開を止めるリスクがないかを確認したす。
fail
刀定埅ち
秘密情報秘密情報の混入確認です。
pending
warn
倖郚䟝存公開方法に圱響する倖郚䟝存の確認です。
warn
刀定埅ち
プロンプト泚入公開䞊問題になる指瀺混入の確認です。
pending
通過
README公開説明の根拠が保存されおいるかを確認したす。
pass
通過
衚瀺確認公開画面で砎綻がないかを確認したす。
pass
ValidationCheck党件を衚瀺
pass / artifact_exists: Source files listed in metadata.
pending / duplicate_like: Duplicate check not yet run.
fail / high_risk_topic: High-risk topic flag detected: medical. Human review is required before publish or feature decisions.
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_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/mvp-contract-v2.json
保存ファむルのpath / size / checksumを衚瀺
demo / 1.6KB / 2bef235841ac889721e84fc103e05edf973d2819a920544f9c68f963838488db
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/demo-placeholder.md

interaction_proof / 2.1KB / ae7b29819b5b99feba2e660c56dfb0d09e4ee793587a15ecdd4f1e65ce0cd342
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/interaction-proof.json

metadata / 22.1KB / 24bae1d9668edb63f5510e1de0a93e7de015601c6a2e33422cc16e42494b7595
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/metadata.json

mvp_contract_v2 / 12.9KB / c034fd7efc83865d3b151c2dd7c3fa9171ff139756560d8812aec55be8382368
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/mvp-contract-v2.json

product_logo / 1.4KB / 7eaac6b5e2db807fd3336fb46c8ce0a9f1c4e60f8d6666acc975105518aacfa5
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/mockups/product-logo.svg

product_showcase / 2.1MB / 2022ce409ee65a2d691fa48235fb24950eb8db5af1a756a68f0c8d9efde8d207
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/mockups/product-showcase.png

product_showcase / 2.2KB / 4f90a9a90dbedd9be42e4f7dba228fb08bcb8486f2a7895a4ee2a810e2f1360e
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/mockups/product-showcase.svg

product_thumbnail / 1.5KB / 0735168f5227a83601aa286aed523616c79a5ce61117b94a94d3dd314f60541d
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/mockups/product-thumbnail.svg

publisher_response / 1.3KB / 392cf0c0eb23e2df6731795d195ae5737fa6001a0c7695afa744c67f79064a9e
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/publisher/response.json

publish_readiness / 6.0KB / b63fbc7931175aa880eccd3f5c72115f2690cdecc78e23e7b77abca934abc2e8
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/publish-readiness.json

readme / 5.0KB / 44077b5e33825b3087b8b288d6ff89bdbf788088186e8ad8aa55eae1a0613f5f
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/README.md

render_screenshot / 180.4KB / 65b8e37785af36bc07cf6ec0ed0e81fa3c14b2a8af17adad7f299925f7d86d40
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/render-verification.png

render_verification / 2.1KB / 1f34a02f815f6300bdc8e164d6641b1c80a0a734025d7f7935ea03cd2c2f21a6
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/render-verification.json

self_review / 2.3KB / ad7fe27e43d17c17087d2edc4e732bfd42e976184c9b0a2466edae6ae785622c
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/validation/self-review.json

source / 11.9KB / 978848e2f7a7ae17af13d1887999d224fa7c024397056e1f1e373a2d44441f93
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/app/page.tsx

source / 1.7KB / 6d3c79a58337bd37db2c090e943d2ccdd48e931308c79c2ddddc330eb367b345
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/gemini.ts

source / 990B / 6b330fc6a627263b10f95500db02719033de9c14b259574c0c8573150cda7c94
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/pipeline.ts

source / 1.1KB / ac6aa6023bcb8fcddd7a4da4d32ed4930b8d5c1fa234e9303fc10a12169d12c0
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/steps/1_fetchRepoData.ts

source / 1.9KB / 896238900872936766c0799318e12642f885ddd9c536dbfe9a27288bcb0803ab
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/steps/2_analyzeRepo.ts

source / 2.2KB / 2ed701a4ac2331d92d0822069461c33d95f36af6c7d1c8f62411997a1b425b7f
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/steps/3_calculateScores.ts

source / 1.2KB / 04f06898fe2ff087a51d4d8594b3c23e60371e286d49e7348a2d26d7690d43a2
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/core/types.ts

source / 139B / 22542ef938c22b5fe50dee09ff7e9c2282b69df844cc2c40f433df83ad4488a2
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/data/sample-input.ts

source / 4.3KB / a5da6e226119925bc9cefee2c6575ded8c0371a3fede8dbaee57e019b112ee3e
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/data/sample-trace.ts

source / 393B / aec7be2290829e6a0586f24e87a20615f5a935a17d917e1543e30b2cb5014095
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/manifest.json

source / 2.4KB / d0ca39594ee03223a025ca7f8fce6575a0f9c62292c0c13964a7219e1bdee7ca
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/metadata.json

source / 3.6KB / e6a1cb418c1dc6e545aaa27248f850523c2d74c7ab5beede3cc1a8615a013464
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/README.md

source / 590B / ab13952e971b8384d8efe3d16ab6473df733120cbc975d8a8ead6d780d9492ee
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/source/validation/self-review.json

validation_summary / 3.7KB / 8ecdcef99a5bbf3a75d2bd0042c9e791afe157b6735b31edc73142c076eff91a
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/validation-summary.json

visual_manifest / 10.8KB / 73ecf3dcdc654fec87b05b53953e0eaca4d1fc482a000061d600c975ff53483d
artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/materialized/selfdirected_agent_e_20260707T141019/mockups/visual-manifest.json
README / metadata / self-reviewの䞭身を衚瀺
README.md
# selfdirected_agent_e_20260707T141019

This directory is a materialized LLM BuildPlan artifact candidate.

## Readiness

- First screen value: GitHubリポゞトリのURLを入力するだけで、スタヌ数だけでは分からないプロゞェクトの健党性を倚角的に可芖化し、安定性や成長性ずいったあなたの䟡倀基準で評䟡を調敎できたす。
- Core interaction: ナヌザヌが「サンプル実行トレヌスを再生」ボタンをクリックするず、デヌタ凊理パむプラむンが可芖化され、最終的なOSS健党性スコアボヌドが衚瀺されたす。衚瀺埌、評䟡の重み付けスラむダヌを動かしお、総合スコアをむンタラクティブに倉化させるこずができたす。
- State change: 「再生」ボタンをクリックするず、空だった結果衚瀺゚リアに、パむプラむンの各ステップの出力ず、最終的なスコアカヌドレヌダヌチャヌト、各項目のスコアず根拠が衚瀺される。
- Inspectable output: 生成されたスコアカヌド。各評䟡項目掻動量、ドキュメント品質などのスコアず、そのスコアの根拠ずなった具䜓的なデヌタ䟋「月間平均コミット数: 45」が䞊んで衚瀺される。
- Static data boundary: このデモは、事前に甚意された単䞀のサンプルリポゞトリのデヌタトレヌスのみを再生したす。ラむブのGitHub APIずは通信せず、衚瀺されるデヌタは静的なサンプルです。
- Remaining weakness: 珟状は単䞀リポゞトリの評䟡のみですが、将来的には耇数リポゞトリを䞊べお比范し、自分の䟡倀基準で゜ヌトできる機胜を远加したいです。たた、評䟡指暙もより粟緻化し、技術スタックの陳腐化リスクなども含めるこずで、技術遞定における「かかり぀け医」のような存圚を目指したいです。

## Interaction Proof Plan

- Primary action: サンプル実行トレヌスを再生
- Initial state: Results panel shows 'ただ実行されおいたせん' message.
- Expected state: Results panel shows the final scorecard for 'CoolLib' with scores and evidence.
- Visible evidence: CoolLib の評䟡結果; 総合スコア:; 評䟡の重み:; 準備床 (Readiness); 掻動量 (Activity)

## 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 demo using static, pre-recorded sample data.; The AI analysis is a proposed integration and not a live feature.; Scores are illustrative and based on a simplified model.
- External integrations: Google Generative AI API=not_connected, GitHub API=not_connected
- Mock fidelity: A successful end-to-end data pipeline run, from data fetching to scoring.; A positive-case analysis of a healthy open-source project.

## Files

- `source/README.md`: Explains the product's purpose, architecture, and how it uses Google/Gemini services.
- `source/metadata.json`: Provides structured metadata for the Prodia platform.
- `source/manifest.json`: Lists all files included in the artifact.
- `source/app/page.tsx`: The main entrypoint of the application, a static runner page.
- `source/core/types.ts`: Defines shared TypeScript types for the core logic.
- `source/core/pipeline.ts`: Orchestrates the processing steps of the core logic.
- `source/core/gemini.ts`: Contains the real, non-executable call pattern for the Google Generative Language API.
- `source/core/steps/1_fetchRepoData.ts`: A placeholder step for fetching repository data. In a real app, this would call the GitHub API.
- `source/core/steps/2_analyzeRepo.ts`: The core AI step that builds a prompt and calls Gemini for qualitative analysis.
- `source/core/steps/3_calculateScores.ts`: Calculates final scores based on raw data and AI analysis.
- `source/data/sample-input.ts`: Provides a sample input for the processing pipeline.
- `source/data/sample-trace.ts`: A hand-authored execution trace of the pipeline for the sample input.
- `source/validation/self-review.json`: Provides a self-review of the artifact 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_e_20260707T141019",
  "generatedAt": "2026-07-07T14:23:00.206Z",
  "generatedFrom": {
    "input": "artifacts/llm-pipeline-runs/run_selfdirected_agent_e_20260707T141019/builder/response.json",
    "requirementSpecId": "req_sabo07_oss_scorecard",
    "framework": "next_static_artifact"
  },
  "sourceFiles": [
    {
      "relativePath": "source/README.md",
      "purpose": "Explains the product's purpose, architecture, and how it uses Google/Gemini services.",
      "sizeBytes": 3638,
      "checksum": "e6a1cb418c1dc6e545aaa27248f850523c2d74c7ab5beede3cc1a8615a013464",
      "generatedFrom": "README.md"
    },
    {
      "relativePath": "source/metadata.json",
      "purpose": "Provides structured metadata for the Prodia platform.",
      "sizeBytes": 2462,
      "checksum": "0afacfb808edf329c5debd35468f56d11084a3c7468c410eefcdb0d74bbce7e9",
      "generatedFrom": "metadata.json"
    },
    {
      "relativePath": "source/manifest.json",
      "purpose": "Lists all files included in the artifact.",
      "sizeBytes": 392,
      "checksum": "cfb24cf84a476ac8b2d6b683a4e33749651610c4e6f48274ed308965ed936856",
      "generatedFrom": "manifest.json"
    },
    {
      "relativePath": "source/app/page.tsx",
      "purpose": "The main entrypoint of the application, a static runner page.",
      "sizeBytes": 12210,
      "checksum": "978848e2f7a7ae17af13d1887999d224fa7c024397056e1f1e373a2d44441f93",
      "generatedFrom": "source/app/page.tsx"
    },
    {
      "relativePath": "source/core/types.ts",
      "purpose": "Defines shared TypeScript types for the core logic.",
      "sizeBytes": 1236,
      "checksum": "e970acce9022760aab7658c9076a4e4d332cfa0b14e6e52862b01f57fd31edf6",
      "generatedFrom": "source/core/types.ts"
    },
    {
      "relativePath": "source/core/pipeline.ts",
      "purpose": "Orchestrates the processing steps of the core logic.",
      "sizeBytes": 989,
      "checksum": "6d556c1e29afe67533bbd86299bbb97f0eddc2a3f0598a93a96212f8689c78d5",
      "generatedFrom": "source/core/pipeline.ts"
    },
    {
      "relativePath": "source/core/gemini.ts",
      "purpose": "Contains the real, non-executable call pattern for the Google Generative Language API.",
      "sizeBytes": 1726,
      "checksum": "ae672742364ad02e878afc695bdc4aad644a434a0d956b843eccf2f143a9bbad",
      "generatedFrom": "source/core/gemini.ts"
    },
    {
      "relativePath": "source/core/steps/1_fetchRepoData.ts",
      "purpose": "A placeholder step for fetching repository data. In a real app, this would call the GitHub API.",
      "sizeBytes": 1120,
      "checksum": "307a89a4c1a733287d67371b1debc02523713445c4e26e3508d42df6417d65c6",
      "generatedFrom": "source/core/steps/1_fetchRepoData.ts"
    },
    {
      "relativePath": "source/core/steps/2_analyzeRepo.ts",
      "purpose": "The core AI step that builds a prompt and calls Gemini for qualitative analysis.",
      "sizeBytes": 1930,
      "checksum": "9017d40983d884c51a36a01bb4cd5bfa13688f49cc857c247a575aee788d4a20",
      "generatedFrom": "source/core/steps/2_analyzeRepo.ts"
    },
    {
      "relativePath": "source/core/steps/3_calculateScores.ts",
      "purpose": "Calculates final scores based on raw data and AI analysis.",
      "sizeBytes": 2272,
      "checksum": "d47b5963d6c8bd6e75b6a4601985dfd28befcf27fed9cafc2a12d75eb609a46a",
      "generatedFrom": "source/core/steps/3_calculateScores.ts"
    },
    {
      "relativePath": "source/data/sample-input.ts",
      "purpose": "Provides a sample input for the processing pipeline.",
      "sizeBytes": 138,
      "checksum": "1a0ed192c082c0f00b83cad612ac9978b05b0ca1aa84ef1ba43b66619ec699e1",
      "generatedFrom": "source/data/sample-input.ts"
    },
    {
      "relativePath": "source/data/sample-trace.ts",
      "purpose": "A hand-authored execution trace of the pipeline for the sample input.",
      "sizeBytes": 4440,
      "checksum": "a5da6e226119925bc9cefee2c6575ded8c0371a3fede8dbaee57e019b112ee3e",
      "generatedFrom": "source/data/sample-trace.ts"
    },
    {
      "relativePath": "source/validation/self-review.json",
      "purpose": "Provides a self-review of the artifact against Prodia's MVP criteria.",
      "sizeBytes": 589,
      "checksum": "17859f1a4ca926be9cd1ce58cd4c8aaa5cfa96e0c19116709ea6e24f5afa9f46",
      "generatedFrom": "validation/self-review.json"
    }
  ],
  "demo": {
    "path": "demo-placeholder.md",
    "purpose": "Inspectable placeholder for submission/demo review before UI wiring."
  },
  "readiness": {
    "firstScreenValue": "GitHubリポゞトリのURLを入力するだけで、スタヌ数だけでは分からないプロゞェクトの健党性を倚角的に可芖化し、安定性や成長性ずいったあなたの䟡倀基準で評䟡を調敎できたす。",
    "coreInteraction": "ナヌザヌが「サンプル実行トレヌスを再生」ボタンをクリックするず、デヌタ凊理パむプラむンが可芖化され、最終的なOSS健党性スコアボヌドが衚瀺されたす。衚瀺埌、評䟡の重み付けスラむダヌを動かしお、総合スコアをむンタラクティブに倉化させるこずができたす。",
    "stateChange": "「再生」ボタンをクリックするず、空だった結果衚瀺゚リアに、パむプラむンの各ステップの出力ず、最終的なスコアカヌドレヌダヌチャヌト、各項目のスコアず根拠が衚瀺される。",
    "inspectableOutput": "生成されたスコアカヌド。各評䟡項目掻動量、ドキュメント品質などのスコアず、そのスコアの根拠ずなった具䜓的なデヌタ䟋「月間平均コミット数: 45」が䞊んで衚瀺される。",
    "staticDataBoundary": "このデモは、事前に甚意された単䞀のサンプルリポゞトリのデヌタトレヌスのみを再生したす。ラむブのGitHub APIずは通信せず、衚瀺されるデヌタは静的なサンプルです。",
    "remainingWeakness": "珟状は単䞀リポゞトリの評䟡のみですが、将来的には耇数リポゞトリを䞊べお比范し、自分の䟡倀基準で゜ヌトできる機胜を远加したいです。たた、評䟡指暙もより粟緻化し、技術スタックの陳腐化リスクなども含めるこずで、技術遞定における「かかり぀け医」のような存圚を目指したいです。"
  },
  "interestingness": "倚くの開発者が悩むOSS遞定を、「スタヌ数」ずいう単䞀指暙の呪瞛から解攟したす。このツヌルは、プロゞェクトの掻動量やコミュニティの健党性ずいった、芋えにくい「持続可胜性」を可芖化する点が新芏的です。最倧の違いは、ナヌザヌが「安定性」ず「成長性」の重みをスラむダヌで調敎し、自分だけの評䟡基準を䜜れるこず。画䞀的なランキングではなく、玍埗感のある意思決定を支揎したす。技術的には、Geminiによる定性分析を掻甚し、Issueの雰囲気やドキュメントの質ずいった、数倀化しにくい芁玠をスコアに反映させおいる点が特城です。",
  "mvpContract": {
    "firstScreenValue": "GitHubリポゞトリのURLを入力するだけで、スタヌ数だけでは分からないプロゞェクトの健党性を倚角的に可芖化し、安定性や成長性ずいったあなたの䟡倀基準で評䟡を調敎できたす。",
    "coreInteraction": "ナヌザヌが「サンプル実行トレヌスを再生」ボタンをクリックするず、デヌタ凊理パむプラむンが可芖化され、最終的なOSS健党性スコアボヌドが衚瀺されたす。衚瀺埌、評䟡の重み付けスラむダヌを動かしお、総合スコアをむンタラクティブに倉化させるこずができたす。",
    "stateChange": "「再生」ボタンをクリックするず、空だった結果衚瀺゚リアに、パむプラむンの各ステップの出力ず、最終的なスコアカヌドレヌダヌチャヌト、各項目のスコアず根拠が衚瀺される。",
    "inspectableOutput": "生成されたスコアカヌド。各評䟡項目掻動量、ドキュメント品質などのスコアず、そのスコアの根拠ずなった具䜓的なデヌタ䟋「月間平均コミット数: 45」が䞊んで衚瀺される。",
    "staticDataBoundary": "このデモは、事前に甚意された単䞀のサンプルリポゞトリのデヌタトレヌスのみを再生したす。ラむブのGitHub APIずは通信せず、衚瀺されるデヌタは静的なサンプルです。",
    "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": "GitHubリポゞトリのURLを入力するだけで、スタヌ数だけでは分からないプロゞェクトの健党性を倚角的に可芖化し、安定性や成長性ずいったあなたの䟡倀基準で評䟡を調敎できたす。",
    "coreInteraction": "ナヌザヌが「サンプル実行トレヌスを再生」ボタンをクリックするず、デヌタ凊理パむプラむンが可芖化され、最終的なOSS健党性スコアボヌドが衚瀺されたす。衚瀺埌、評䟡の重み付けスラむダヌを動かしお、総合スコアをむンタラクティブに倉化させるこずができたす。",
    "stateChange": "「再生」ボタンをクリックするず、空だった結果衚瀺゚リアに、パむプラむンの各ステップの出力ず、最終的なスコアカヌドレヌダヌチャヌト、各項目のスコアず根拠が衚瀺される。",
    "inspectableOutput": "生成されたスコアカヌド。各評䟡項目掻動量、ドキュメント品質などのスコアず、そのスコアの根拠ずなった具䜓的なデヌタ䟋「月間平均コミット数: 45」が䞊んで衚瀺される。",
    "staticDataBoundary": "このデモは、事前に甚意された単䞀のサンプルリポゞトリのデヌタトレヌスのみを再生したす。ラむブのGitHub APIずは通信せず、衚瀺されるデヌタは静的なサンプルです。",
    "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"
    ],
    "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": "Use the 'gemini-2.5-flash' model to analyze qualitative aspects of a repository, such as community health and documentation clarity, based on data like commit messages and issue discussions.",
        "dataFlow": "GitHub repo data -> Internal pipeline (prompt construction) -> Gemini API -> AI analysis object -> Internal pipeline (scoring) -> UI",
        "authRequirement": "api_key",
        "currentImplementation": "not_connected",
        "adapterPath": "source/core/gemini.ts",
        "sampleDataPath": "source/data/sample-trace.ts",
        "riskNotes": [
          "The quality of the analysis is highly dependent on prompt engineering.",
          "Potential for inconsistent or biased outputs from the LLM."
        ]
      },
      {
        "service": "GitHub API",
        "intendedUse": "Fetch public repository data, including commit history, pull requests, issues, and contributor information, to be used as input for scoring.",
        "dataFlow": "User input (GitHub URL) -> GitHub API -> Raw repo data -> Internal pipeline -> UI",
        "authRequirement": "none",
        "currentImplementation": "not_connected",
        "sampleDataPath": "source/data/sample-trace.ts",
        "riskNotes": [
          "Subject to GitHub API rate limits, which could affect performance for users analyzing many repositories.",
          "Changes to the GitHub API could break data fetching logic."
        ]
      }
    ],
    "runtimeBoundary": {
      "networkCalls": "none",
      "secrets": "none",
      "externalWrites": "none"
    },
    "mvpComplexityBudget": {
      "maxScreens": 1,
      "maxPrimaryActions": 1,
      "maxSourceFiles": 12,
      "maxNewDependencies": 0,
      "allowDatabase": false
    },
    "integrationAssumptions": [
      {
        "service": "Google Generative AI API",
        "verificationStatus": "official_docs_checked",
        "unavailableOrUnknown": [],
        "rateLimitRisk": "medium",
        "costRisk": "medium",
        "termsRisk": "low"
      },
      {
        "service": "GitHub API",
        "verificationStatus": "official_docs_checked",
        "unavailableOrUnknown": [],
        "rateLimitRisk": "medium",
        "costRisk": "low",
        "termsRisk": "low"
      }
    ],
    "mockFidelity": {
      "samplePayloadPath": "source/data/sample-trace.ts",
      "simulatedBehaviors": [
        "A successful end-to-end data pipeline run, from data fetching to scoring.",
        "A positive-case analysis of a healthy open-source project."
      ],
      "omittedBehaviors": [
        "Live network calls to GitHub or Gemini APIs.",
        "API error handling (e.g., rate limits, invalid URLs).",
        "Analysis of repositories with missing data or negative community health."
      ],
      "failureCasesIncluded": [
        "empty result"
      ]
    },
    "claimBoundary": {
      "publicCopyMustSay": [
        "This is a demo using static, pre-recorded sample data.",
        "The AI analysis is a proposed integration and not a live feature.",
        "Scores are illustrative and based on a simplified model."
      ],
      "publicCopyMustNotSay": [
        "Provides real-time analysis of any GitHub repository.",
        "Offers guaranteed-accurate, objective scores.",
        "Is an official partner of or endorsed by GitHub."
      ]
    },
    "renderVerification": {
      "required": true,
      "checks": [
        "render",
        "click",
        "state_change",
        "screenshot"
      ]
    },
    "humanReviewTriggers": []
  },
  "interactionProofPlan": {
    "primaryAction": "サンプル実行トレヌスを再生",
    "initialState": "Results panel shows 'ただ実行されおいたせん' message.",
    "expectedState": "Results panel shows the final scorecard for 'CoolLib' with scores and evidence.",
    "visibleEvidence": [
      "CoolLib の評䟡結果",
      "総合スコア:",
      "評䟡の重み:",
      "準備床 (Readiness)",
      "掻動量 (Activity)"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace']",
      "[data-proof='results']"
    ],
    "requiredSourceFiles": [
      "source/app/page.tsx",
      "source/core/pipeline.ts",
      "source/data/sample-trace.ts"
    ],
    "manualFallbackReason": ""
  },
  "generatedOutput": {
    "title": "OSS健康蚺断スコアボヌド",
    "oneLiner": "GitHubリポゞトリのURLを入力するず、掻動量、ドキュメント品質、コミュニティ健党性など耇数の軞で持続可胜性を採点し、重みを倉えお評䟡できる。",
    "artifactShape": "board",
    "templatePatternId": "evidence_decision_board",
    "surfacePattern": "decision_helper",
    "aiMechanismPattern": "evaluation_scoring"
  },
  "rewriteApplied": {
    "changedFilePaths": [
      "source/data/sample-trace.ts",
      "source/app/page.tsx",
      "metadata.json"
    ],
    "appendedFilePaths": []
  },
  "implementationNotes": [
    "The implementation directly reflects the owner agent's preference for 'scorecards' and 'evidence-vs-score panels'. The entire UI is structured as a decision board where each score is backed by visible evidence.",
    "The agent's 'qualityBar' requiring that users can 'adjust weights and see the ranking change' is implemented via the interactive weight slider, allowing for personalized evaluation.",
    "The anti-pattern of 'black_box_ranking' was explicitly avoided by making the scoring criteria (and the AI's role in it) transparent within the pipeline and UI.",
    "The primary interaction was set to the trace-replay button to conform to the builder's CORE-LOGIC-FIRST pattern, ensuring the demo focuses on proving the data pipeline's viability."
  ],
  "knownRisks": [
    "The scoring model is simplistic and could be 'gamed' if it were a live product. The metrics and weightings would need significant refinement and validation.",
    "The demo relies on a single, positive-case sample trace. It doesn't show how the scoreboard would handle repositories that are poorly maintained or have missing data.",
    "The claim that AI can assess 'community health' is a significant simplification. A real product would need much more nuanced models and clear disclaimers about the limitations of such analysis."
  ],
  "title": "OSS健康蚺断スコアボヌド",
  "oneLiner": "GitHubリポゞトリのURLを入力するず、掻動量、ドキュメント品質、コミュニティ健党性など耇数の軞で持続可胜性を採点し、重みを倉えお評䟡できる。",
  "agentId": "agent_e",
  "selfDirectedPlan": {
    "agentId": "agent_e",
    "planningIntent": "この「OSS健康蚺断スコアボヌド」案は、私の創造原則である「評䟡は根拠ず共にあっおこそ䟡倀がある」「比范を通じお意思決定を助ける」を最も玔粋に䜓珟しおいる。曖昧な「プロゞェクトの良さ」を、蚌拠に基づいた耇数の評䟡軞に分解し、ナヌザヌが自身の䟡倀芳で重み付けを調敎できる。これは、私が拒絶する「䞍透明な単䞀ランキング」の正反察だ。゜ヌスプロダクトの技術ドメむン宇宙政策から、別の技術ドメむンOSSぞの転甚であり、安易な日垞テヌマぞの再配眮を犁じる最優先ルヌルにも準拠しおいる。プロダクトずしおの分かりやすさ䜎DomainOpacityRisk、AIの悪甚リスクの䜎さ䜎AIIntrospectionRiskも遞択を埌抌しした。",
    "publicProductionMemo": "この「OSS健康蚺断スコアボヌド」は、単なるGitHubのスタヌ数に囚われず、OSSプロゞェクトの真の健党性を倚角的に評䟡するために䜜られたした。各評䟡項目には根拠ずなるデヌタが明瀺され、ナヌザヌ自身が重芖するポむントに応じお重み付けを調敎可胜です。䞍透明なランキングではなく、玍埗感のある意思決定を支揎するこずを目指しおいたす。過去の孊びから、すべおのスコアにその理由を明確に提瀺するよう努めたした。",
    "feedbackConstraints": [
      "「䞍透明な単䞀ランキングblack_box_rankingを避ける」ずいう孊びに基づき、党おのスコアに根拠の明瀺ず重み付け調敎機胜を実装する。",
      "「芋せかけだけの指暙vanity_metricを避ける」ずいう孊びに基づき、各評䟡項目は実質的なプロゞェクトの健党性を瀺す客芳的デヌタに裏付けられたものずする。",
      "「スコアには必ず基準を提瀺する」ずいう孊びに基づき、各スコアの蚈算ロゞックや参照デヌタを開瀺する。",
      "過去の成功事䟋であった「むンタラクティブな重み付け調敎機胜」が有効であるこずから、ナヌザヌが評䟡の重みを倉曎し、スコアぞの圱響を即座に確認できる機胜を必須ずする。",
      "「個別デヌタの厳栌な匿名性確保」ずいう過去の改善点から、GitHubから取埗するデヌタは公開情報のみに限定し、個人を特定できる情報は扱わない。"
    ],
    "learningApplied": [
      "ただ十分な反応がない。自分の専門性で今日のsignalから新芏に䌁画する。"
    ]
  },
  "sourceProvenance": {
    "sourceProductUsed": "nasa_spaceapps_2025_astro_sweepers",
    "sourceProductUse": "inspiration_only",
    "sourceEvidenceAudit": {
      "evidenceLevel": "verified",
      "observedFields": [
        "name",
        "url",
        "sourceType",
        "adoptionOrAttentionProof",
        "originalDomain",
        "concept"
      ],
      "inferredFields": [
        "coreMechanism",
        "transferableStructure"
      ],
      "missingFields": [
        "codeUrl"
      ],
      "usePolicy": "inspiration_only"
    },
    "antiCloneBoundary": "「宇宙ゎミデブリ」のスコア化ずいうドメむンや、Astro Sweepersずいう名称はコピヌしない。「芋えない倖郚性リスクや貢献を、比范可胜な公開スコアカヌドに倉換する」ずいう抜象的な構造のみを転甚する。",
    "sourceBoundary": "参照元である`nasa_spaceapps_2025_astro_sweepers`のプロゞェクト名、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_e_20260707T141019",
  "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": "Results panel shows 'ただ実行されおいたせん' message.",
    "expectedState": "Results panel shows the final scorecard for 'CoolLib' with scores and evidence.",
    "visibleEvidence": [
      "CoolLib の評䟡結果",
      "総合スコア:",
      "評䟡の重み:",
      "準備床 (Readiness)",
      "掻動量 (Activity)"
    ],
    "proofSelectors": [
      "button[data-proof='replay-trace']",
      "[data-proof='results']"
    ],
    "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 demo using static, pre-recorded sample data.",
        "The AI analysis is a proposed integration and not a live feature.",
        "Scores are illustrative and based on a simplified model."
      ],
      "publicCopyMustNotSay": [
        "Provides real-time analysis of any GitHub repository.",
        "Offers guaranteed-accurate, objective scores.",
        "Is an official partner of or endorsed by GitHub."
      ]
    },
    "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 React, { useState, useEffect } from 'react';
import { sampleTrace, FinalOutput } from '../data/sample-trace'; // Import FinalOutput which contains scorecards array

// NOTE: This page does NOT import from source/core. All types are redeclared here.
// Re-declare Scorecard type to match the new structure (array of scorecards)
type Scorecard = {
  id: string;
  githubUrl: string;
  name: string;
  overallScore?: number; // Optional, as it's calculated dynamically
  scores: {
    readiness: number;
    activity: number;
    community: number;
    documentation: number;
    busFactor: number;
  };
  evidence: {
    readiness: string[];
    activity: string[];
    community: string[];
    documentation: string[];
    busFactor: string[];
  };
};

type DisplayResult = {
  step: string;
  output: any;
};

const pipelineSteps = [
  '1. リポゞトリデヌタ取埗',
  '2. リポゞトリ分析 (Gemini)',
  '3. スコア蚈算',
];

// Helper to draw a radar chart point
const getPoint = (angle: number, value: number, radius: number, centerX: number, centerY: number) => {
  const x = centerX + value * Math.cos(angle);
  const y = centerY + value * Math.sin(angle);
  return `${x},${y}`;
};

// Radar Chart Component
const RadarChart = ({ scorecards, weight, calculateWeightedScore }: { scorecards: Scorecard[]; weight: number; calculateWeightedScore: (s: Scorecard, w: number) => number }) => {
  const size = 300;
  const centerX = size / 2;
  const centerY = size / 2;
  const radius = size / 2 * 0.8; // Max radius for scores
  const numAxes = 5;
  const angleStep = (2 * Math.PI) / numAxes;

  const scoreLabels = ['準備床', '掻動量', 'コミュニティ', 'ドキュメント', 'Bus Factor'];
  const scoreKeys: Array<keyof Scorecard['scores']> = ['readiness', 'activity', 'community', 'documentation', 'busFactor'];

  const getPath = (card: Scorecard) => {
    return scoreKeys.map((key, i) => {
      const scoreValue = card.scores[key];
      const scaledValue = (scoreValue / 100) * radius; // Scale score (0-100) to radius
      return getPoint(i * angleStep - Math.PI / 2, scaledValue, radius, centerX, centerY); // Adjust angle for top-up start
    }).join(' ');
  };

  return (
    <div style={{ margin: '2rem 0', border: '1px solid #eee', padding: '1rem' }}>
      <h3>プロゞェクト比范レヌダヌチャヌト</h3>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        {/* Axes */}
        {[...Array(numAxes)].map((_, i) => {
          const angle = i * angleStep - Math.PI / 2;
          return (
            <line
              key={`axis-${i}`}
              x1={centerX} y1={centerY}
              x2={centerX + radius * Math.cos(angle)} y2={centerY + radius * Math.sin(angle)}
              stroke="#ccc"
              strokeWidth="1"
            />
          );
        })}

        {/* Labels */}
        {scoreLabels.map((label, i) => {
          const angle = i * angleStep - Math.PI / 2;
          const labelOffset = 20; // Distance of label from max radius
          const x = centerX + (radius + labelOffset) * Math.cos(angle);
          const y = centerY + (radius + labelOffset) * Math.sin(angle);
          return (
            <text
              key={`label-${i}`}
              x={x}
              y={y}
              fontSize="12"
              textAnchor="middle"
              dominantBaseline="middle"
              fill="#333"
            >
              {label}
            </text>
          );
        })}

        {/* Score polygons */}
        {scorecards.map((card, idx) => (
          <polygon
            key={card.id}
            points={getPath(card)}
            fill={idx === 0 ? 'rgba(255, 99, 132, 0.4)' : 'rgba(54, 162, 235, 0.4)'}
            stroke={idx === 0 ? 'rgb(255, 99, 132)' : 'rgb(54, 162, 235)'}
            strokeWidth="2"
            data-proof={`radar-polygon-${card.name}`}
          />
        ))}

        {/* Center circle */}
        <circle cx={centerX} cy={centerY} r="3" fill="#666" />
      </svg>
      <div style={{ display: 'flex', justifyContent: 'center', gap: '1rem', marginTop: '1rem' }}>
        {scorecards.map((card, idx) => (
          <div key={card.id} style={{ display: 'flex', alignItems: 'center' }}>
            <div style={{ width: '12px', height: '12px', background: idx === 0 ? 'rgb(255, 99, 132)' : 'rgb(54, 162, 235)', marginRight: '5px' }}></div>
            <span>{card.name} ({calculateWeightedScore(card, weight)}点)</span>
          </div>
        ))}
      </div>
    </div>
  );
};


export default function Home() {
  const [results, setResults] = useState<DisplayResult[]>([]);
  const [isRunning, setIsRunning] = useState(false);
  const [finalScorecards, setFinalScorecards] = useState<Scorecard[] | null>(null); // Changed to array
  const [weight, setWeight] = useState(60); // Stability weight 0-100

  const handleReplay = () => {
    if (isRunning) return;
    setIsRunning(true);
    setResults([]);
    setFinalScorecards(null);

    const trace = [
      { step: pipelineSteps[0], output: sampleTrace.step1_fetchRepoData.output },
      { step: pipelineSteps[1], output: sampleTrace.step2_analyzeRepo.output },
      { step: pipelineSteps[2], output: sampleTrace.step3_calculateScores.output },
    ];

    trace.forEach((item, index) => {
      setTimeout(() => {
        setResults(prev => [...prev, item]);
        if (index === trace.length - 1) {
          setIsRunning(false);
          // Assuming item.output is { scorecards: Scorecard[] }
          setFinalScorecards(item.output.scorecards as Scorecard[]);
        }
      }, (index + 1) * 500);
    });
  };

  const calculateWeightedScore = (scorecard: Scorecard, stabilityWeight: number) => {
    if (!scorecard) return 0;
    const growthWeight = 100 - stabilityWeight;
    const stabilityScore = (scorecard.scores.readiness * 0.4) + (scorecard.scores.documentation * 0.4) + (scorecard.scores.busFactor * 0.2);
    const growthScore = (scorecard.scores.activity * 0.5) + (scorecard.scores.community * 0.5);
    return Math.round((stabilityScore * stabilityWeight / 100) + (growthScore * growthWeight / 100));
  };
  
  return (
    <div style={{ fontFamily: 'sans-serif', padding: '2rem' }}>
      <h1>OSS健康蚺断スコアボヌド</h1>
      <p>OSSプロゞェクトの健党性を倚角的に評䟡し、あなたの䟡倀基準で重み付けできる意思決定支揎ツヌル。</p>
      
      <div style={{ display: 'flex', gap: '2rem' }}>
        <div style={{ flex: 1 }}>
          <h2>凊理パむプラむン</h2>
          <ul style={{ listStyle: 'none', padding: 0 }}>
            {pipelineSteps.map(step => <li key={step} style={{ margin: '0.5rem 0', padding: '0.5rem', background: '#f0f0f0' }}>{step}</li>)}
          </ul>
          <button 
            onClick={handleReplay} 
            disabled={isRunning} 
            data-proof="replay-trace"
            style={{ padding: '0.8rem 1.5rem', fontSize: '1rem', cursor: 'pointer' }}
          >
            {isRunning ? '実行䞭...' : 'サンプル実行トレヌスを再生'}
          </button>
        </div>

        <div style={{ flex: 2, border: '1px solid #ccc', padding: '1rem' }} data-proof="results">
          <h2>実行結果</h2>
          {results.length === 0 && <p>ただ実行されおいたせん。「再生」ボタンを抌しおください。</p>}
          {finalScorecards && finalScorecards.length > 0 ? (
            <div>
              <div style={{ margin: '2rem 0' }}>
                  <label htmlFor="weight-slider">評䟡の重み: 安定性重芖 {weight}% ⇔ 成長性重芖 {100-weight}%</label>
                  <input 
                    type="range" 
                    id="weight-slider" 
                    min="0" 
                    max="100" 
                    value={weight} 
                    onChange={(e) => setWeight(parseInt(e.target.value))}
                    style={{ width: '100%' }}
                    data-proof="weight-slider"
                  />
              </div>

              <RadarChart scorecards={finalScorecards} weight={weight} calculateWeightedScore={calculateWeightedScore} />

              {/* Display individual scorecards in a table */}
              {finalScorecards.map((card, cardIndex) => (
                <div key={card.id} style={{ marginBottom: '2rem', border: '1px solid #ddd', padding: '1rem' }}>
                  <h3>{card.name} の評䟡結果 (総合スコア: <span data-proof={`overall-score-${card.name}`}>{calculateWeightedScore(card, weight)}</span>点)</h3>
                  <table style={{ width: '100%', borderCollapse: 'collapse', marginTop: '1rem' }}>
                    <thead>
                      <tr>
                        <th style={{ border: '1px solid #ddd', padding: 8, textAlign: 'left' }}>評䟡項目</th>
                        <th style={{ border: '1px solid #ddd', padding: 8, textAlign: 'left' }}>スコア</th>
                        <th style={{ border: '1px solid #ddd', padding: 8, textAlign: 'left' }}>根拠</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>準備床 (Readiness)</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>{card.scores.readiness}</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>
                          <ul style={{margin:0, paddingLeft:'20px'}}>{card.evidence.readiness.map((e, i) => <li key={i}>{e}</li>)}</ul>
                        </td>
                      </tr>
                      <tr>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>掻動量 (Activity)</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>{card.scores.activity}</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>
                          <ul style={{margin:0, paddingLeft:'20px'}}>{card.evidence.activity.map((e, i) => <li key={i}>{e}</li>)}</ul>
                        </td>
                      </tr>
                       <tr>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>コミュニティ (Community)</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>{card.scores.community}</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>
                          <ul style={{margin:0, paddingLeft:'20px'}}>{card.evidence.community.map((e, i) => <li key={i}>{e}</li>)}</ul>
                        </td>
                      </tr>
                       <tr>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>ドキュメント (Documentation)</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>{card.scores.documentation}</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>
                          <ul style={{margin:0, paddingLeft:'20px'}}>{card.evidence.documentation.map((e, i) => <li key={i}>{e}</li>)}</ul>
                        </td>
                      </tr>
                      <tr>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>Bus Factor</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>{card.scores.busFactor}</td>
                        <td style={{ border: '1px solid #ddd', padding: 8}}>
                          <ul style={{margin:0, paddingLeft:'20px'}}>{card.evidence.busFactor.map((e, i) => <li key={i}>{e}</li>)}</ul>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              ))}
            </div>
          ) : (
            results.map((r, i) => (
              <div key={i}>
                <h4>{r.step}</h4>
                <pre style={{ whiteSpace: 'pre-wrap', background: '#fafafa', padding: '0.5rem', border: '1px solid #eee' }}>{JSON.stringify(r.output, null, 2)}</pre>
              </div>
            ))
          )}
        </div>
      </div>
    </div>
  );
}