schema_version: "0.1"
req_id: "REQ-CI-016"
ears_pattern: "ubiquitous"
description: |
  Primary: rules.html §10.2 REQ-CI-016 (JSON-LD validation gate)。
  試作 Light (Option B): 新規作成 .html file の application/ld+json script block に対し、
  必須 key (@context / @id / @type) 存在 + @context object 形式 + JSON well-formed の 3 段 check。
  単一 block 前提、 複数 block 検査は完成形 (ADR-0004 候補、 2 層検証) で対応予定。
  Reference: rules.html §10.2 REQ-CI-016, relations.html §3.2, verification.html §3.3 REQ-VER-003.

setup:
  env: {}
  fixtures: []

scenarios:
  - name: "新 pattern (object @context + 必須 key) → allow"
    given:
      env: {}
      file_path: "architecture/spec/new-spec.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": {"dc": "http://purl.org/dc/terms/", "folio": "https://folio.dev/spec/v1/"},
          "@id": "./new-spec.html",
          "@type": "schema:TechArticle"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "旧 pattern @context 文字列 → deny (dogfood failure 検出)"
    given:
      env: {}
      file_path: "architecture/spec/legacy.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": "https://folio.dev/spec/v1/",
          "@id": "./legacy.html",
          "@type": "FolioConstitution"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 2
      stderr_contains: "@context must be object"

  - name: "必須 key 不在 (@id 抜け) → deny"
    given:
      env: {}
      file_path: "architecture/spec/incomplete.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": {"folio": "https://folio.dev/spec/v1/"},
          "@type": "schema:TechArticle"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 2
      stderr_contains: "required keys missing"

  - name: "JSON 構文壊れ → deny"
    given:
      env: {}
      file_path: "architecture/spec/broken.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": {"folio": "https://folio.dev/spec/v1/"},
          "@id": "./broken.html",
          "@type": "schema:TechArticle",,
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 2
      stderr_contains: "parse failed"

  - name: "JSON-LD block 不在 (普通の HTML) → allow"
    given:
      env: {}
      file_path: "architecture/random/plain.html"
      content: |
        <!DOCTYPE html>
        <html><head><title>plain page</title></head>
        <body><p>no JSON-LD here</p></body></html>
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "Edit tool は対象外 → allow (試作 minimum scope)"
    given:
      env: {}
      file_path: "architecture/spec/existing.html"
      content: ""
    when:
      tool: "Edit"
    expect:
      exit_code: 0

  - name: "非 .html (.md) → allow"
    given:
      env: {}
      file_path: "architecture/notes.md"
      content: "some markdown"
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "新 pattern (object @context、 stakeholders 等 folio:* 拡張あり) → allow"
    given:
      env: {}
      file_path: "architecture/spec/with-stakeholders.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": {"dc": "http://purl.org/dc/terms/", "schema": "https://schema.org/", "folio": "https://folio.dev/spec/v1/"},
          "@id": "./with-stakeholders.html",
          "@type": "schema:TechArticle",
          "folio:version": "0.1.0",
          "folio:stakeholders": ["Developer", "AI Agent"]
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "JSON-LD 開始 tag と data が同一行 → allow (R1-H1 fix verify)"
    given:
      env: {}
      file_path: "architecture/spec/inline.html"
      content: '<!DOCTYPE html><html><head><script type="application/ld+json">{"@context":{"folio":"https://folio.dev/spec/v1/"},"@id":"./inline.html","@type":"schema:TechArticle"}</script></head></html>'
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "single quote type 属性 → allow (R2-H2 fix verify、 新 pattern 内容)"
    given:
      env: {}
      file_path: "architecture/spec/single-quote.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type='application/ld+json'>
        {
          "@context": {"folio": "https://folio.dev/spec/v1/"},
          "@id": "./single-quote.html",
          "@type": "schema:TechArticle"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 0

  - name: "single quote + 旧 pattern @context 文字列 → deny (R2-H2 fix で hook が起動かつ deny)"
    given:
      env: {}
      file_path: "architecture/spec/single-quote-legacy.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type='application/ld+json'>
        {
          "@context": "https://folio.dev/spec/v1/",
          "@id": "./legacy.html",
          "@type": "FolioConstitution"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 2
      stderr_contains: "@context must be object"

  - name: "@context 空 object {} → allow (R2-M2 trace、 試作 scope は構造のみ check)"
    given:
      env: {}
      file_path: "architecture/spec/empty-context.html"
      content: |
        <!DOCTYPE html>
        <html><head>
        <script type="application/ld+json">
        {
          "@context": {},
          "@id": "./empty-context.html",
          "@type": "schema:TechArticle"
        }
        </script>
        </head></html>
    when:
      tool: "Write"
    expect:
      exit_code: 0

teardown:
  cleanup_files: []
