{
  "schema_version": 1,
  "app": {
    "id": "protein",
    "name": "Protein",
    "url": "https://protein.the-ysl.com/",
    "roadmap_url": "https://protein.the-ysl.com/roadmap.html"
  },
  "updated": "2026-11-02",
  "stages": [
    {
      "id": 1,
      "title": "Public protein comparison",
      "description": "Compare purchasable Singapore powders and milk using sourced prices and nutrition.",
      "tasks": [
        {
          "id": "DATA-01",
          "title": "Source powder and milk variants",
          "status": "Done",
          "scope": "Review exact packs, SGD prices, nutrition labels and retailer purchase links, including smaller Singapore brands.",
          "acceptance": "The manifest reconciles 17 unique variants: 10 powders and 7 milks, with price and nutrition sources and no missing numeric fields.",
          "verification": "Catalog model checks pass; nutrition images and primary retailer/manufacturer pages reviewed on 2026-11-01.",
          "depends": []
        },
        {
          "id": "UI-01",
          "title": "Interactive comparison and charts",
          "status": "Done",
          "scope": "Sortable table, powder/milk and type filters, source links, Pareto scatterplot, protein/SGD bars, custom prices, target calculator and CSV export.",
          "acceptance": "Calculation and frontier checks pass; browser controls, export, reload persistence and desktop/mobile layout pass.",
          "depends": [
            "DATA-01"
          ],
          "verification": "Six model tests and 22 browser acceptance checks pass locally, including a 25g\u219250g calculator regression, CSV download, custom-price reload persistence and 390px/1440px layout."
        },
        {
          "id": "WEB-01",
          "title": "Publish the public subdomain",
          "status": "Done",
          "scope": "Deploy versioned static source with HTTPS, public access, app roadmap and shared hub discovery.",
          "acceptance": "Unauthenticated HTTPS pages, JS and data return 200; live browser checks pass; the deployed SHA and roadmap hub match the published source.",
          "depends": [
            "UI-01"
          ],
          "verification": "Public HTTPS page, modules and feeds return 200 without owner authentication; HTTP redirects to HTTPS. All 22 browser acceptance checks pass on production at 1440px and 390px. Release f449422 deployed and its canonical feed discovered live by the roadmap hub."
        }
      ]
    },
    {
      "id": 2,
      "title": "Compact interactive comparison",
      "description": "Expose the core comparison and reveal secondary information where it is used.",
      "tasks": [
        {
          "id": "UI-02",
          "title": "Progressive disclosure and linked exploration",
          "status": "Done",
          "scope": "Replace KPI cards and duplicate chart with compact rows, source/price expansions, linked frontier highlighting, persistent shortlist, side-by-side comparison and live protein amounts.",
          "acceptance": "Desktop/mobile and keyboard checks pass; primary ratios stay visible while optional data starts collapsed.",
          "verification": "Local browser acceptance passes for expansion, shortlist persistence, compare mode, live amounts, linked chart and keyboard input.",
          "depends": [
            "UI-01"
          ]
        },
        {
          "id": "DATA-02",
          "title": "Verify Myprotein bulk discount in Singapore",
          "status": "Done",
          "scope": "Include the current bulk Vanilla SKU and distinguish actual code pricing from the advertised maximum discount.",
          "acceptance": "Exact pack and nutrition match the SG product variant; price is verified in the basket and code conditions appear beside the comparison.",
          "verification": "2.7kg Vanilla variant 17712192: S$329 list, S$164.50 with MPVALUE in a single-item SG basket on 2 Nov 2026; model regression covers the 50% discount and normalization.",
          "depends": [
            "DATA-01"
          ]
        },
        {
          "id": "WEB-02",
          "title": "Publish and verify the compact interface",
          "status": "Done",
          "scope": "Deploy the tested version and synchronize the app-owned roadmap with the hub.",
          "acceptance": "Live browser acceptance passes; public pages/data and release SHA match the pushed source; app/hub feeds agree.",
          "depends": [
            "UI-02",
            "DATA-02"
          ],
          "verification": "Release 8f828f4 pushed and deployed. Seven model checks and the full browser acceptance flow pass on production, including row/graph disclosure, price and shortlist persistence, side-by-side comparison, keyboard controls, live amounts, CSV offer provenance and 390px/1440px layouts. The hub retrieves the same six-task app feed."
        },
        {
          "id": "UI-03",
          "title": "Separate pack sizes and show total cost",
          "status": "Done",
          "scope": "List Myprotein concentrate and isolate in independent 900g and 2.7kg rows, with exact variant links and verified prices. Add a sortable total whole-pack cost column.",
          "acceptance": "All four variants render as separate rows; 2.7kg isolate price matches the SG basket; total cost responds to custom price/deposits but not the protein target; desktop/mobile checks and app/hub feed parity pass.",
          "depends": [
            "DATA-02",
            "UI-02"
          ],
          "verification": "Eight model checks and the full production browser acceptance flow pass on release 794121a. All four Myprotein variants render independently with verified prices; total-cost sorting, target independence, editable prices and 390px/1440px layouts pass. Catalog reload now bypasses stale browser data."
        }
      ]
    }
  ]
}
