play data-safety: PSL_SUPPORT_DATA_DELETION_BY_USER as Play's single choice (partialDeletion true | false | 'auto90'), drop the removed PSL_DATA_COLLECTION_USER_REQUEST_DELETE (deletionRequest deprecated, check notes it); ship Google's empty form (cli/data/play-data-safety-form.csv, exported 2026-10-12), take every Answer requirement from it and report pairs not in it (formPairIssues) in check, declarations and play data-safety. Pitfall 21
This commit is contained in:
parent
dfc28c15f8
commit
b5b8f2da9d
35 changed files with 1824 additions and 859 deletions
|
|
@ -127,7 +127,7 @@ export function declarations(config: ShipConfig, inp: DeclarationInputs): Declar
|
|||
ask.push({ area: 'dataSafety', id: `ds-row-${i.question}`, text: i.msg, fix: i.msg.replace(/^.*; set /, 'Set ').replace(/\)$/, '.') });
|
||||
const types = Object.entries(ds.data).map(([id, u]) => ({ id, category: categoryOf(id), shared: !!u.shared, ephemeral: !!u.ephemeral, optional: !!u.optional, collect: [...u.collect], share: [...(u.shared ? u.share ?? [] : [])] }));
|
||||
dataSafety = {
|
||||
collectsData: ds.collectsData, encryptedInTransit: ds.encryptedInTransit, deletionRequest: ds.deletionRequest, accountCreation: ds.accountCreation ?? ['PSL_ACM_NONE'],
|
||||
collectsData: ds.collectsData, encryptedInTransit: ds.encryptedInTransit, partialDeletion: ds.partialDeletion ?? null, accountCreation: ds.accountCreation ?? ['PSL_ACM_NONE'],
|
||||
types, extra: ds.extra?.length ?? 0, csv, rows: csv ? csv.trim().split('\n').length - 1 : 0,
|
||||
uploaded: inp.uploaded && csv ? { at: inp.uploaded.at, changes: dataSafetyChanges(inp.uploaded.csv, csv) } : null,
|
||||
};
|
||||
|
|
@ -135,7 +135,6 @@ export function declarations(config: ShipConfig, inp: DeclarationInputs): Declar
|
|||
if (!ds.collectsData && types.length) ask.push({ area: 'dataSafety', id: 'ds-contradiction', text: 'collectsData is false but data types are listed.', fix: 'Decide which is true; Play rejects a form that says both.' });
|
||||
if (profile === 'game' && !ds.data.PSL_DEVICE_ID) ask.push({ area: 'dataSafety', id: 'ds-ads-id', text: 'A game profile usually ships an ads or analytics SDK that reads the advertising id, but PSL_DEVICE_ID is not declared.', fix: 'Check every SDK\'s data disclosure; declare PSL_DEVICE_ID (advertising, analytics) if any reads it.' });
|
||||
if (config.accounts?.enabled && (ds.accountCreation ?? ['PSL_ACM_NONE']).includes('PSL_ACM_NONE')) ask.push({ area: 'dataSafety', id: 'ds-accounts', text: 'The app has accounts, but the form says no account creation.', fix: `Set dataSafety.accountCreation to the methods the app offers${accountCreationOf(config.accounts.signUp) ? ` (accounts.signUp means ${JSON.stringify(accountCreationOf(config.accounts.signUp))})` : ' (or set accounts.signUp and run storebound scan)'}, and the delete-account URL in dataSafety.extra.` });
|
||||
if (!ds.deletionRequest && config.accounts?.enabled) ask.push({ area: 'dataSafety', id: 'ds-deletion', text: 'Users can create accounts but deletionRequest is false.', fix: 'Both stores want account deletion (account-deletion skill); then set deletionRequest: true.' });
|
||||
}
|
||||
|
||||
// App Privacy: suggested from the Data safety answers; linked / tracking are questions only the owner can answer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue