From c9653cccfd4fa5d51b16bdf96ddf8d25529ccb87 Mon Sep 17 00:00:00 2001 From: yhryzy Date: Thu, 7 May 2026 21:15:05 +0100 Subject: [PATCH 1/2] Add ChatGPT app privacy remediation --- docs/platform/chatgpt-app-privacy-policy.md | 167 ++++++++++++++++++ .../chatgpt-app-resubmission-checklist.md | 92 ++++++++++ docs/platform/chatgpt-remote-mcp-prototype.md | 6 + docs/platform/openai-codex-mcp-guide.md | 2 + docs/platform/release-readiness-status.md | 2 + src/vulca/mcp_remote.py | 13 +- tests/test_mcp_remote_profile.py | 37 +++- 7 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 docs/platform/chatgpt-app-privacy-policy.md create mode 100644 docs/platform/chatgpt-app-resubmission-checklist.md diff --git a/docs/platform/chatgpt-app-privacy-policy.md b/docs/platform/chatgpt-app-privacy-policy.md new file mode 100644 index 00000000..cf083775 --- /dev/null +++ b/docs/platform/chatgpt-app-privacy-policy.md @@ -0,0 +1,167 @@ +# Vulca ChatGPT App Privacy Policy + +**Effective date:** 2026-05-07 + +This policy describes the data practices for the submitted Vulca ChatGPT App +remote profile. Vulca is an agent-native visual workflow tool for tradition +lookup, visual direction support, prompt composition, and rubric-based visual +evaluation. + +This policy is scoped to the ChatGPT App remote MCP profile. The open-source +Vulca Python package, local CLI, local MCP server, and separately configured +provider-backed workflows may have different data flows depending on how a user +runs them. + +## App Scope + +The submitted ChatGPT App profile exposes only these tools: + +- `list_traditions` +- `get_tradition_guide` +- `search_traditions` +- `compose_prompt_from_design` +- `evaluate_artwork` + +The submitted profile does not expose image generation, image upload, pixel +reading, redraw, inpaint, layer mutation, publishing, archive, sync, admin, or +filesystem-writing tools. + +`evaluate_artwork` is configured in `rubric_only` and `mock` mode for this +profile. It returns an L1-L5 rubric payload and does not read image pixels or +call a vision model by default. + +## Data We Receive + +Vulca receives only the tool arguments that ChatGPT sends to the selected MCP +tool. Depending on the tool, this can include: + +- Tradition names, such as `chinese_xieyi` or `photography`. +- Search tags or short visual keywords supplied by the user. +- A task-specific intent or evaluation description supplied by the user. +- A workspace-relative design document path for `compose_prompt_from_design`. +- The text content of an approved `design.md` file when prompt composition is + requested and the file is inside the configured remote workspace root. +- An image reference string for `evaluate_artwork`; in the submitted profile, + this is used only as an input placeholder for rubric selection and is not + opened, uploaded, or returned. +- Basic transport and security information generated by the hosting + environment, such as request time, IP address, user agent, status code, and + error summaries, if operational logging is enabled. +- Contact information that a user voluntarily provides when asking for support. + +The submitted profile does not intentionally request or collect precise +location, payment card data, government identifiers, health information, +passwords, API keys, MFA codes, OAuth tokens, raw full chat history, or images. + +## Data We Return To ChatGPT + +Tool responses are purpose-limited to the user's request. Responses can include: + +- The list of supported Vulca traditions and their public L1-L5 weights. +- Public tradition guide content, including terminology, taboos, weights, and + suggested layer structures. +- Ranked tradition search matches and matched public terms. +- A composed prompt, negative prompt, tradition tokens, color tokens, and style + treatment derived from a user-approved design document. +- A rubric-only L1-L5 evaluation structure, including the selected tradition, + rubric fields, score schema, and summary fields. + +The submitted remote profile is designed not to return local filesystem paths, +raw image bytes, provider API responses, request IDs, trace IDs, session IDs, +authentication secrets, or internal debug payloads. + +## Purposes Of Use + +Vulca uses the data described above to: + +- Provide the requested tradition lookup, search, prompt composition, or rubric + evaluation result. +- Validate that file paths remain inside the configured remote workspace root. +- Maintain app security, reliability, abuse prevention, and operational + debugging. +- Respond to support, privacy, or deletion requests. +- Comply with legal, platform, and app-review requirements. + +Vulca does not sell personal data. Vulca does not use ChatGPT App tool inputs +for advertising or behavioral profiling. + +## Recipients And Service Providers + +For the submitted ChatGPT App profile, data may be processed by: + +- OpenAI and ChatGPT as the platform through which the user invokes the app, + under OpenAI's applicable terms and privacy policy. +- Vulca's app server or hosting provider, for routing MCP requests and + returning tool responses. +- Operational service providers used for security, uptime monitoring, error + logging, or support, if configured. + +The submitted profile does not send prompts, images, masks, files, or evaluation +requests to image-generation providers or third-party vision model providers. +If a user separately installs or runs Vulca outside this submitted profile and +explicitly configures provider-backed generation, editing, or VLM evaluation, +the selected provider may receive the prompts, images, masks, metadata, or +other inputs required for that separate workflow. Those separate workflows are +outside the submitted ChatGPT App remote profile. + +## Retention + +By default, the submitted profile does not persist raw tool inputs, full tool +outputs, design document contents, or image references after the request is +served. + +Operational logs, if enabled by the production hosting environment, should be +limited to security and reliability data and retained for no longer than 30 +days unless a longer period is required to investigate abuse, debug a user +reported issue, comply with law, or preserve service integrity. + +Support emails and privacy requests are retained only as long as needed to +respond, maintain records of the request, and meet legal or platform +obligations. + +## User Controls + +Users can control what Vulca receives by choosing whether to invoke the app and +what information to include in their prompt or tool request. + +Users should not provide sensitive personal data, secrets, precise location, +payment information, health information, government identifiers, or private +images to the submitted ChatGPT App profile. + +Users can: + +- Disconnect or disable the Vulca app from ChatGPT. +- Avoid sending personal information in visual keywords, intents, or design + documents. +- Request access, correction, deletion, or other privacy assistance by + contacting the maintainer. + +## Security Measures + +The submitted profile uses a positive allowlist of remote-safe tools. File reads +for prompt composition are constrained to `VULCA_REMOTE_WORKSPACE_ROOT`, and +paths outside that root are rejected. Cost-incurring, filesystem-writing, +image-generation, redraw, inpaint, archive, sync, and admin tools are not +exposed in the submitted profile. + +Tool responses are minimized to remove local file paths and diagnostic metadata +that are not necessary for the user's request. + +## Children's Privacy + +The app is intended for general audiences and does not intentionally target +children under 13. Users should not submit children's personal data to the app. + +## Changes To This Policy + +This policy may be updated as the app changes. Material changes should be +reflected in the app submission metadata and resubmitted for review when +required by the platform. + +## Contact + +For privacy requests or support, contact: + +Yu Haorui +Email: `yuhaorui48@gmail.com` + diff --git a/docs/platform/chatgpt-app-resubmission-checklist.md b/docs/platform/chatgpt-app-resubmission-checklist.md new file mode 100644 index 00000000..dd6642be --- /dev/null +++ b/docs/platform/chatgpt-app-resubmission-checklist.md @@ -0,0 +1,92 @@ +# ChatGPT App Resubmission Checklist + +**Status:** Privacy-remediation checklist +**Created:** 2026-05-07 + +## Rejection Reason + +OpenAI review rejected Vulca because the submitted privacy policy did not +clearly disclose all data uses. The requested remediation is a complete policy +covering data collected, purposes, recipients, retention, and user controls, and +alignment with current tool inputs and outputs. + +Relevant OpenAI requirements: + +- ChatGPT app submissions must include a clear, published privacy policy. +- The policy must cover categories of personal data collected, purposes of use, + recipient categories, retention timelines, and user controls. +- Tool responses should return only data directly relevant to the request and + avoid diagnostic, telemetry, or internal identifiers unless required. +- MCP tool responses should be audited for nested fields, debug payloads, PII, + telemetry, internal IDs, and secrets. + +## Code/Docs Remediation + +- Publish `docs/platform/chatgpt-app-privacy-policy.md` at a stable public URL, + for example: + `https://github.com/vulca-org/vulca/blob/master/docs/platform/chatgpt-app-privacy-policy.md` +- Keep the submitted remote profile limited to: + - `list_traditions` + - `get_tradition_guide` + - `search_traditions` + - `compose_prompt_from_design` + - `evaluate_artwork` +- Confirm `compose_prompt_from_design` does not echo `source_design_path`. +- Confirm remote `evaluate_artwork` does not echo `image_path` or `latency_ms`. +- Re-run remote-profile tests before resubmission. + +## Tool Response Audit + +Run representative tool calls in ChatGPT developer mode or via MCP/API +Playground and record the raw responses. + +Check that responses do not include: + +- local filesystem paths; +- raw image bytes; +- full chat transcripts; +- precise location; +- API keys, OAuth tokens, passwords, or other secrets; +- request IDs, trace IDs, session IDs, internal account IDs; +- timestamps or latency diagnostics; +- unrelated debug payloads; +- provider raw responses. + +Expected allowed response categories: + +- public tradition identifiers and L1-L5 weights; +- public tradition guide content; +- user-supplied search tags echoed as `query_tags`; +- composed prompt fields derived from a user-approved design document; +- rubric-only L1-L5 evaluation payload. + +## Dashboard Resubmission Notes + +Use a concise release note: + +```text +Privacy remediation after review feedback. Published a complete Vulca ChatGPT App privacy policy covering collected data, purposes, recipient categories, retention, and user controls. Audited remote MCP tool responses and removed unnecessary local path and diagnostic metadata from the submitted remote profile. +``` + +## Optional Email Reply + +```text +Hello OpenAI review team, + +Thank you for the review. We have remediated the privacy-policy issue for Vulca. + +Changes made: +- Published a complete privacy policy covering data collected, purposes of use, recipient categories, retention timelines, and user controls. +- Audited the submitted ChatGPT App remote MCP profile and confirmed it exposes only the five review-safe tools: list_traditions, get_tradition_guide, search_traditions, compose_prompt_from_design, and evaluate_artwork. +- Removed unnecessary local path and diagnostic metadata from remote tool responses. +- Confirmed the submitted profile does not expose generation, image upload, pixel reading, redraw, inpaint, archive, sync, admin, or filesystem-writing tools. + +Privacy policy URL: + + +We will resubmit the app from the OpenAI Platform dashboard. + +Best, +Haorui Yu +``` + diff --git a/docs/platform/chatgpt-remote-mcp-prototype.md b/docs/platform/chatgpt-remote-mcp-prototype.md index 0d677a29..525e92d1 100644 --- a/docs/platform/chatgpt-remote-mcp-prototype.md +++ b/docs/platform/chatgpt-remote-mcp-prototype.md @@ -69,6 +69,12 @@ Use `http://127.0.0.1:8765/mcp` for local API experiments. ChatGPT developer mod - Do not pass private images to a remote server without explicit user approval. - Do not pass private project paths to a remote server unless the path is inside `VULCA_REMOTE_WORKSPACE_ROOT`. +- Do not echo local filesystem paths in remote tool responses. +- Do not return diagnostic metadata such as request IDs, trace IDs, session IDs, timestamps, or latency measurements unless required for the user's request. - Do not enable pixel-reading or provider-backed VLM evaluation by default. - Do not expose filesystem-writing tools in the first prototype. - Keep all cost-incurring tools behind explicit opt-in. + +Published app submissions should use `docs/platform/chatgpt-app-privacy-policy.md` +as the privacy-policy source of truth and should verify raw MCP responses against +`docs/platform/chatgpt-app-resubmission-checklist.md` before resubmission. diff --git a/docs/platform/openai-codex-mcp-guide.md b/docs/platform/openai-codex-mcp-guide.md index f4014189..2187cc1a 100644 --- a/docs/platform/openai-codex-mcp-guide.md +++ b/docs/platform/openai-codex-mcp-guide.md @@ -100,6 +100,8 @@ Before public install instructions: - validate the repo marketplace in a clean Codex Desktop session; - verify `vulca-mcp` is available in the target environment; - verify `vulca-mcp-remote` starts with `VULCA_REMOTE_WORKSPACE_ROOT` set before ChatGPT remote MCP experiments; +- publish and submit the privacy policy in `docs/platform/chatgpt-app-privacy-policy.md`; +- audit the raw remote MCP responses against `docs/platform/chatgpt-app-resubmission-checklist.md`; - run one no-cost `/visual-discovery` or prompt-composition workflow; - confirm generated artifacts stay in the workspace; - confirm public copy says official Codex public publishing is still pending unless OpenAI has opened it. diff --git a/docs/platform/release-readiness-status.md b/docs/platform/release-readiness-status.md index 11ddfa47..301beb92 100644 --- a/docs/platform/release-readiness-status.md +++ b/docs/platform/release-readiness-status.md @@ -104,6 +104,8 @@ Observed: 14 passed. - Optional: run a full interactive `claude --plugin-dir .` session if you want UI-level confirmation beyond `plugin validate` and non-interactive skill discovery. - Optional: open Codex UI and confirm the newly added `vulca-plugins` marketplace source appears as expected. - Deploy `vulca-mcp-remote` behind HTTPS/auth/logging before connecting it to ChatGPT developer mode from a public URL. +- For ChatGPT App resubmission, publish `docs/platform/chatgpt-app-privacy-policy.md` + at a stable public URL and complete `docs/platform/chatgpt-app-resubmission-checklist.md`. - Review marketplace copy and screenshots before submission. - Dogfood v0.22 redraw on representative real images and confirm the user-facing after-image is `source_pasteback_path`. - Decide what to do with main-worktree untracked generated artifacts before any broad cleanup. diff --git a/src/vulca/mcp_remote.py b/src/vulca/mcp_remote.py index 8b8543ad..56d03738 100644 --- a/src/vulca/mcp_remote.py +++ b/src/vulca/mcp_remote.py @@ -71,7 +71,11 @@ async def _remote_compose_prompt_from_design(design_path: str) -> dict: ) from vulca.mcp_server import compose_prompt_from_design - return await compose_prompt_from_design(str(safe_path)) + result = await compose_prompt_from_design(str(safe_path)) + # The local tool returns the source path for agent debugging. The public + # remote profile should not echo local filesystem paths back to ChatGPT. + result.pop("source_design_path", None) + return result async def _evaluate_artwork(**kwargs) -> dict: @@ -86,7 +90,7 @@ async def _remote_evaluate_artwork( intent: str = "", ) -> dict: """Use this when returning Vulca's L1-L5 rubric without reading pixels or calling a VLM.""" - return await _evaluate_artwork( + result = await _evaluate_artwork( image_path=image_path, tradition=tradition, intent=intent, @@ -94,6 +98,11 @@ async def _remote_evaluate_artwork( mode="rubric_only", vlm_model="", ) + # Keep remote responses purpose-bound: do not echo user file paths or + # diagnostic timing metadata in the submitted ChatGPT app profile. + result.pop("image_path", None) + result.pop("latency_ms", None) + return result remote_mcp = FastMCP( diff --git a/tests/test_mcp_remote_profile.py b/tests/test_mcp_remote_profile.py index 68154b66..d82bee5a 100644 --- a/tests/test_mcp_remote_profile.py +++ b/tests/test_mcp_remote_profile.py @@ -192,6 +192,37 @@ def test_remote_workspace_path_allows_relative_file_inside_root(tmp_path): ) == design_path.resolve() +def test_remote_compose_prompt_does_not_echo_source_path(monkeypatch, tmp_path): + from vulca import mcp_remote + + workspace = tmp_path / "workspace" + workspace.mkdir() + design_path = workspace / "design.md" + design_path.write_text("# Design\n", encoding="utf-8") + + async def fake_compose_prompt_from_design(path): + return { + "composed_prompt": "misty mountain", + "negative_prompt": "", + "source_design_path": path, + } + + monkeypatch.setenv("VULCA_REMOTE_WORKSPACE_ROOT", str(workspace)) + monkeypatch.setattr( + "vulca.mcp_server.compose_prompt_from_design", + fake_compose_prompt_from_design, + ) + + result = asyncio.run( + mcp_remote._remote_compose_prompt_from_design("design.md") + ) + + assert result == { + "composed_prompt": "misty mountain", + "negative_prompt": "", + } + + def test_remote_evaluate_artwork_forces_mock_rubric_only(monkeypatch): from vulca import mcp_remote @@ -199,7 +230,11 @@ def test_remote_evaluate_artwork_forces_mock_rubric_only(monkeypatch): async def fake_evaluate_artwork(**kwargs): captured.update(kwargs) - return {"ok": True} + return { + "ok": True, + "image_path": kwargs["image_path"], + "latency_ms": 12, + } monkeypatch.setattr(mcp_remote, "_evaluate_artwork", fake_evaluate_artwork) From 529f2050e96cb65f3e9f84c2ecc7056115586bbd Mon Sep 17 00:00:00 2001 From: yhryzy Date: Mon, 11 May 2026 13:10:22 +0100 Subject: [PATCH 2/2] docs(platform): fix privacy packet whitespace --- docs/platform/chatgpt-app-privacy-policy.md | 3 +-- docs/platform/chatgpt-app-resubmission-checklist.md | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/platform/chatgpt-app-privacy-policy.md b/docs/platform/chatgpt-app-privacy-policy.md index cf083775..dcdc2f77 100644 --- a/docs/platform/chatgpt-app-privacy-policy.md +++ b/docs/platform/chatgpt-app-privacy-policy.md @@ -162,6 +162,5 @@ required by the platform. For privacy requests or support, contact: -Yu Haorui +Yu Haorui Email: `yuhaorui48@gmail.com` - diff --git a/docs/platform/chatgpt-app-resubmission-checklist.md b/docs/platform/chatgpt-app-resubmission-checklist.md index dd6642be..402d8667 100644 --- a/docs/platform/chatgpt-app-resubmission-checklist.md +++ b/docs/platform/chatgpt-app-resubmission-checklist.md @@ -89,4 +89,3 @@ We will resubmit the app from the OpenAI Platform dashboard. Best, Haorui Yu ``` -