{
  "gate": "omnistore-online-games-roster",
  "version": 1,
  "decidedOn": "2026-10-04",
  "decision": "LICENSE_DEPENDENCY_GATE",
  "foundation": {
    "repository": "Sigmafier/ellaz-games",
    "commit": "7ee515a10aaba90860f79c83ee52fa81cf9f01e5",
    "license": "MIT",
    "note": "Foundation licence covers the repository source. It does NOT by itself license sprite/atlas/manifest assets carried by individual games."
  },
  "authoritativeRosterCount": 49,
  "safeGameCount": 46,
  "blockedGameCount": 3,
  "rosterIds": [
    "memory",
    "evolve",
    "coloring",
    "finddiff",
    "hidden",
    "math",
    "2048",
    "tictactoe",
    "minesweeper",
    "sudoku",
    "snake",
    "blocks",
    "wordguess",
    "sequence",
    "vanish",
    "shadows",
    "echo",
    "balloons",
    "bubbles",
    "bees",
    "frog",
    "reaction",
    "sort",
    "merge",
    "pet",
    "fit",
    "music",
    "maze",
    "letters",
    "spell",
    "bubbleshooter",
    "match3",
    "jigsaw",
    "lettercross",
    "flow",
    "arrowtap",
    "fruit",
    "parking",
    "nonogram",
    "onestroke",
    "wordsearch",
    "untangle",
    "survivors",
    "chess",
    "backgammon",
    "holdtheline",
    "snakesurvivors",
    "puzzlesnake",
    "snakearena"
  ],
  "idToDirectoryExceptions": {
    "2048": "n2048"
  },
  "blocked": [
    {
      "id": "survivors",
      "directory": "survivors",
      "status": "BLOCKED",
      "reasonCode": "UNKNOWN_ASSET_PROVENANCE",
      "reason": "Sprite/atlas/manifest assets carry UNKNOWN provenance and UNKNOWN licence. Provenance chain ends at a 'studio' workspace (commit ef7901ae) that is absent from this machine and from the foundation clone; no LICENSE/NOTICE exists for these files. MIT at repository root is not treated as licence evidence for the assets.",
      "assets": [
        "src/games/survivors/sprites/*.png",
        "src/games/survivors/sprites/*.atlas.json",
        "src/games/survivors/sprites/*.manifest.json",
        "src/games/survivors/sprites/*.moves.json"
      ]
    },
    {
      "id": "holdtheline",
      "directory": "holdtheline",
      "status": "BLOCKED",
      "reasonCode": "UNKNOWN_ASSET_PROVENANCE",
      "reason": "Same UNKNOWN provenance chain as survivors. bat.png and golem.png are byte-identical to the survivors copies (sha256 547f5b6e... and 65f56d11...), so both games share one unlicensed art source.",
      "assets": [
        "src/games/holdtheline/sprites/*.png",
        "src/games/holdtheline/sprites/*.atlas.json",
        "src/games/holdtheline/sprites/*.manifest.json",
        "src/games/holdtheline/sprites/*.moves.json"
      ]
    },
    {
      "id": "snakesurvivors",
      "directory": "snakesurvivors",
      "status": "BLOCKED",
      "reasonCode": "TRANSITIVE_DEPENDENCY_ON_BLOCKED_ASSETS",
      "reason": "The game's own files are MIT-clean, but running or shipping it requires shipping survivors' blocked assets. cast.ts re-exports the sheet table from '../survivors/sprites' and SnakeSurvivorsScene.ts loads those sheets with this.load.atlas(key, CAST[key].png, CAST[key].atlas). Independent licence status of a game does NOT make it safe when it depends on a blocked asset source.",
      "dependencyEdges": [
        "snakesurvivors/cast.ts -> ../survivors/sprites",
        "snakesurvivors/SnakeSurvivorsScene.ts -> ../survivors/sprites",
        "snakesurvivors/SnakeSurvivorsScene.ts -> ../survivors/stick",
        "snakesurvivors/SnakeSurvivorsGame.tsx -> ../survivors/entrance/NeonTitle",
        "snakesurvivors/SnakeSurvivorsGame.tsx -> ../survivors/phoneArena",
        "snakesurvivors/SnakeTitle.tsx -> ../survivors/entrance/sprite",
        "snakesurvivors/careerScreens.tsx -> ../survivors/careerArt",
        "snakesurvivors/careerScreens.tsx -> ../survivors/careerScreens",
        "snakesurvivors/careerHooks.ts -> ../survivors/world",
        "snakesurvivors/body.ts -> ../survivors/world",
        "snakesurvivors/chase.ts -> ../survivors/world",
        "snakesurvivors/crowd.ts -> ../survivors/world",
        "snakesurvivors/draw.ts -> ../survivors/world",
        "snakesurvivors/floor.ts -> ../survivors/world",
        "snakesurvivors/logic.ts -> ../survivors/world",
        "snakesurvivors/tutorial.ts -> ../survivors/world"
      ],
      "hardRule": "snakesurvivors may never be reclassified SAFE without either a documented licence for the survivors sprite set, or an art source that is independently documented. Provenance must never be invented or assumed."
    }
  ],
  "safeIds": [
    "memory",
    "evolve",
    "coloring",
    "finddiff",
    "hidden",
    "math",
    "2048",
    "tictactoe",
    "minesweeper",
    "sudoku",
    "snake",
    "blocks",
    "wordguess",
    "sequence",
    "vanish",
    "shadows",
    "echo",
    "balloons",
    "bubbles",
    "bees",
    "frog",
    "reaction",
    "sort",
    "merge",
    "pet",
    "fit",
    "music",
    "maze",
    "letters",
    "spell",
    "bubbleshooter",
    "match3",
    "jigsaw",
    "lettercross",
    "flow",
    "arrowtap",
    "fruit",
    "parking",
    "nonogram",
    "onestroke",
    "wordsearch",
    "untangle",
    "chess",
    "backgammon",
    "puzzlesnake",
    "snakearena"
  ],
  "safeCrossGameDependencies": [
    {
      "from": "evolve",
      "to": "n2048",
      "status": "SAFE",
      "note": "Both ids are SAFE; no blocked asset is reachable."
    }
  ],
  "contaminatedFoundationModules": [
    "src/build/toyboxArt.ts",
    "src/content/games/fr/holdtheline.ts",
    "src/content/games/fr/snakesurvivors.ts",
    "src/content/games/fr/survivors.ts",
    "src/content/games/holdtheline.ts",
    "src/content/games/snakesurvivors.ts",
    "src/content/games/survivors.ts",
    "src/content/games/sv/holdtheline.ts",
    "src/content/games/sv/snakesurvivors.ts",
    "src/content/index.ts",
    "src/portal/career/Career.tsx",
    "src/portal/career/careerCards.ts",
    "src/portal/gamesRest.ts",
    "src/ui/arcade-entrance-covers-the-arena.test.ts",
    "src/ui/arcade-title.test.ts",
    "src/ui/the-page-holds-still-while-a-run-is-live.test.ts"
  ],
  "lettercross": {
    "id": "lettercross",
    "status": "SAFE",
    "noticeRequired": true,
    "noticePath": "src/games/lettercross/NOTICE.md",
    "noticeMustShipWithDistribution": true,
    "wordListSource": "scripts/build-lettercross-words.mjs",
    "wordListLicence": "ENABLE1 word list, public domain per foundation NOTICE"
  },
  "uiFonts": {
    "gate": "PASS",
    "policy": "No Ellaz UI font may be vendored into OmniStore. Every font that ships inside OmniStore must carry its own licence text committed beside it.",
    "forbiddenFamilies": [
      "Fredoka",
      "Baloo 2",
      "Gochi Hand",
      "Press Start 2P",
      "Heebo (Ellaz UI subsets)"
    ],
    "forbiddenFiles": [
      { "sha256": "27d49d7c8362279bf81267c615481f4be9548d7568d58889aeb1a6395dd6c070", "path": "src/ui/fonts/fredoka-latin.woff2" },
      { "sha256": "337681f6b85d3ea22d9dd48c593d32a3a2588755a76ad9e3a4c64d014db51db1", "path": "src/ui/fonts/fredoka-latin-ext.woff2" },
      { "sha256": "4eb357133c42c52eca85b20cf43c0bb0e7d4d2febb53a6ed6b28bf5d7673cce7", "path": "src/ui/fonts/fredoka-hebrew.woff2" },
      { "sha256": "5968ef50a00f549a771e975d978c22127bd00d170c2be85867bc72050b848071", "path": "src/ui/fonts/heebo-latin.woff2" },
      { "sha256": "54037b588f809fb7b07b74c8ba3c59668480bbf4473c53a11a4ed15a72a6bac3", "path": "src/ui/fonts/heebo-latin-ext.woff2" },
      { "sha256": "5272f40edeb1940202dd278d9121649047819a24b1cf0c8d8773f670f95f2596", "path": "src/ui/fonts/heebo-hebrew.woff2" },
      { "sha256": "2e9420db49d01d76a7b8a38ef22ec9c45305d9f15fafa370389b7bf467658fc3", "path": "src/ui/themes/fonts/baloo-2-latin.woff2" },
      { "sha256": "65da857e1941e9856da139e5b4c955cdd49492819565df6ac6e80866bbf92773", "path": "src/ui/themes/fonts/gochi-hand-latin.woff2" },
      { "sha256": "42144b97bd2942ea606e5d880684eae0f7be5c804bdd57b1faac5a8d7699ae6e", "path": "src/ui/themes/fonts/press-start-2p-latin.woff2" }
    ],
    "allowedFoundationFonts": [
      { "family": "Cairo", "licenceFile": "src/build/assets/Cairo-LICENSE.txt", "licence": "SIL OFL 1.1" },
      { "family": "Heebo (build copy)", "licenceFile": "src/build/assets/Heebo-LICENSE.txt", "licence": "SIL OFL 1.1" },
      { "family": "Noto Sans (build copy)", "licenceFile": "src/build/assets/NotoSans-LICENSE.txt", "licence": "SIL OFL 1.1" }
    ]
  },
  "blockedAssets": [
    { "sha256": "0744b5c01aa25d660d28b0579e0a0e14c3c47c047410f4f017d83392095b4591", "path": "src/games/survivors/sprites/bat.atlas.json" },
    { "sha256": "af57c47d29151e3890eb53be311a783d3d71a3f567e8c3e8dc3d5f216fcef145", "path": "src/games/survivors/sprites/bat.manifest.json" },
    { "sha256": "150df9ea6b9437e35faeb183ca6cc7eb680675d3dfe3286c25eff639df4e01dc", "path": "src/games/survivors/sprites/bat.moves.json" },
    { "sha256": "547f5b6e2e7571d424e794aba41c592e135da00e020046bff3f88dd431ebb6d4", "path": "src/games/survivors/sprites/bat.png" },
    { "sha256": "9fd5d52bcdf727ae145a7327a436d200ba7ed194e4cafe911d60eb13a84eb41f", "path": "src/games/survivors/sprites/crab.atlas.json" },
    { "sha256": "046931afdd6e49427e72bdc8e616a4a5ae82c417735a260a950bd62e1a4a8285", "path": "src/games/survivors/sprites/crab.manifest.json" },
    { "sha256": "c0817b7e25ffa3ccb0526354c2e5a3ba227139d70e85fb32328cc18d193d9a81", "path": "src/games/survivors/sprites/crab.png" },
    { "sha256": "a8a8f426a4df14459ee3a82a361e86db811f11041ffec7ab865a2f114a3c583c", "path": "src/games/survivors/sprites/golem.atlas.json" },
    { "sha256": "8f52af608fd59332c4a449a9934d0676fb6e027f7346e4f3796d10e8807f01d2", "path": "src/games/survivors/sprites/golem.manifest.json" },
    { "sha256": "65f56d11d42583e8909e7d0deced671b6fcd9c50bd01dcec99d45c2588329d4e", "path": "src/games/survivors/sprites/golem.png" },
    { "sha256": "78c63af068f2850cbefe8d2b215b5fcf8a4cfa882fffdaeaa607d968f65b28be", "path": "src/games/survivors/sprites/robot.atlas.json" },
    { "sha256": "2a68989b76fa7a0e50f8d3af2b60940bc4cb93dcda4b61fb44eabe1eacd0c1b6", "path": "src/games/survivors/sprites/robot.manifest.json" },
    { "sha256": "e0c307ede95ffa2dc0c069595227cbe6238cd92d85655f8e8493bb9b32c74cea", "path": "src/games/survivors/sprites/robot.moves.json" },
    { "sha256": "3a54f7f14c08587d15da930d3efb6de9212ccaf220a8ada583a7fb4dc7969a0c", "path": "src/games/survivors/sprites/robot.png" },
    { "sha256": "9850390f1f7fdb7552576bd4a5a04c5e157047793b37536a497fa28a87339e5c", "path": "src/games/survivors/sprites/slime.atlas.json" },
    { "sha256": "3d2aa6900801651f04f6b7539174ddce0d48f77eff9aac525f5e0ed43b96efae", "path": "src/games/survivors/sprites/slime.manifest.json" },
    { "sha256": "887e501f0a457b59dd524f58f8af1b37ef3b766b45c6e470473df2c933f4c7f1", "path": "src/games/survivors/sprites/slime.moves.json" },
    { "sha256": "1ba3d5f7779c7d08b0d59276918b99d5b6b146da2a8e8710c2161237af1878b0", "path": "src/games/survivors/sprites/slime.png" },
    { "sha256": "0744b5c01aa25d660d28b0579e0a0e14c3c47c047410f4f017d83392095b4591", "path": "src/games/holdtheline/sprites/bat.atlas.json" },
    { "sha256": "319630231b0a7409859ab53bc8a36b28977da0bc9ef7aab0b5bf8a47b8eda5cf", "path": "src/games/holdtheline/sprites/bat.manifest.json" },
    { "sha256": "150df9ea6b9437e35faeb183ca6cc7eb680675d3dfe3286c25eff639df4e01dc", "path": "src/games/holdtheline/sprites/bat.moves.json" },
    { "sha256": "547f5b6e2e7571d424e794aba41c592e135da00e020046bff3f88dd431ebb6d4", "path": "src/games/holdtheline/sprites/bat.png" },
    { "sha256": "d301e07d0230d258168fc179275da8b1bb1e429598c590bf6c59d07176b83ae0", "path": "src/games/holdtheline/sprites/brawler.atlas.json" },
    { "sha256": "e9a798fa4c88eac1174e70de26c6a421ed63cc4370545324f158838f05695fa9", "path": "src/games/holdtheline/sprites/brawler.manifest.json" },
    { "sha256": "3279b8e24d1c5690e89f0292c8327c799978df965b4c62fd2847067996b4e715", "path": "src/games/holdtheline/sprites/brawler.png" },
    { "sha256": "a8a8f426a4df14459ee3a82a361e86db811f11041ffec7ab865a2f114a3c583c", "path": "src/games/holdtheline/sprites/golem.atlas.json" },
    { "sha256": "fa7531e8dac9c4cc412be8840c188372af681607a61085a5251081724d49d03a", "path": "src/games/holdtheline/sprites/golem.manifest.json" },
    { "sha256": "cdfe20821807d7a0bedf5d85580c2a41c54ccf02f8698fc1aceccdb9dd9b82e4", "path": "src/games/holdtheline/sprites/golem.moves.json" },
    { "sha256": "65f56d11d42583e8909e7d0deced671b6fcd9c50bd01dcec99d45c2588329d4e", "path": "src/games/holdtheline/sprites/golem.png" },
    { "sha256": "c5254a290b6eaae530e7784f90db6d09a055b54d02fb5a610ffa4147744413d8", "path": "src/games/holdtheline/sprites/knight.atlas.json" },
    { "sha256": "663cf6df135ffe98404dd729c5c624181d5f728902ef90ae75db67c309c191fc", "path": "src/games/holdtheline/sprites/knight.manifest.json" },
    { "sha256": "5dc5b88a96fad9d77f0e3f6a485f467adc532be4ae3ffacef85ff0bf48c743cd", "path": "src/games/holdtheline/sprites/knight.moves.json" },
    { "sha256": "100077f71640bca8ef633b7c55e5ddce2b43b5b534057361a2f0b7e77487be88", "path": "src/games/holdtheline/sprites/knight.png" },
    { "sha256": "a98d647b865a5117952b9a01f092633c06a73c0c14fbad9bb6af9d5c1c02346f", "path": "src/games/holdtheline/sprites/ninja.atlas.json" },
    { "sha256": "7f39bd83d8b2a91622626700d82feb76d92de20c554a6c2dbc763018da7f104e", "path": "src/games/holdtheline/sprites/ninja.manifest.json" },
    { "sha256": "1182675038e96c72bcedbd833963e93555a62d70a91403779a970e96f3a538dd", "path": "src/games/holdtheline/sprites/ninja.moves.json" },
    { "sha256": "aa6863699b7aa945562c0de1f67232847a0c019c610b1cefce2d44478b1e3f13", "path": "src/games/holdtheline/sprites/ninja.png" },
    { "sha256": "be0fac500bf0580027dff92b83a868f8d1890bdfe36e23da999e7e1ea5095ca7", "path": "src/games/holdtheline/sprites/wizard.atlas.json" },
    { "sha256": "b791c2bc868249b1896f350dc1fb53f5cd30a2e1c1faa3f25d09ccb272ab9dcd", "path": "src/games/holdtheline/sprites/wizard.manifest.json" },
    { "sha256": "8dec8dd3a9c116a7de86a53db16c04c5eb98253f77f811a828ea7870ac6e2fe5", "path": "src/games/holdtheline/sprites/wizard.moves.json" },
    { "sha256": "f1779809d16c39006e81f8e847ead72a0868344b10685df6fce703d342e8658f", "path": "src/games/holdtheline/sprites/wizard.png" }
  ],
  "productionRosterContract": {
    "path": "online-games/ROSTER.json",
    "rule": "When implementation starts, the production roster MUST be written to this path and MUST be a subset of safeIds. This gate fails if the file exists and contains any blocked id.",
    "catalogLazinessRequired": true,
    "expectedSafeGames": 46,
    "expectedBlockedGames": 3
  }
}
