{
  "schemaVersion": 1,
  "skillId": "superpowers-brainstorming",
  "revision": "bb92a77741419a4ab5f06e711a283343f1ada0c3",
  "runAt": "2026-10-19",
  "mode": "exported-helper-runtime-with-blocked-integration",
  "summary": "Seven exported upstream helper cases passed. The optional loopback server integration was attempted but blocked by host permissions; no full brainstorming workflow or HTTP security pass is claimed.",
  "sourceManifest": [
    {
      "path": "skills/brainstorming/SKILL.md",
      "sha256": "6ee10d1481b8a2580d5336ff66c5c08acc9d4b251b13bbc3bfd31be99c261d43",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/SKILL.md"
    },
    {
      "path": "LICENSE",
      "sha256": "a37e0e9697144819e1d965176ac4ae5bc3fa02d11e7812036bbcadf6dafe2400",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/LICENSE"
    },
    {
      "path": "skills/brainstorming/builder-check-prompt.md",
      "sha256": "36d51a4723d6f0a3ce5811a0ea3b3a8424f07533947e1355f5d8cb8cce40c55e",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/builder-check-prompt.md"
    },
    {
      "path": "skills/brainstorming/visual-companion.md",
      "sha256": "6ffcb038b53254bd31debaa15e12dcd4ff24bd63d690e0b644ac6396701cf2e2",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/visual-companion.md"
    },
    {
      "path": "skills/brainstorming/scripts/server.cjs",
      "sha256": "763abf96510e0b892a1141397b31aa82ef900cf87ed34dde94bc8782baf4a7ca",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/scripts/server.cjs"
    },
    {
      "path": "skills/brainstorming/scripts/helper.js",
      "sha256": "43c6d69954a46ec34a2a262bcc62a9a7e83e839c739f199cb72646d397c686e3",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/scripts/helper.js"
    },
    {
      "path": "skills/brainstorming/scripts/frame-template.html",
      "sha256": "6a8a4e58bd6a44b904e2e3c57de774481d909204597e1498de53f1b2fecc4c4e",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/scripts/frame-template.html"
    },
    {
      "path": "skills/brainstorming/scripts/start-server.sh",
      "sha256": "a4e5ae84275bcaacd2f84345afeabe59cf7b00ba080e123da7cc1fb226f12847",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/scripts/start-server.sh"
    },
    {
      "path": "skills/brainstorming/scripts/stop-server.sh",
      "sha256": "0b5ccbbd57f62d3ed88993f7940b5ee0e5c0fc9b21c550c623da4f6292e47daf",
      "sourceUrl": "https://github.com/obra/superpowers/blob/bb92a77741419a4ab5f06e711a283343f1ada0c3/skills/brainstorming/scripts/stop-server.sh"
    }
  ],
  "cases": [
    {
      "id": "masked-frame",
      "method": "upstream-helper-runtime",
      "expected": "Decode a masked synthetic choice JSON payload",
      "observed": {
        "pass": true,
        "payload": "{\"choice\":\"synthetic-a\"}",
        "bytesConsumed": 30
      },
      "passed": true
    },
    {
      "id": "unmasked-client-frame",
      "method": "upstream-helper-runtime",
      "expected": "Reject an unmasked frame",
      "observed": {
        "pass": true,
        "error": "Client frames must be masked"
      },
      "passed": true
    },
    {
      "id": "partial-client-frame",
      "method": "upstream-helper-runtime",
      "expected": "Wait for remaining payload bytes",
      "observed": {
        "pass": true,
        "value": null
      },
      "passed": true
    },
    {
      "id": "oversized-declared-payload",
      "method": "upstream-helper-runtime",
      "expected": "Reject a declared 10MiB+1 payload before allocation",
      "observed": {
        "pass": true,
        "error": "WebSocket frame payload exceeds maximum allowed size"
      },
      "passed": true
    },
    {
      "id": "windows-launcher-argument",
      "method": "upstream-helper-runtime",
      "expected": "Keep a synthetic URL with shell metacharacters in one argument",
      "observed": {
        "pass": true,
        "launcher": {
          "bin": "rundll32.exe",
          "args": [
            "url.dll,FileProtocolHandler",
            "http://localhost:50001/?key=synthetic&echo=unexecuted"
          ]
        }
      },
      "passed": true
    },
    {
      "id": "headless-launcher",
      "method": "upstream-helper-runtime",
      "expected": "No default launcher for headless Linux",
      "observed": {
        "pass": true,
        "value": null
      },
      "passed": true
    },
    {
      "id": "bounded-reconnect-backoff",
      "method": "upstream-helper-runtime",
      "expected": "Double and cap reconnect delay at configured maximum",
      "observed": {
        "pass": true,
        "values": [
          1000,
          30000,
          30000
        ]
      },
      "passed": true
    }
  ],
  "results": {
    "passed": 7,
    "failed": 0,
    "total": 7
  },
  "findings": [
    {
      "severity": "info",
      "title": "Bounded protocol and launcher helpers passed",
      "detail": "Seven upstream exported-helper cases passed: masked-frame parsing, rejection of unmasked and oversized frames, incomplete-frame handling, literal Windows launcher arguments, headless launcher selection and capped reconnect backoff. These are helper results, not an executed design workflow."
    },
    {
      "severity": "attention",
      "title": "Local previews still contain active web content",
      "detail": "The server inserts supplied HTML without sanitizing it and serves helper JavaScript. Its frame-ancestors policy is not an outbound-content sandbox. Use reviewed synthetic content, avoid secrets and do not load untrusted markup as a preview."
    },
    {
      "severity": "attention",
      "title": "Default branding can make a remote image request",
      "detail": "Source inspection found a remote logo URL in rendered branding unless telemetry is disabled. The probe set SUPERPOWERS_DISABLE_TELEMETRY=1; no browser or remote asset request was made. That setting does not prevent arbitrary external assets in user-written mockups."
    },
    {
      "severity": "attention",
      "title": "Session keys and stored mockups need care",
      "detail": "The optional server uses a session key in its bootstrap URL and cookie, and stores connection details and event data locally. Keep the default loopback bind, avoid sharing the key and check persistence and file access before using sensitive designs."
    },
    {
      "severity": "info",
      "title": "Approval paths are more specific than a universal gate",
      "detail": "The current instructions allow clear small tasks and an explicit skip-questions path. Larger designs need approval; an accepted throwaway spike does not authorize keeping and extending it."
    }
  ],
  "limitations": [
    "Seven exported-helper cases ran on Node 24.18.0/Windows. They cover frame parsing, launcher argument construction and reconnect timing, not an end-to-end brainstorming conversation.",
    "The optional server started on loopback, but the sandbox denied HTTP connections (EACCES) and hardlink setup (EPERM). A scoped integration retry was not executed because the approval service reported a capacity error. No HTTP authorization or WebSocket integration pass is claimed.",
    "No browser, remote asset fetch, account, design commit, visual quality assessment, host-agent orchestration or startup/stop shell script was executed. No Windows ACL, network-exposure or broad security guarantee."
  ],
  "methodology": "Actual upstream exported JavaScript functions ran in Node against synthetic values. The optional server integration was attempted separately; its host-permission failure is retained below and not included as a passing helper case.",
  "executionAttempts": [
    {
      "node": "v24.18.0",
      "platform": "win32",
      "scope": "Upstream server.cjs only; synthetic loopback HTTP/WebSocket. No browser, launcher, external asset fetch or user account.",
      "setupDiagnostics": [
        {
          "check": "hardlink-read",
          "status": "not-run",
          "reason": "EPERM"
        }
      ],
      "cases": [
        {
          "id": "loopback-bind",
          "method": "upstream-helper-runtime",
          "expected": "127.0.0.1",
          "observed": "127.0.0.1",
          "passed": true
        },
        {
          "id": "harness-error",
          "method": "upstream-helper-runtime",
          "expected": "No harness error",
          "observed": "Error: connect EACCES 127.0.0.1:61485",
          "passed": false
        }
      ],
      "results": {
        "passed": 1,
        "failed": 1,
        "total": 2
      }
    }
  ]
}
