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 transmitted — pdd/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-out — llm_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
- 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.
- 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.
--auto-submit scope is unstated. What exactly is submitted, under what licence, and can it contain proprietary identifiers or business logic?
- 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
- 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.
- State the licence and provenance policy for community examples, and document
--auto-submit scope explicitly.
- 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.
- 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.
- Optionally, make
--local the default for first runs until the user opts into cloud.
Related: #2342, #2343, #2346.
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 transmitted —
pdd/llm_invoke.py:1010-1032:prompthere 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 byauto-deps.Transmission —
:1045-1050:Cloud is the default; local is opt-out —
llm_invoke.py:4708: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/andREADME.mdfor retention / privacy / training / subprocessor language returns nothing substantive:Credit where due
Several adjacent concerns are already handled, and I want to be precise about scope:
$defs.groundinginpdd/schemas/evidence_manifest.schema.jsonrecordsmode(cloud/local/unavailable),selected_examples(module, id, title,prompt_sha256,code_sha256, similarity, source), pluspinned,excluded, andreviewed. Combined with--review-examples, users can see and control what conditions their generation.docs/evidence_manifest.mdstates 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
pdd-cliand runspdd synctransmits proprietary source before anyone reviews that decision. Security teams weight default behaviour heavily.--auto-submitscope is unstated. What exactly is submitted, under what licence, and can it contain proprietary identifiers or business logic?Proposed fix
docs/data-handling.mdcovering, 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.--auto-submitscope explicitly.lm_studio/andollama/rows exist in the catalog andPDD_FORCE_LOCAL/PDD_SKIP_LOCAL_MODELSexist, so this appears feasible — a short "offline / air-gapped install" section would unlock evaluation where code cannot leave the premises.--localthe default for first runs until the user opts into cloud.Related: #2342, #2343, #2346.