Skip to content

Cloud mode is the default and transmits fully hydrated prompts; add a data-handling document and a first-run notice #2348

Description

@bhargavchintam

Summary

The README states that "by default, all commands run in the cloud mode." In that mode the fully preprocessed prompt — which by design contains the contents of every <include>d source file, example, and test — is POSTed to a PDD-operated endpoint. The repository contains no data-handling document: no retention statement, no subprocessor list, no residency statement, and no described air-gapped configuration.

This is primarily a documentation gap, which is why I rank it high value for low effort — it is currently a procurement blocker that a page of prose could clear.

Inspected at commit 817abe2. Static inspection only; no PDD commands were run and no data was transmitted.

Evidence

What is transmittedpdd/llm_invoke.py:1010-1032:

    payload: Dict[str, Any] = {
        "strength": strength,
        "temperature": temperature,
        "time": time if time is not None else 0.25,
        "verbose": verbose,
        "useBatchMode": use_batch_mode,
    }
    ...
    if messages:
        payload["messages"] = messages
    else:
        payload["prompt"] = prompt
        payload["inputJson"] = input_json

prompt here is the post-preprocessing string: <include> resolution has inlined file contents, <shell> output has been substituted, and <web> content fetched and embedded. For a typical dev unit that is the module source, its example, its tests, and any schema/API docs pulled in by auto-deps.

Transmission — :1045-1050:

        response = requests.post(
            cloud_url,
            json=payload,
            headers=headers,
            timeout=get_cloud_request_timeout(),
        )

Cloud is the default; local is opt-outllm_invoke.py:4708:

use_cloud: None=auto-detect (cloud if enabled, local if PDD_FORCE_LOCAL=1), True=force cloud, False=force local.

Model selection happens server-side. The response carries modelName (:1108), so the caller learns which model ran only afterward, and the cloud-side candidate pool and fallback policy are not visible to the client.

No data-handling documentation exists. Searching docs/ and README.md for retention / privacy / training / subprocessor language returns nothing substantive:

$ ls docs/ | grep -iE "privacy|data-handling|security|compliance"
(no results)

Credit where due

Several adjacent concerns are already handled, and I want to be precise about scope:

  • Few-shot provenance is tracked. $defs.grounding in pdd/schemas/evidence_manifest.schema.json records mode (cloud/local/unavailable), selected_examples (module, id, title, prompt_sha256, code_sha256, similarity, source), plus pinned, excluded, and reviewed. Combined with --review-examples, users can see and control what conditions their generation.
  • Snapshots are secret-redacted. docs/evidence_manifest.md states shell/web snapshots are redacted for authorization headers, bearer/basic tokens, URL credentials, provider keys, and secret-like assignments before hashing and storage, and that raw environment dumps and unredacted tokens must not be persisted.

So the engineering for provenance and secret hygiene is in place. The gap is that none of it is described in terms a security reviewer or procurement team can evaluate.

Why this matters

  1. Defaults determine outcomes. A developer who installs pdd-cli and runs pdd sync transmits proprietary source before anyone reviews that decision. Security teams weight default behaviour heavily.
  2. Subprocessor disclosure. Because model selection is server-side, adopters cannot enumerate which providers process their code — a direct problem for GDPR Art. 28 disclosure and SOC 2 vendor management.
  3. --auto-submit scope is unstated. What exactly is submitted, under what licence, and can it contain proprietary identifiers or business logic?
  4. Licence of consumed examples. If community-contributed examples condition code that ships commercially, legal will ask about their licence and indemnity. The manifest records which examples were used; it does not state what rights attach to them.

Proposed fix

  1. Add docs/data-handling.md covering, for cloud vs --local: which fields leave the machine, whether prompts/responses are logged or retained and for how long, whether they are used for training, which providers act as subprocessors, and data-residency regions.
  2. State the licence and provenance policy for community examples, and document --auto-submit scope explicitly.
  3. Document an air-gapped configuration. lm_studio/ and ollama/ rows exist in the catalog and PDD_FORCE_LOCAL / PDD_SKIP_LOCAL_MODELS exist, so this appears feasible — a short "offline / air-gapped install" section would unlock evaluation where code cannot leave the premises.
  4. Add a one-time first-run notice stating that cloud mode transmits prompt contents and how to opt out. Low cost, removes the "surprising default" objection.
  5. Optionally, make --local the default for first runs until the user opts into cloud.

Related: #2342, #2343, #2346.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions